]> git.proxmox.com Git - mirror_ovs.git/blame - tests/ovn.at
treewide: Convert leading tabs to spaces.
[mirror_ovs.git] / tests / ovn.at
CommitLineData
49d7c759
BP
1# OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2#
3# This compares packets read from PCAP, in pcap format, to those read
4# from EXPECTED, which is a text file containing packets as hex
5# strings, one per line. If PCAP contains fewer packets than
6# EXPECTED, it waits up to 10 seconds for more packets to appear.
7#
8# The implementation is an m4 macro that is mostly implemented in
9# terms of a shell function. This reduces the size of the generated
10# testsuite file since the shell function is only emitted once even
11# when this macro is invoked many times.
12m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
20 ovs_wait_cond () {
abb37b6b
FF
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
49d7c759
BP
24 }
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
26
e4543cfe 27 sort $exp_text > expout
49d7c759
BP
28 }
29])
30m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
33
f295c17b 34AT_BANNER([OVN components])
10b1662b
BP
35
36AT_SETUP([ovn -- lexer])
37dnl For lines without =>, input and expected output are identical.
38dnl For lines with =>, input precedes => and expected output follows =>.
39AT_DATA([test-cases.txt], [dnl
40foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41"abc\u0020def" => "abc def"
42" => error("Input ends inside quoted string.")dnl "
43
2c5cbb15
RB
44$foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45$1 => error("`$' must be followed by a valid identifier.") 1
46
10b1662b
BP
47a/*b*/c => a c
48a//b c => a
49a/**/b => a b
50a/*/b => a error("`/*' without matching `*/'.")
51a/*/**/b => a b
52a/b => a error("`/' is only valid as part of `//' or `/*'.") b
53
540 1 12345 18446744073709551615
5518446744073709551616 => error("Decimal constants must be less than 2**64.")
569999999999999999999999 => error("Decimal constants must be less than 2**64.")
5701 => error("Decimal constants must not have leading zeros.")
58
590/0
600/1
611/0 => error("Value contains unmasked 1-bits.")
621/1
63128/384
641/3
651/ => error("Integer constant expected.")
66
671/0x123 => error("Value and mask have incompatible formats.")
68
690x1234
700x01234 => 0x1234
710x0 => 0
720x000 => 0
730xfedcba9876543210
740XFEDCBA9876543210 => 0xfedcba9876543210
750xfedcba9876543210fedcba9876543210
10b1662b
BP
760x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
770x => error("Hex digits expected following 0x.")
780X => error("Hex digits expected following 0X.")
790x0/0x0 => 0/0
800x0/0x1 => 0/0x1
810x1/0x0 => error("Value contains unmasked 1-bits.")
820xffff/0x1ffff
830x. => error("Invalid syntax in hexadecimal constant.")
84
85192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86256.1.2.3 => error("Invalid numeric constant.")
87192.168.0.0/16
88192.168.0.0/255.255.0.0 => 192.168.0.0/16
89192.168.0.0/255.255.255.0 => 192.168.0.0/24
90192.168.0.0/255.255.0.255
91192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
92192.168.0.0/32
93192.168.0.0/255.255.255.255 => 192.168.0.0/32
52c0fc39 941.2.3.4:5 => 1.2.3.4 : 5
10b1662b
BP
95
96::
97::1
98ff00::1234 => ff00::1234
992001:db8:85a3::8a2e:370:7334
1002001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
1012001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
102::ffff:192.0.2.128
103::ffff:c000:0280 => ::ffff:192.0.2.128
104::1/::1
105::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
106::1/128
107ff00::/8
108ff00::/ff00:: => ff00::/8
109
11001:23:45:67:ab:cd
11101:23:45:67:AB:CD => 01:23:45:67:ab:cd
112fe:dc:ba:98:76:54
113FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
11401:00:00:00:00:00/01:00:00:00:00:00
115ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118fe:x => error("Invalid numeric constant.")
11900:01:02:03:04:x => error("Invalid numeric constant.")
120
a20c96c6 121# Test that operators are tokenized as expected, even without white space.
52c0fc39 122(){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
10b1662b
BP
123& => error("`&' is only valid as part of `&&'.")
124| => error("`|' is only valid as part of `||'.")
56091efe 125- => error("`-' is only valid as part of `--'.")
10b1662b
BP
126
127^ => error("Invalid character `^' in input.")
128])
129AT_CAPTURE_FILE([input.txt])
130sed 's/ =>.*//' test-cases.txt > input.txt
131sed 's/.* => //' test-cases.txt > expout
132AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
133AT_CLEANUP
e0840f11 134
7700eea0
BP
135dnl The OVN expression parser needs to know what fields overlap with one
136dnl another. This test therefore verifies that all the smaller registers
137dnl are defined as terms of subfields of the larger ones.
138dnl
139dnl When we add or remove registers this test needs to be updated, of course.
140AT_SETUP([ovn -- registers])
141AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142[[reg0 = xxreg0[96..127]
143reg1 = xxreg0[64..95]
144reg2 = xxreg0[32..63]
145reg3 = xxreg0[0..31]
146reg4 = xxreg1[96..127]
147reg5 = xxreg1[64..95]
148reg6 = xxreg1[32..63]
149reg7 = xxreg1[0..31]
150reg8 = xreg4[32..63]
151reg9 = xreg4[0..31]
152xreg0 = xxreg0[64..127]
153xreg1 = xxreg0[0..63]
154xreg2 = xxreg1[64..127]
155xreg3 = xxreg1[0..63]
156xreg4 = OXM_OF_PKT_REG4
157xxreg0 = NXM_NX_XXREG0
158xxreg1 = NXM_NX_XXREG1
159]])
160AT_CLEANUP
161
2277b860
BP
162dnl Check that the OVN conntrack field definitions are correct.
163AT_SETUP([ovn -- conntrack fields])
164AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
858c2f76
GS
165[[ct.dnat = ct_state[7]
166ct.est = ct_state[1]
2277b860
BP
167ct.inv = ct_state[4]
168ct.new = ct_state[0]
169ct.rel = ct_state[2]
170ct.rpl = ct_state[3]
858c2f76 171ct.snat = ct_state[6]
2277b860
BP
172ct.trk = ct_state[5]
173ct_label = NXM_NX_CT_LABEL
b73db61d 174ct_label.blocked = ct_label[0]
2277b860
BP
175ct_mark = NXM_NX_CT_MARK
176ct_state = NXM_NX_CT_STATE
177]])
178AT_CLEANUP
179
fb8635c5 180AT_SETUP([ovn -- composition])
42d36b58
AZ
181AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
182AT_CLEANUP
183
e0840f11
BP
184AT_SETUP([ovn -- expression parser])
185dnl For lines without =>, input and expected output are identical.
186dnl For lines with =>, input precedes => and expected output follows =>.
187AT_DATA([test-cases.txt], [[
188eth.type == 0x800
189eth.type==0x800 => eth.type == 0x800
190eth.type[0..15] == 0x800 => eth.type == 0x800
191
192vlan.present
193vlan.present == 1 => vlan.present
194!(vlan.present == 0) => vlan.present
195!(vlan.present != 1) => vlan.present
196!vlan.present
197vlan.present == 0 => !vlan.present
198vlan.present != 1 => !vlan.present
199!(vlan.present == 1) => !vlan.present
200!(vlan.present != 0) => !vlan.present
201
202eth.dst[0]
203eth.dst[0] == 1 => eth.dst[0]
204eth.dst[0] != 0 => eth.dst[0]
205!(eth.dst[0] == 0) => eth.dst[0]
206!(eth.dst[0] != 1) => eth.dst[0]
207
208!eth.dst[0]
209eth.dst[0] == 0 => !eth.dst[0]
210eth.dst[0] != 1 => !eth.dst[0]
211!(eth.dst[0] == 1) => !eth.dst[0]
212!(eth.dst[0] != 0) => !eth.dst[0]
213
214vlan.tci[12..15] == 0x3
215vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
216vlan.tci[12..15] != 0x3
217vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
218
219!vlan.pcp => vlan.pcp == 0
220!(vlan.pcp) => vlan.pcp == 0
221vlan.pcp == 0x4
222vlan.pcp != 0x4
223vlan.pcp > 0x4
224vlan.pcp >= 0x4
225vlan.pcp < 0x4
226vlan.pcp <= 0x4
227!(vlan.pcp != 0x4) => vlan.pcp == 0x4
228!(vlan.pcp == 0x4) => vlan.pcp != 0x4
229!(vlan.pcp <= 0x4) => vlan.pcp > 0x4
230!(vlan.pcp < 0x4) => vlan.pcp >= 0x4
231!(vlan.pcp >= 0x4) => vlan.pcp < 0x4
232!(vlan.pcp > 0x4) => vlan.pcp <= 0x4
2330x4 == vlan.pcp => vlan.pcp == 0x4
2340x4 != vlan.pcp => vlan.pcp != 0x4
2350x4 < vlan.pcp => vlan.pcp > 0x4
2360x4 <= vlan.pcp => vlan.pcp >= 0x4
2370x4 > vlan.pcp => vlan.pcp < 0x4
2380x4 >= vlan.pcp => vlan.pcp <= 0x4
239!(0x4 != vlan.pcp) => vlan.pcp == 0x4
240!(0x4 == vlan.pcp) => vlan.pcp != 0x4
241!(0x4 >= vlan.pcp) => vlan.pcp > 0x4
242!(0x4 > vlan.pcp) => vlan.pcp >= 0x4
243!(0x4 <= vlan.pcp) => vlan.pcp < 0x4
244!(0x4 < vlan.pcp) => vlan.pcp <= 0x4
245
2461 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
2471 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2481 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
2491 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
2501 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2514 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
2524 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
2534 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
2544 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
255!(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
256!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
257!(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
258!(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
259!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
260!(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
261!(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
262!(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
263!(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
264
265vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
267
268vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
269vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
270
271vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
272vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
273vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
274
275ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
276ip6.src == ::1 => ip6.src == 0x1
277
278ip4.src == 1.2.3.4 => ip4.src == 0x1020304
279ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
280ip6.src == ::1 => ip6.src == 0x1
281
2821
2830
284!1 => 0
285!0 => 1
286
287inport == "eth0"
288!(inport != "eth0") => inport == "eth0"
289
3b7cb7e1
BP
290ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
291inport == 1 => String field inport is not compatible with integer constant.
76da94b5 292ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
e0840f11
BP
293
294ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
295eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
296vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
297
298inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
299!(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
300eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
301!(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
76da94b5 302inport = "eth0" => Syntax error at `=' expecting relational operator.
e0840f11
BP
303
304123 == 123 => Syntax error at `123' expecting field name.
305
2c5cbb15 306$name => Syntax error at `$name' expecting address set name.
3d2848ba 307@name => Syntax error at `@name' expecting port group name.
2c5cbb15 308
e0840f11
BP
309123 == xyzzy => Syntax error at `xyzzy' expecting field name.
310xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311
312inport[1] == 1 => Cannot select subfield of string field inport.
313
314eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
315eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
316eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317
318eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319
320eth.type[5..1] => Invalid bit range 5 to 1.
321
322eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323
324eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325
326eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327
328!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329
330123 => Syntax error at end of input expecting relational operator.
331
332123 x => Syntax error at `x' expecting relational operator.
333
334{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335
336eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337
338(1 x) => Syntax error at `x' expecting `)'.
339
340!0x800 != eth.type => Missing parentheses around operand of !.
341
342eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343
344eth.dst == {} => Syntax error at `}' expecting constant.
345
346eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff => Only == and != operators may be used with masked constants. Consider using subfields instead (e.g. eth.src[0..15] > 0x1111 in place of eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).
347
3b7cb7e1 348ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
e0840f11
BP
349
3501 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
8b34ccda 351
9aef3c1b 352eth.dst[40] x => Syntax error at `x' expecting end of input.
ea382567
RB
353
354ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
355eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
e0840f11
BP
356]])
357sed 's/ =>.*//' test-cases.txt > input.txt
358sed 's/.* => //' test-cases.txt > expout
359AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
360AT_CLEANUP
361
362AT_SETUP([ovn -- expression annotation])
363dnl Input precedes =>, expected output follows =>.
32157c87 364dnl Empty lines and lines starting with # are ignored.
e0840f11
BP
365AT_DATA([test-cases.txt], [[
366ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
367ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
368ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
32157c87 369ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
e0840f11
BP
370ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
371
32157c87
JS
372# Nested expressions over a single symbol should be annotated with symbol's
373# prerequisites only once, at the top level.
374tcp.dst == 1 || (tcp.dst >= 2 && tcp.dst <= 3) => (tcp.dst == 0x1 || (tcp.dst >= 0x2 && tcp.dst <= 0x3)) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
375
e0840f11
BP
376ip => eth.type == 0x800 || eth.type == 0x86dd
377ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
378ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
379ip > 0 => Only == and != operators may be used with nominal field ip.
380!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
381ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
382
383vlan.present => vlan.tci[12]
384!vlan.present => !vlan.tci[12]
385
386!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
387vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
7700eea0 388!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
e0840f11
BP
389
390ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
391!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
392ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
393
394bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
395self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
396mutual_recurse_1 != 0 => Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_1'.
397mutual_recurse_2 != 0 => Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_2'.
398]])
399sed 's/ =>.*//' test-cases.txt > input.txt
400sed 's/.* => //' test-cases.txt > expout
401AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
402AT_CLEANUP
403
9d4aecca 404AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 405AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 406 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
407])
408AT_CLEANUP
409
9d4aecca 410AT_SETUP([ovn -- 2-term expression conversion])
e0840f11 411AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
8c3caa2c 412 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
413])
414AT_CLEANUP
415
9d4aecca 416AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 417AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
8c3caa2c 418 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
419])
420AT_CLEANUP
421
9d4aecca
BP
422AT_SETUP([ovn -- 3-term numeric expression simplification])
423AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
8c3caa2c 424 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
425])
426AT_CLEANUP
427
9d4aecca
BP
428AT_SETUP([ovn -- 4-term string expression simplification])
429AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
430 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
431])
432AT_CLEANUP
433
9d4aecca
BP
434AT_SETUP([ovn -- 3-term mixed expression simplification])
435AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
8c3caa2c 436 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
437])
438AT_CLEANUP
439
97ba1d55
BP
440AT_SETUP([ovn -- simplification special cases])
441simplify() {
442 echo "$1" | ovstest test-ovn simplify-expr
443}
444AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
445])
a3d79068
BP
446AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
447])
33f15d17
BP
448AT_CHECK([simplify 'tcp.dst >= 0'], [0],
449 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
450])
451AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
452 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
453])
454AT_CHECK([simplify 'tcp.dst > 0'], [0],
455 [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
456]])
457AT_CHECK([simplify 'tcp.dst < 65535'], [0],
458 [[(!tcp.dst[0] || !tcp.dst[1] || !tcp.dst[2] || !tcp.dst[3] || !tcp.dst[4] || !tcp.dst[5] || !tcp.dst[6] || !tcp.dst[7] || !tcp.dst[8] || !tcp.dst[9] || !tcp.dst[10] || !tcp.dst[11] || !tcp.dst[12] || !tcp.dst[13] || !tcp.dst[14] || !tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
459]])
97ba1d55
BP
460AT_CLEANUP
461
ba8d3816
MS
462AT_SETUP([ovn -- is_chassis_resident simplification])
463simplify() {
464 echo "$1" | ovstest test-ovn simplify-expr
465}
466AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
467])
468AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
469])
470AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
471])
472AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
473])
474AT_CLEANUP
475
9d4aecca
BP
476AT_SETUP([ovn -- 4-term numeric expression normalization])
477AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
8c3caa2c 478 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
479])
480AT_CLEANUP
481
9d4aecca
BP
482AT_SETUP([ovn -- 4-term string expression normalization])
483AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
484 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
485])
486AT_CLEANUP
487
488AT_SETUP([ovn -- 4-term mixed expression normalization])
489AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
8c3caa2c 490 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
9d4aecca
BP
491])
492AT_CLEANUP
493
494AT_SETUP([ovn -- 5-term numeric expression normalization])
495AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
8c3caa2c 496 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
9d4aecca
BP
497])
498AT_CLEANUP
499
500AT_SETUP([ovn -- 5-term string expression normalization])
501AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
503])
504AT_CLEANUP
505
506AT_SETUP([ovn -- 5-term mixed expression normalization])
507AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
8c3caa2c 508 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
509])
510AT_CLEANUP
511
512AT_SETUP([ovn -- 4-term numeric expressions to flows])
8c3caa2c 513AT_KEYWORDS([expression])
9d4aecca 514AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
8c3caa2c 515 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
9d4aecca
BP
516])
517AT_CLEANUP
518
519AT_SETUP([ovn -- 4-term string expressions to flows])
8c3caa2c 520AT_KEYWORDS([expression])
9d4aecca
BP
521AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
522 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
523])
524AT_CLEANUP
525
526AT_SETUP([ovn -- 4-term mixed expressions to flows])
8c3caa2c 527AT_KEYWORDS([expression])
9d4aecca 528AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
8c3caa2c 529 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
530])
531AT_CLEANUP
532
533AT_SETUP([ovn -- 3-term numeric expressions to flows])
8c3caa2c 534AT_KEYWORDS([expression])
9d4aecca 535AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
8c3caa2c 536 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
537])
538AT_CLEANUP
f386a8a7
BP
539
540AT_SETUP([ovn -- converting expressions to flows -- string fields])
8c3caa2c 541AT_KEYWORDS([expression])
f386a8a7
BP
542expr_to_flow () {
543 echo "$1" | ovstest test-ovn expr-to-flows | sort
544}
cc5e28d8 545AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 546])
cc5e28d8 547AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
548])
549AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
550])
551AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
552ip,reg14=0x5
553ipv6,reg14=0x5
f386a8a7
BP
554])
555AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
556ip,reg14=0x6
557ipv6,reg14=0x6
f386a8a7
BP
558])
559AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
560])
561AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
562[reg14=0x5
563reg14=0x6
564reg14=0xfffe
f386a8a7
BP
565])
566AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
567ip,reg14=0x5
568ip,reg14=0x6
569ipv6,reg14=0x5
570ipv6,reg14=0x6
f386a8a7 571])
9d4aecca
BP
572AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
573(no flows)
574])
f386a8a7 575AT_CLEANUP
3b7cb7e1 576
2c5cbb15 577AT_SETUP([ovn -- converting expressions to flows -- address sets])
8c3caa2c 578AT_KEYWORDS([expression])
2c5cbb15
RB
579expr_to_flow () {
580 echo "$1" | ovstest test-ovn expr-to-flows | sort
581}
582AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
583ip,nw_src=10.0.0.1
584ip,nw_src=10.0.0.2
585ip,nw_src=10.0.0.3
586])
587AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
588ip,nw_src=10.0.0.1
589ip,nw_src=10.0.0.2
590ip,nw_src=10.0.0.3
591])
592AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
593ip,nw_src=1.2.3.4
594ip,nw_src=10.0.0.1
595ip,nw_src=10.0.0.2
596ip,nw_src=10.0.0.3
597])
598AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
599ip,nw_src=1.2.0.0/20
600ip,nw_src=10.0.0.1
601ip,nw_src=10.0.0.2
602ip,nw_src=10.0.0.3
603ip,nw_src=5.5.5.0/24
604])
605AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
606ipv6,ipv6_src=::1
607ipv6,ipv6_src=::2
608ipv6,ipv6_src=::3
609])
610AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
611ipv6,ipv6_src=::1
612ipv6,ipv6_src=::2
613ipv6,ipv6_src=::3
614ipv6,ipv6_src=::4
615])
616AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, 00:00:00:00:00:02, 00:00:00:00:00:03}'], [0], [dnl
617dl_src=00:00:00:00:00:01
618dl_src=00:00:00:00:00:02
619dl_src=00:00:00:00:00:03
620])
621AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
622dl_src=00:00:00:00:00:01
623dl_src=00:00:00:00:00:02
624dl_src=00:00:00:00:00:03
625])
ea382567
RB
626AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
627dl_src=00:00:00:00:00:01
628dl_src=00:00:00:00:00:02
629dl_src=00:00:00:00:00:03
630dl_src=ba:be:be:ef:de:ad
631])
f3a4e992
HZ
632AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
633(no flows)
634])
635AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
636ip,nw_src=1.2.3.4
637])
638AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
639ip,nw_src=1.2.3.4
640])
641AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
642
643])
644AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
645ip,nw_src=0.0.0.0/1.0.0.0
646ip,nw_src=128.0.0.0/1
647ip,nw_src=16.0.0.0/16.0.0.0
648ip,nw_src=2.0.0.0/2.0.0.0
649ip,nw_src=32.0.0.0/32.0.0.0
650ip,nw_src=4.0.0.0/4.0.0.0
651ip,nw_src=64.0.0.0/64.0.0.0
652ip,nw_src=8.0.0.0/8.0.0.0
653])
654AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
655ip,nw_src=0.0.0.0/1.0.0.0
656ip,nw_src=128.0.0.0/1
657ip,nw_src=16.0.0.0/16.0.0.0
658ip,nw_src=2.0.0.0/2.0.0.0
659ip,nw_src=32.0.0.0/32.0.0.0
660ip,nw_src=4.0.0.0/4.0.0.0
661ip,nw_src=64.0.0.0/64.0.0.0
662ip,nw_src=8.0.0.0/8.0.0.0
663])
2c5cbb15
RB
664AT_CLEANUP
665
3d2848ba
HZ
666AT_SETUP([ovn -- converting expressions to flows -- port groups])
667AT_KEYWORDS([expression])
668expr_to_flow () {
669 echo "$1" | ovstest test-ovn expr-to-flows | sort
670}
671AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
672reg15=0x11
673reg15=0x12
674reg15=0x13
675])
676AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
677(no flows)
678])
679AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
680reg15=0x11
681])
682AT_CLEANUP
683
55b25947
NS
684AT_SETUP([ovn -- converting expressions to flows -- conjunction])
685AT_KEYWORDS([conjunction])
686expr_to_flow () {
687 echo "$1" | ovstest test-ovn expr-to-flows | sort
688}
689
690lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
691ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
692AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
693conj_id=1,ip
694ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
695ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
696ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
697ip,nw_src=10.0.0.1: conjunction(1, 1/2)
698ip,nw_src=10.0.0.2: conjunction(1, 1/2)
699ip,nw_src=10.0.0.3: conjunction(1, 1/2)
700])
701
702lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
703AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
704ct_state=+est+trk,ct_label=0x1/0x1,ip
705ct_state=+est+trk,ct_label=0x1/0x1,ipv6
706ct_state=-est+trk,ip
707ct_state=-est+trk,ipv6
708])
709
710lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
711ip4.dst == {20.0.0.1, 20.0.0.2}"
712AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
713conj_id=1,ip
714ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
715ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
716ip,nw_src=10.0.0.1: conjunction(1, 1/2)
717ip,nw_src=10.0.0.2: conjunction(1, 1/2)
718ip,nw_src=10.0.0.3: conjunction(1, 1/2)
719])
720
721lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
722ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
723tcp.dst >= 1000 && tcp.dst <= 1010"
724
725AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
726conj_id=1,tcp
727tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
728tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
729tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
730tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
731tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
732tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
733tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
734tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
735tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
736tcp,tp_dst=1000: conjunction(1, 2/3)
737tcp,tp_dst=1001: conjunction(1, 2/3)
738tcp,tp_dst=1010: conjunction(1, 2/3)
739])
740
741lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
742((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
743tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
744|| ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
745
746AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
747conj_id=1,tcp
748ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
749ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
750ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
751ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
752ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
753ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
754tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
755tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
756tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
757tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
758tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
759tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
760tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
761tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
762tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
763tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
764tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
765tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
766tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
767tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
768tcp,tp_dst=1000: conjunction(1, 2/4)
769tcp,tp_dst=1001: conjunction(1, 2/4)
770tcp,tp_dst=2000: conjunction(1, 2/4)
771tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
772tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
773tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
774tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
775tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
776tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
777tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
778tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
779tcp,tp_src=1000: conjunction(1, 3/4)
780tcp,tp_src=1001: conjunction(1, 3/4)
781tcp,tp_src=2000: conjunction(1, 3/4)
782])
783AT_CLEANUP
784
3b7cb7e1 785AT_SETUP([ovn -- action parsing])
d5a76da4
BP
786dnl Unindented text is input (a set of OVN logical actions).
787dnl Indented text is expected output.
788AT_DATA([test-cases.txt],
789[[# drop
790drop;
791 encodes as drop
792drop; next;
793 Syntax error at `next' expecting end of input.
794next; drop;
795 Syntax error at `drop' expecting action.
5f822129
BP
796
797# output
d5a76da4
BP
798output;
799 encodes as resubmit(,64)
5f822129
BP
800
801# next
d5a76da4 802next;
00c875d0 803 encodes as resubmit(,19)
d5a76da4 804next(11);
8f5de083 805 formats as next;
00c875d0 806 encodes as resubmit(,19)
d5a76da4 807next(0);
00c875d0
MS
808 encodes as resubmit(,8)
809next(23);
d5a76da4
BP
810 encodes as resubmit(,31)
811
812next();
4c99cb18 813 Syntax error at `)' expecting "pipeline" or "table".
d5a76da4
BP
814next(10;
815 Syntax error at `;' expecting `)'.
00c875d0
MS
816next(24);
817 "next" action cannot advance beyond table 23.
5f822129 818
4c99cb18
BP
819next(table=11);
820 formats as next;
00c875d0 821 encodes as resubmit(,19)
4c99cb18
BP
822next(pipeline=ingress);
823 formats as next;
00c875d0 824 encodes as resubmit(,19)
4c99cb18
BP
825next(table=11, pipeline=ingress);
826 formats as next;
00c875d0 827 encodes as resubmit(,19)
4c99cb18
BP
828next(pipeline=ingress, table=11);
829 formats as next;
00c875d0 830 encodes as resubmit(,19)
4c99cb18
BP
831
832next(pipeline=egress);
833 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
834
835next(table=10);
836 formats as next(10);
00c875d0 837 encodes as resubmit(,18)
4c99cb18 838
5f822129 839# Loading a constant value.
d5a76da4
BP
840tcp.dst=80;
841 formats as tcp.dst = 80;
842 encodes as set_field:80->tcp_dst
843 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
844eth.dst[40] = 1;
845 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
846vlan.pcp = 2;
847 encodes as set_field:0x4000/0xe000->vlan_tci
848 has prereqs vlan.tci[12]
849vlan.tci[13..15] = 2;
850 encodes as set_field:0x4000/0xe000->vlan_tci
851inport = "";
852 encodes as set_field:0->reg14
853ip.ttl=4;
854 formats as ip.ttl = 4;
855 encodes as set_field:4->nw_ttl
856 has prereqs eth.type == 0x800 || eth.type == 0x86dd
857outport="eth0"; next; outport="LOCAL"; next;
8f5de083 858 formats as outport = "eth0"; next; outport = "LOCAL"; next;
00c875d0 859 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
d5a76da4
BP
860
861inport[1] = 1;
862 Cannot select subfield of string field inport.
863ip.proto[1] = 1;
864 Cannot select subfield of nominal field ip.proto.
865eth.dst[40] == 1;
866 Syntax error at `==' expecting `=' or `<->'.
867ip = 1;
868 Predicate symbol ip used where lvalue required.
869ip.proto = 6;
870 Field ip.proto is not modifiable.
871inport = {"a", "b"};
872 Syntax error at `{' expecting constant.
873inport = {};
874 Syntax error at `{' expecting constant.
875bad_prereq = 123;
876 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
877self_recurse = 123;
878 Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
879vlan.present = 0;
880 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
881
882# Moving one field into another.
d5a76da4
BP
883reg0=reg1;
884 formats as reg0 = reg1;
885 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
886vlan.pcp = reg0[0..2];
887 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
888 has prereqs vlan.tci[12]
889reg0[10] = vlan.pcp[1];
890 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
891 has prereqs vlan.tci[12]
892outport = inport;
893 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
894
895reg0[0] = vlan.present;
896 Predicate symbol vlan.present used where lvalue required.
897reg0 = reg1[0..10];
898 Can't assign 11-bit value to 32-bit destination.
899inport = reg0;
900 Can't assign integer field (reg0) to string field (inport).
901inport = big_string;
902 String fields inport and big_string are incompatible for assignment.
903ip.proto = reg0[0..7];
904 Field ip.proto is not modifiable.
5f822129
BP
905
906# Exchanging fields.
d5a76da4
BP
907reg0 <-> reg1;
908 encodes as push:NXM_NX_XXREG0[64..95],push:NXM_NX_XXREG0[96..127],pop:NXM_NX_XXREG0[64..95],pop:NXM_NX_XXREG0[96..127]
909vlan.pcp <-> reg0[0..2];
910 encodes as push:NXM_NX_XXREG0[96..98],push:NXM_OF_VLAN_TCI[13..15],pop:NXM_NX_XXREG0[96..98],pop:NXM_OF_VLAN_TCI[13..15]
911 has prereqs vlan.tci[12]
912reg0[10] <-> vlan.pcp[1];
913 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
914 has prereqs vlan.tci[12]
915outport <-> inport;
916 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
917
918reg0[0] <-> vlan.present;
919 Predicate symbol vlan.present used where lvalue required.
920reg0 <-> reg1[0..10];
921 Can't exchange 32-bit field with 11-bit field.
922inport <-> reg0;
923 Can't exchange string field (inport) with integer field (reg0).
924inport <-> big_string;
925 String fields inport and big_string are incompatible for exchange.
926ip.proto <-> reg0[0..7];
927 Field ip.proto is not modifiable.
928reg0[0..7] <-> ip.proto;
929 Field ip.proto is not modifiable.
5f822129
BP
930
931# TTL decrement.
d5a76da4
BP
932ip.ttl--;
933 encodes as dec_ttl
934 has prereqs ip
935ip.ttl
936 Syntax error at end of input expecting `--'.
5f822129 937
467085fd 938# load balancing.
d5a76da4 939ct_lb;
00c875d0 940 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
941 has prereqs ip
942ct_lb();
943 formats as ct_lb;
00c875d0 944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
945 has prereqs ip
946ct_lb(192.168.1.2:80, 192.168.1.3:80);
947 encodes as group:1
948 has prereqs ip
949ct_lb(192.168.1.2, 192.168.1.3, );
950 formats as ct_lb(192.168.1.2, 192.168.1.3);
951 encodes as group:2
952 has prereqs ip
9d236afa
MM
953ct_lb(fd0f::2, fd0f::3, );
954 formats as ct_lb(fd0f::2, fd0f::3);
955 encodes as group:3
956 has prereqs ip
d5a76da4
BP
957
958ct_lb(192.168.1.2:);
959 Syntax error at `)' expecting port number.
960ct_lb(192.168.1.2:123456);
961 Syntax error at `123456' expecting port number.
962ct_lb(foo);
9d236afa
MM
963 Syntax error at `foo' expecting IP address.
964ct_lb([192.168.1.2]);
965 Syntax error at `192.168.1.2' expecting IPv6 address.
d5a76da4
BP
966
967# ct_next
968ct_next;
00c875d0 969 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
d5a76da4
BP
970 has prereqs ip
971
972# ct_commit
973ct_commit;
974 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
975 has prereqs ip
976ct_commit();
977 formats as ct_commit;
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
979 has prereqs ip
980ct_commit(ct_mark=1);
981 formats as ct_commit(ct_mark=0x1);
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
983 has prereqs ip
984ct_commit(ct_mark=1/1);
985 formats as ct_commit(ct_mark=0x1/0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
987 has prereqs ip
988ct_commit(ct_label=1);
989 formats as ct_commit(ct_label=0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
991 has prereqs ip
992ct_commit(ct_label=1/1);
993 formats as ct_commit(ct_label=0x1/0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
995 has prereqs ip
996ct_commit(ct_mark=1, ct_label=2);
997 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
999 has prereqs ip
1000
1001ct_commit(ct_label=0x01020304050607080910111213141516);
1002 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1003 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1004 has prereqs ip
1005ct_commit(ct_label=0x181716151413121110090807060504030201);
1006 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1008 has prereqs ip
1009ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1010 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1011 has prereqs ip
1012ct_commit(ct_label=18446744073709551615);
1013 formats as ct_commit(ct_label=0xffffffffffffffff);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1015 has prereqs ip
1016ct_commit(ct_label=18446744073709551616);
1017 Decimal constants must be less than 2**64.
1018
1019# ct_dnat
1020ct_dnat;
00c875d0 1021 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
d5a76da4
BP
1022 has prereqs ip
1023ct_dnat(192.168.1.2);
00c875d0 1024 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
d5a76da4
BP
1025 has prereqs ip
1026
1027ct_dnat(192.168.1.2, 192.168.1.3);
1028 Syntax error at `,' expecting `)'.
1029ct_dnat(foo);
1030 Syntax error at `foo' expecting IPv4 address.
1031ct_dnat(foo, bar);
1032 Syntax error at `foo' expecting IPv4 address.
1033ct_dnat();
1034 Syntax error at `)' expecting IPv4 address.
1035
1036# ct_snat
1037ct_snat;
00c875d0 1038 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
d5a76da4
BP
1039 has prereqs ip
1040ct_snat(192.168.1.2);
00c875d0 1041 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
d5a76da4
BP
1042 has prereqs ip
1043
1044ct_snat(192.168.1.2, 192.168.1.3);
1045 Syntax error at `,' expecting `)'.
1046ct_snat(foo);
1047 Syntax error at `foo' expecting IPv4 address.
1048ct_snat(foo, bar);
1049 Syntax error at `foo' expecting IPv4 address.
1050ct_snat();
1051 Syntax error at `)' expecting IPv4 address.
de297547 1052
db0e819b
BP
1053# ct_clear
1054ct_clear;
1055 encodes as ct_clear
1056
b3bd2c33 1057# clone
8f5de083 1058clone { ip4.dst = 255.255.255.255; output; }; next;
00c875d0 1059 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
b3bd2c33
BP
1060 has prereqs eth.type == 0x800
1061
6335d074 1062# arp
8a41ad8e
BP
1063arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1064 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
d5a76da4 1065 has prereqs ip4
bac29564
BP
1066arp { };
1067 formats as arp { drop; };
1068 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1069 has prereqs ip4
6335d074 1070
0bac7164 1071# get_arp
d5a76da4
BP
1072get_arp(outport, ip4.dst);
1073 encodes as push:NXM_NX_REG0[],push:NXM_OF_IP_DST[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[]
1074 has prereqs eth.type == 0x800
1075get_arp(inport, reg0);
1076 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG0[],push:NXM_NX_XXREG0[96..127],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[],pop:NXM_NX_REG15[]
1077
1078get_arp;
1079 Syntax error at `;' expecting `('.
1080get_arp();
1081 Syntax error at `)' expecting field name.
1082get_arp(inport);
1083 Syntax error at `)' expecting `,'.
1084get_arp(inport ip4.dst);
1085 Syntax error at `ip4.dst' expecting `,'.
1086get_arp(inport, ip4.dst;
1087 Syntax error at `;' expecting `)'.
1088get_arp(inport, eth.dst);
1089 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1090get_arp(inport, outport);
1091 Cannot use string field outport where numeric field is required.
1092get_arp(reg0, ip4.dst);
1093 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
1094
1095# put_arp
d5a76da4
BP
1096put_arp(inport, arp.spa, arp.sha);
1097 encodes as push:NXM_NX_REG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ARP_SHA[],push:NXM_OF_ARP_SPA[],pop:NXM_NX_REG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.01.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_REG0[]
1098 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 1099
42814145 1100# put_dhcp_opts
d5a76da4
BP
1101reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1102 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.40.01.02.03.04.03.04.0a.00.00.01,pause)
1103reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
1104 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain = "ovn.org");
1105 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67,pause)
1106reg0[15] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.255.0,mtu=1400,ip_forward_enable=1,default_ttl=121,dns_server={8.8.8.8,7.7.7.7},classless_static_route={30.0.0.0/24,10.0.0.4,40.0.0.0/16,10.0.0.6,0.0.0.0/0,10.0.0.1},ethernet_encap=1,router_discovery=0);
1107 formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, ethernet_encap = 1, router_discovery = 0);
1108 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00,pause)
1109
1110reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1111 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1112reg1[0] = put_dhcp_opts();
1113 put_dhcp_opts requires offerip to be specified.
1114reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1115 Syntax error at `x' expecting DHCPv4 option name.
1116reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1117 put_dhcp_opts requires offerip to be specified.
1118reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1119 Syntax error at `"hi"'.
1120reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1121 Syntax error at `xyzzy' expecting DHCPv4 option name.
1122reg1[0] = put_dhcp_opts(offerip="xyzzy");
1123 DHCPv4 option offerip requires numeric value.
1124reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1125 DHCPv4 option domain requires string value.
42814145 1126
b1a3a6a4
NS
1127# nd_ns
1128nd_ns { nd.target = xxreg0; output; };
1129 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1130 has prereqs ip6
1131
1132nd_ns { };
1133 formats as nd_ns { drop; };
1134 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1135 has prereqs ip6
1136
f8a8db39 1137# nd_na
d5a76da4
BP
1138nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1139 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1140 encodes as controller(userdata=00.00.00.03.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1141 has prereqs nd_ns
c9756229
NS
1142# nd_na_router
1143nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1144 formats as nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1145 encodes as controller(userdata=00.00.00.0c.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1146 has prereqs nd_ns
e75451fe 1147
c34a87b6 1148# get_nd
d5a76da4
BP
1149get_nd(outport, ip6.dst);
1150 encodes as push:NXM_NX_XXREG0[],push:NXM_NX_IPV6_DST[],pop:NXM_NX_XXREG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_XXREG0[]
1151 has prereqs eth.type == 0x86dd
1152get_nd(inport, xxreg0);
1153 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG15[]
1154get_nd;
1155 Syntax error at `;' expecting `('.
1156get_nd();
1157 Syntax error at `)' expecting field name.
1158get_nd(inport);
1159 Syntax error at `)' expecting `,'.
1160get_nd(inport ip6.dst);
1161 Syntax error at `ip6.dst' expecting `,'.
1162get_nd(inport, ip6.dst;
1163 Syntax error at `;' expecting `)'.
1164get_nd(inport, eth.dst);
1165 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1166get_nd(inport, outport);
1167 Cannot use string field outport where numeric field is required.
1168get_nd(xxreg0, ip6.dst);
1169 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
1170
1171# put_nd
d5a76da4
BP
1172put_nd(inport, nd.target, nd.sll);
1173 encodes as push:NXM_NX_XXREG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ND_SLL[],push:NXM_NX_ND_TARGET[],pop:NXM_NX_XXREG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.04.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_XXREG0[]
32157c87 1174 has prereqs (icmp6.type == 0x87 || icmp6.type == 0x88) && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
c34a87b6 1175
01cfdb2f 1176# put_dhcpv6_opts
d5a76da4 1177reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
a55dacac 1178 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.05.00.10.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.00.02.00.06.00.00.00.00.10.02,pause)
d5a76da4
BP
1179reg1[0] = put_dhcpv6_opts();
1180 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1181reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1182 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
a55dacac 1183 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
40df4566
ZKL
1184reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1185 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
a55dacac 1186 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.02.00.06.12.34.56.78.9a.bc.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.89.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
d5a76da4 1187reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
a55dacac 1188 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.18.00.07.6f.76.6e.2e.6f.72.67,pause)
d5a76da4
BP
1189reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1190 Syntax error at `x' expecting DHCPv6 option name.
1191reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1192 Syntax error at `"hi"'.
1193reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1194 Syntax error at `xyzzy' expecting DHCPv6 option name.
1195reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1196 DHCPv6 option ia_addr requires numeric value.
1197reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1198 DHCPv6 option domain_search requires string value.
01cfdb2f 1199
a6095f81
BS
1200# set_queue
1201set_queue(0);
1202 encodes as set_queue:0
1203set_queue(61440);
1204 encodes as set_queue:61440
1205set_queue(65535);
1206 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1207
ea991ad2
NS
1208# dns_lookup
1209reg1[0] = dns_lookup();
1210 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1211 has prereqs udp
1212reg1[0] = dns_lookup("foo");
1213 dns_lookup doesn't take any parameters
1214
66d89287
GL
1215# set_meter
1216set_meter(0);
1217 Rate 0 for set_meter is not in valid.
1218set_meter(1);
1219 encodes as meter:1
1220set_meter(100, 1000);
1221 encodes as meter:2
1222set_meter(100, 1000, );
1223 Syntax error at `,' expecting `)'.
1224set_meter(4294967295, 4294967295);
1225 encodes as meter:3
1226
52ed5fcc
NS
1227# put_nd_ra_opts
1228reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1229 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
1230 has prereqs ip6
1231reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1232 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
1233 has prereqs ip6
1234reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1235 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
1236 has prereqs ip6
1237reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1238 slla option not present
1239reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1240 prefix option can't be set when address mode is dhcpv6_stateful.
1241reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1242 prefix option can't be set when address mode is dhcpv6_stateful.
1243reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1244 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1245reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1246 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1247reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1248 Syntax error at `dhcpv6_stateless' expecting constant.
1249reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1250 Invalid value for "prefix" option
1251reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1252 Invalid value for "addr_mode" option
1253reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1254 IPv6 ND RA option mtu requires numeric value.
1255reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1256 Invalid value for "mtu" option
1257
bc3d6a63
LB
1258# icmp4
1259icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1260 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1261 has prereqs ip4
1262
1263icmp4 { };
1264 formats as icmp4 { drop; };
1265 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1266 has prereqs ip4
1267
3e7fa1e3
LB
1268# icmp6
1269icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1270 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1271 has prereqs ip6
1272
1273icmp6 { };
1274 formats as icmp6 { drop; };
1275 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1276 has prereqs ip6
1277
22b65e4d
LB
1278# tcp_reset
1279tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1280 encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1281 has prereqs tcp
1282
1283tcp_reset { };
1284 formats as tcp_reset { drop; };
1285 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1286 has prereqs tcp
1287
5f822129 1288# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
1289ip4.src = ip6.src[0..31];
1290 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1291 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1292ip4.src <-> ip6.src[0..31];
1293 encodes as push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[]
1294 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1295
1296# Miscellaneous negative tests.
1297;
1298 Syntax error at `;'.
1299xyzzy;
1300 Syntax error at `xyzzy' expecting action.
1301next; 123;
1302 Syntax error at `123'.
1303next; xyzzy;
1304 Syntax error at `xyzzy' expecting action.
1305next
9aef3c1b 1306 Syntax error at end of input expecting `;'.
3b7cb7e1 1307]])
d5a76da4
BP
1308sed '/^[[ ]]/d' test-cases.txt > input.txt
1309cp test-cases.txt expout
3b7cb7e1
BP
1310AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1311AT_CLEANUP
f295c17b
BP
1312
1313AT_BANNER([OVN end-to-end tests])
1314
9975d7be
BP
1315# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1316AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1317AT_KEYWORDS([ovnarp])
f295c17b
BP
1318AT_SKIP_IF([test $HAVE_PYTHON = no])
1319ovn_start
1320
1321# Create hypervisors hv[123].
9975d7be 1322# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1323# Add all of the vifs to a single logical switch lsw0.
1324# Turn on port security on all the vifs except vif[123]1.
1325# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1326# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1327ovn-nbctl ls-add lsw0
f295c17b
BP
1328net_add n1
1329for i in 1 2 3; do
1330 sim_add hv$i
1331 as hv$i
1332 ovs-vsctl add-br br-phys
1333 ovn_attach n1 br-phys 192.168.0.$i
1334
1335 for j in 1 2 3; do
1336 ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
31ed1192 1337 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1338 if test $j = 1; then
31ed1192 1339 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1340 else
7dc88496
NS
1341 if test $j = 3; then
1342 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1343 else
1344 ip_addrs="192.168.0.$i$j"
1345 fi
31ed1192
JP
1346 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1347 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1348 fi
1349 done
1350done
1351ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1352ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1353ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1354ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:11\",\"f0:00:00:00:00:21\",\"f0:00:00:00:00:31\"
1355ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b 1356
3d2848ba
HZ
1357get_lsp_uuid () {
1358 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1359}
1360
1361ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1362ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1363
f295c17b
BP
1364# Pre-populate the hypervisors' ARP tables so that we don't lose any
1365# packets for ARP resolution (native tunneling doesn't queue packets
1366# for ARP resolution).
74868f2c 1367OVN_POPULATE_ARP
f295c17b
BP
1368
1369# Allow some time for ovn-northd and ovn-controller to catch up.
1370# XXX This should be more systematic.
1371sleep 1
611099dc 1372
fc6f9978
HZ
1373# Make sure there is no attempt to adding duplicated flows by ovn-controller
1374AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1375AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1376AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1377
57d143eb
HZ
1378# Given the name of a logical port, prints the name of the hypervisor
1379# on which it is located.
1380vif_to_hv() {
1381 echo hv${1%?}
1382}
1383
f295c17b
BP
1384# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1385#
1386# This shell function causes a packet to be received on INPORT. The packet's
1387# content has Ethernet destination DST and source SRC (each exactly 12 hex
1388# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1389# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1390# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1391for i in 1 2 3; do
1392 for j in 1 2 3; do
1393 : > $i$j.expected
1394 done
1395done
1396test_packet() {
1397 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1398 hv=`vif_to_hv $inport`
f295c17b
BP
1399 vif=vif$inport
1400 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1401 for outport; do
e4543cfe 1402 echo $packet >> $outport.expected
f295c17b
BP
1403 done
1404}
1405
57d143eb
HZ
1406# test_arp INPORT SHA SPA TPA [REPLY_HA]
1407#
1408# Causes a packet to be received on INPORT. The packet is an ARP
1409# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1410# it should be the hardware address of the target to expect to receive in an
1411# ARP reply; otherwise no reply is expected.
1412#
31ed1192 1413# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1414# SHA and REPLY_HA are each 12 hex digits.
1415# SPA and TPA are each 8 hex digits.
1416test_arp() {
1417 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1418 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1419 hv=`vif_to_hv $inport`
1420 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1421
92f9822b 1422 if test X$reply_ha = X; then
57d143eb
HZ
1423 # Expect to receive the broadcast ARP on the other logical switch ports
1424 # if no reply is expected.
1425 local i j
1426 for i in 1 2 3; do
1427 for j in 1 2 3; do
1428 if test $i$j != $inport; then
1429 echo $request >> $i$j.expected
1430 fi
1431 done
1432 done
1433 else
1434 # Expect to receive the reply, if any.
1435 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1436 echo $reply >> $inport.expected
1437 fi
1438}
1439
1440ip_to_hex() {
1441 printf "%02x%02x%02x%02x" "$@"
1442}
1443
f295c17b
BP
1444# Send packets between all pairs of source and destination ports:
1445#
31ed1192
JP
1446# 1. Unicast packets are delivered to exactly one logical switch port
1447# (except that packets destined to their input ports are dropped).
f295c17b 1448#
31ed1192
JP
1449# 2. Broadcast and multicast are delivered to all logical switch ports
1450# except the input port.
f295c17b 1451#
ea46a4e9 1452# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1453# MAC address.
1454#
ea46a4e9 1455# 4. The switch drops all packets with a VLAN tag.
f295c17b 1456#
ea46a4e9 1457# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1458# affects behavior when port security is turned off, since otherwise port
1459# security would drop the packet anyway.)
1460#
ea46a4e9 1461# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1462# switch ports with "unknown" among their MAC addresses (and port
1463# security disabled).
f295c17b 1464#
ea46a4e9 1465# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1466#
ea46a4e9 1467# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1468#
9fcb6a18
BP
1469# 9. OVN generates responses to ARP requests for known IPs, except for
1470# requests from a port for the port's own IP.
57d143eb
HZ
1471#
1472# 10. No response to ARP requests for unknown IPs.
4acd1e87 1473
f295c17b
BP
1474for is in 1 2 3; do
1475 for js in 1 2 3; do
1476 s=$is$js
1477 bcast=
4d5c43d5
JP
1478 unknown=
1479 bacl2=
1480 bacl3=
f295c17b
BP
1481 for id in 1 2 3; do
1482 for jd in 1 2 3; do
1483 d=$id$jd
1484
1485 if test $d != $s; then unicast=$d; else unicast=; fi
1486 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1487
1488 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1489 impersonate=$d
1490 else
1491 impersonate=
1492 fi
f295c17b
BP
1493 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1494
4d5c43d5
JP
1495 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1496 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1497 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1498 # Source of 11, 21, or 31 and dest of 33 should be dropped
1499 # due to the 4th ACL that uses address_set(set1).
1500 acl4=
1501 else
1502 acl4=$d
1503 fi
3d2848ba
HZ
1504 if test $d = $s || test $d = 22 || test $d = 33; then
1505 # dest of 22 and 33 should be dropped
1506 # due to the 5th ACL that uses port_group(pg1).
1507 acl5=
1508 else
1509 acl5=$d
1510 fi
f295c17b
BP
1511 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1512 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1513 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1514 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
3d2848ba 1515 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
f295c17b
BP
1516
1517 test_packet $s f000000000$d f00000000055 810000091234 #4
1518 test_packet $s f000000000$d 0100000000$s $s$d #5
1519
4d5c43d5
JP
1520 if test $d != $s && test $jd = 1; then
1521 unknown="$unknown $d"
1522 fi
f295c17b
BP
1523 bcast="$bcast $unicast"
1524 bacl2="$bacl2 $acl2"
1525 bacl3="$bacl3 $acl3"
57d143eb 1526
db02f370 1527 sip=`ip_to_hex 192 168 0 $is$js`
57d143eb
HZ
1528 tip=`ip_to_hex 192 168 0 $id$jd`
1529 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1530 if test $d != $s; then
1531 reply_ha=f000000000$d
1532 else
1533 reply_ha=
1534 fi
1535 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1536 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1537
1538 if test $jd = 3; then
31ed1192 1539 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1540 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1541 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1542 fi
f295c17b
BP
1543 done
1544 done
1545
4d5c43d5 1546 # Broadcast and multicast.
f295c17b
BP
1547 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1548 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1549 if test $js = 1; then
f295c17b
BP
1550 bcast_impersonate=$bcast
1551 else
4d5c43d5
JP
1552 bcast_impersonate=
1553 fi
f295c17b
BP
1554 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1555
1556 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1557
1558 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1559 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1560 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1561 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1562 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1563 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1564 done
1565done
1566
7dc88496
NS
1567# set address for lp13 with invalid characters.
1568# lp13 should be configured with only 192.168.0.13.
31ed1192 1569ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1570
1571# Allow some time for ovn-northd and ovn-controller to catch up.
1572# XXX This should be more systematic.
1573sleep 1
1574
7dc88496
NS
1575sip=`ip_to_hex 192 168 0 11`
1576tip=`ip_to_hex 192 168 0 13`
1577test_arp 11 f00000000011 $sip $tip f00000000013
1578
1579tip=`ip_to_hex 192 169 0 13`
1580#arp request for 192.169.0.13 should be flooded
1581test_arp 11 f00000000011 $sip $tip
1582
91125642 1583# dump information and flows with counters
bb0c41d3
RM
1584ovn-sbctl dump-flows -- list multicast_group
1585
1586echo "------ hv1 dump ------"
1587as hv1 ovs-vsctl show
1588as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1589
1590echo "------ hv2 dump ------"
1591as hv2 ovs-vsctl show
1592as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1593
1594echo "------ hv3 dump ------"
1595as hv3 ovs-vsctl show
1596as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1597
f295c17b
BP
1598# Now check the packets actually received against the ones expected.
1599for i in 1 2 3; do
1600 for j in 1 2 3; do
49d7c759 1601 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1602 done
1603done
fcde56f5 1604
7a8f15e0 1605OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1606
f295c17b 1607AT_CLEANUP
eb6b08eb 1608
4acd1e87
BP
1609AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1610AT_SKIP_IF([test $HAVE_PYTHON = no])
1611ovn_start
1612
1613# Create a logical switch and some logical ports.
1614# Turn on port security on all lports except ls1.
1615# Make ls1 a destination for unknown MACs.
1616# Add some ACLs for Ethertypes 1234, 1235, 1236.
1617ovn-nbctl ls-add lsw0
1618ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1619for i in 1 2 3; do
1620 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1621done
1622ovn-nbctl --wait=sb sync
1623for i in 1 2 3; do
4acd1e87
BP
1624 ovn-sbctl lsp-bind lp$i hv0
1625 if test $i = 1; then
abb37b6b 1626 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1627 else
abb37b6b
FF
1628 if test $i = 3; then
1629 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1630 else
1631 ip_addrs="192.168.0.$i"
1632 fi
a8e2addc
LR
1633 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1634 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
4acd1e87
BP
1635 fi
1636done
1637ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1638ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1639ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1640ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1641ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1642
1643ovn-nbctl --wait=sb sync
1644on_exit 'kill `cat ovn-trace.pid`'
1645ovn-trace --detach --pidfile --no-chdir
1646
1647# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1648#
1649# This shell function causes a packet to be received on INPORT. The packet's
1650# content has Ethernet destination DST and source SRC (each exactly 12 hex
1651# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1652# more) list the VIFs on which the packet should be received. INPORT and the
1653# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1654test_packet() {
1655 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1656 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1657 while :; do
abb37b6b
FF
1658 case $1 in # (
1659 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1660 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1661 *) break ;;
1662 esac
4acd1e87
BP
1663 done
1664 for outport; do
abb37b6b 1665 echo "output(\"lp$outport\");"
4acd1e87
BP
1666 done > expout
1667
1668 AT_CAPTURE_FILE([trace])
1669 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1670}
1671
1672# test_arp INPORT SHA SPA TPA [REPLY_HA]
1673#
1674# Causes a packet to be received on INPORT. The packet is an ARP
1675# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1676# it should be the hardware address of the target to expect to receive in an
1677# ARP reply; otherwise no reply is expected.
1678#
1679# INPORT is an logical switch port number, e.g. 11 for vif11.
1680# SHA and REPLY_HA are each 12 hex digits.
1681# SPA and TPA are each 8 hex digits.
1682test_arp() {
1683 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1684
1685 local request="inport == \"lp$inport\"
1686 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1687 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1688 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1689
1690 if test -z "$reply_ha"; then
1691 reply=
abb37b6b
FF
1692 local i
1693 for i in 1 2 3; do
1694 if test $i != $inport; then
1695 reply="${reply}output(\"lp$i\");
4acd1e87 1696"
abb37b6b
FF
1697 fi
1698 done
4acd1e87
BP
1699 else
1700 reply="\
1701eth.dst = $sha;
1702eth.src = $reply_ha;
1703arp.op = 2;
1704arp.tha = $sha;
1705arp.sha = $reply_ha;
1706arp.tpa = $spa;
1707arp.spa = $tpa;
1708output(\"lp$inport\");
1709"
1710 fi
1711
1712 AT_CAPTURE_FILE([trace])
1713 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1714}
1715
1716# Send packets between all pairs of source and destination ports:
1717#
1718# 1. Unicast packets are delivered to exactly one logical switch port
1719# (except that packets destined to their input ports are dropped).
1720#
1721# 2. Broadcast and multicast are delivered to all logical switch ports
1722# except the input port.
1723#
1724# 3. When port security is turned on, the switch drops packets from the wrong
1725# MAC address.
1726#
1727# 4. The switch drops all packets with a VLAN tag.
1728#
1729# 5. The switch drops all packets with a multicast source address. (This only
1730# affects behavior when port security is turned off, since otherwise port
1731# security would drop the packet anyway.)
1732#
1733# 6. The switch delivers packets with an unknown destination to logical
1734# switch ports with "unknown" among their MAC addresses (and port
1735# security disabled).
1736#
1737# 7. The switch drops unicast packets that violate an ACL.
1738#
1739# 8. The switch drops multicast and broadcast packets that violate an ACL.
1740#
9fcb6a18
BP
1741# 9. OVN generates responses to ARP requests for known IPs, except for
1742# requests from a port for the port's own IP.
4acd1e87
BP
1743#
1744# 10. No response to ARP requests for unknown IPs.
1745
1746for s in 1 2 3; do
1747 bcast=
1748 unknown=
1749 bacl2=
1750 bacl3=
1751 for d in 1 2 3; do
abb37b6b
FF
1752 echo
1753 echo "lp$s -> lp$d"
1754 if test $d != $s; then unicast=$d; else unicast=; fi
1755 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1756
1757 if test $d != $s && test $s = 1; then
1758 impersonate=$d
1759 else
1760 impersonate=
1761 fi
1762 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1763
1764 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1765 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1766 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1767 # Source of 1 or 2 and dest of 3 should be dropped
1768 # due to the 4th ACL that uses address_set(set1).
1769 acl4=
1770 else
1771 acl4=$d
1772 fi
1773
1774 #7, acl1 to acl4:
1775 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1776 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1777 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1778 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1779
1780 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1781 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1782
1783 if test $d != $s && test $d = 1; then
1784 unknown="$unknown $d"
1785 fi
1786 bcast="$bcast $unicast"
1787 bacl2="$bacl2 $acl2"
1788 bacl3="$bacl3 $acl3"
1789
1790 sip=192.168.0.$s
1791 tip=192.168.0.$d
1792 tip_unknown=11.11.11.11
9fcb6a18
BP
1793 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1794 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1795 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1796
1797 if test $d = 3; then
1798 # lp3 has an additional ip 192.169.0.[123]3.
1799 tip=192.169.0.$d
9fcb6a18 1800 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1801 fi
4acd1e87
BP
1802 done
1803
1804 # Broadcast and multicast.
1805 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1806 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1807 if test $s = 1; then
abb37b6b 1808 bcast_impersonate=$bcast
4acd1e87 1809 else
abb37b6b 1810 bcast_impersonate=
4acd1e87
BP
1811 fi
1812 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1813
1814 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1815
1816 #8, acl1 to acl3:
1817 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1818 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1819 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1820
1821 #8, acl1 to acl3:
1822 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1823 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1824 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1825done
1826
1827AT_CLEANUP
1828
7277bc83
RB
1829# 2 hypervisors, 4 logical ports per HV
1830# 2 locally attached networks (one flat, one vlan tagged over same device)
1831# 2 ports per HV on each network
e90aeb57 1832AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1833AT_SKIP_IF([test $HAVE_PYTHON = no])
1834ovn_start
1835
ea46a4e9
JP
1836# In this test cases we create 3 switches, all connected to same
1837# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1838# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1839# of VIF port name indicates the hypervisor it is bound to, e.g.
1840# lp23 means VIF 3 on hv2.
1841#
ea46a4e9 1842# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1843# - ls1:
1844# - untagged
ea46a4e9 1845# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1846#
1847# - ls2:
1848# - tagged with VLAN 101
ea46a4e9 1849# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1850# - ls3:
1851# - untagged
ea46a4e9 1852# - ports: lp15, lp25
0ee7f7f1 1853#
ea46a4e9 1854# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1855# physical network.
1856
1857for i in 1 2 3; do
ea46a4e9
JP
1858 ls_name=ls$i
1859 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1860 ln_port_name=ln$i
1861 if test $i -eq 2; then
ea46a4e9 1862 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1863 else
ea46a4e9 1864 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1865 fi
31ed1192
JP
1866 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1867 ovn-nbctl lsp-set-type $ln_port_name localnet
1868 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1869done
d79fc5f4 1870
69b72264
BP
1871# lsp_to_ls LSP
1872#
1873# Prints the name of the logical switch that contains LSP.
1874lsp_to_ls () {
1875 case $1 in dnl (
5a0e4aec
BP
1876 lp?[[12]]) echo ls1 ;; dnl (
1877 lp?[[34]]) echo ls2 ;; dnl (
1878 lp?5) echo ls3 ;; dnl (
1879 *) AT_FAIL_IF([:]) ;;
69b72264
BP
1880 esac
1881}
1882
d79fc5f4
RB
1883net_add n1
1884for i in 1 2; do
1885 sim_add hv$i
1886 as hv$i
1887 ovs-vsctl add-br br-phys
1888 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1889 ovn_attach n1 br-phys 192.168.0.$i
1890
0ee7f7f1 1891 for j in 1 2 3 4 5; do
d79fc5f4
RB
1892 ovs-vsctl add-port br-int vif$i$j -- \
1893 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1894 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1895 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1896 ofport-request=$i$j
1897
31ed1192 1898 lsp_name=lp$i$j
5a0e4aec 1899 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 1900
ea46a4e9 1901 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1902 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1903 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1904
31ed1192 1905 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1906 done
1907done
69b72264
BP
1908ovn-nbctl --wait=sb sync
1909ovn-sbctl dump-flows
d79fc5f4 1910
74868f2c 1911OVN_POPULATE_ARP
d79fc5f4
RB
1912
1913# XXX This is now the 3rd copy of these functions in this file ...
1914
1915# Given the name of a logical port, prints the name of the hypervisor
1916# on which it is located.
1917vif_to_hv() {
1918 echo hv${1%?}
1919}
1920#
69b72264 1921# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
1922#
1923# This shell function causes a packet to be received on INPORT. The packet's
1924# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
1925# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1926# logical switch port numbers, e.g. 11 for vif11.
1927#
1928# EOUT is the end-to-end output port, that is, where the packet will end up
1929# after possibly bouncing through one or more localnet ports. LOUT is the
1930# logical output port, which might be a localnet port, as seen by ovn-trace
1931# (which doesn't know what localnet ports are connected to and therefore can't
1932# figure out the end-to-end answer).
d79fc5f4 1933for i in 1 2; do
0ee7f7f1 1934 for j in 1 2 3 4 5; do
d79fc5f4
RB
1935 : > $i$j.expected
1936 done
1937done
1938test_packet() {
69b72264
BP
1939 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1940 echo "$@"
1941
1942 # First try tracing the packet.
1943 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1944 if test $lout != drop; then
1945 echo "output(\"$lout\");"
1946 fi > expout
1947 AT_CAPTURE_FILE([trace])
1948 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1949
1950 # Then actually send a packet, for an end-to-end test.
1951 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
1952 hv=`vif_to_hv $inport`
1953 vif=vif$inport
1954 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
1955 if test $eout != drop; then
1956 echo $packet >> ${eout#lp}.expected
1957 fi
d79fc5f4
RB
1958}
1959
7277bc83
RB
1960# lp11 and lp21 are on the same network (phys, untagged)
1961# and on different hypervisors
69b72264
BP
1962test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1963test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 1964
7277bc83
RB
1965# lp11 and lp12 are on the same network (phys, untagged)
1966# and on the same hypervisor
69b72264
BP
1967test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1968test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
1969
1970# lp13 and lp23 are on the same network (phys, VLAN 101)
1971# and on different hypervisors
69b72264
BP
1972test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1973test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
1974
1975# lp13 and lp14 are on the same network (phys, VLAN 101)
1976# and on the same hypervisor
69b72264
BP
1977test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1978test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 1979
0ee7f7f1 1980# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 1981# same hypervisor, and on different switches
69b72264
BP
1982test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1983test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
1984
1985# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 1986# different hypervisors, and on different switches
69b72264
BP
1987test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1988test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 1989
d79fc5f4 1990# Ports that should not be able to communicate
69b72264
BP
1991test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1992test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1993test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1994test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1995test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1996test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1997test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1998test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 1999
d79fc5f4
RB
2000# Dump a bunch of info helpful for debugging if there's a failure.
2001
2002echo "------ OVN dump ------"
2003ovn-nbctl show
2004ovn-sbctl show
2005
2006echo "------ hv1 dump ------"
2007as hv1 ovs-vsctl show
2008as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2009
2010echo "------ hv2 dump ------"
2011as hv2 ovs-vsctl show
2012as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2013
2014# Now check the packets actually received against the ones expected.
2015for i in 1 2; do
0ee7f7f1 2016 for j in 1 2 3 4 5; do
49d7c759 2017 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
2018 done
2019done
2020
7a8f15e0 2021OVN_CLEANUP([hv1],[hv2])
d9c8c57c 2022
d79fc5f4
RB
2023AT_CLEANUP
2024
91125642
FF
2025AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2026AT_KEYWORDS([vtep])
eb6b08eb
JP
2027AT_SKIP_IF([test $HAVE_PYTHON = no])
2028ovn_start
2029
2030# Configure the Northbound database
ea46a4e9 2031ovn-nbctl ls-add lsw0
eb6b08eb 2032
31ed1192
JP
2033ovn-nbctl lsp-add lsw0 lp1
2034ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 2035
31ed1192
JP
2036ovn-nbctl lsp-add lsw0 lp2
2037ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 2038
31ed1192
JP
2039ovn-nbctl lsp-add lsw0 lp-vtep
2040ovn-nbctl lsp-set-type lp-vtep vtep
2041ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2042ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 2043
77adbb62
DB
2044# lpr, lr and lrp1 are used for the ARP request handling test only.
2045ovn-nbctl lsp-add lsw0 lpr
2046ovn-nbctl lr-add lr
2047ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2048ovn-nbctl set Logical_Switch_Port lpr type=router \
2049 options:router-port=lrp1 \
2050 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2051
2052
eb6b08eb
JP
2053net_add n1 # Network to connect hv1, hv2, and vtep
2054net_add n2 # Network to connect vtep and hv3
2055
2056# Create hypervisor hv1 connected to n1
2057sim_add hv1
2058as hv1
2059ovs-vsctl add-br br-phys
2060ovn_attach n1 br-phys 192.168.0.1
2061ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
2062
2063# Create hypervisor hv2 connected to n1
2064sim_add hv2
2065as hv2
2066ovs-vsctl add-br br-phys
2067ovn_attach n1 br-phys 192.168.0.2
2068ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
2069
2070
2071# Start the vtep emulator with a leg in both networks
2072sim_add vtep
2073as vtep
2074
2075ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2076ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2077
2078ovs-vsctl add-br br-phys
2079net_attach n1 br-phys
2080
2081mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2082arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2083ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2084ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2085
2086ovs-vsctl add-br br-vtep
2087net_attach n2 br-vtep
2088
2089vtep-ctl add-ps br-vtep
2090vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2091vtep-ctl add-ls lsw0
2092
2093start_daemon ovs-vtep br-vtep
2094start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2095
8cdc4312 2096OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 2097
475f0a2c
DB
2098OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2099 grep -- source`"])
2100# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
2101sleep 1
2102
2103# Add hv3 on the other side of the vtep
2104sim_add hv3
2105as hv3
2106ovs-vsctl add-br br-phys
2107net_attach n2 br-phys
2108
2109ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
2110
2111# Pre-populate the hypervisors' ARP tables so that we don't lose any
2112# packets for ARP resolution (native tunneling doesn't queue packets
2113# for ARP resolution).
74868f2c 2114OVN_POPULATE_ARP
eb6b08eb
JP
2115
2116# Allow some time for ovn-northd and ovn-controller to catch up.
2117# XXX This should be more systematic.
2118sleep 1
6977df72 2119
eb6b08eb
JP
2120# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2121#
2122# This shell function causes a packet to be received on INPORT. The packet's
2123# content has Ethernet destination DST and source SRC (each exactly 12 hex
2124# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2125# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2126# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
2127for i in 1 2 3; do
2128 : > $i.expected
2129done
2130test_packet() {
2131 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2132 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2133 hv=hv$inport
2134 vif=vif$inport
2135 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2136 for outport; do
e4543cfe 2137 echo $packet >> $outport.expected
eb6b08eb
JP
2138 done
2139}
2140
2141# Send packets between all pairs of source and destination ports:
2142#
31ed1192
JP
2143# 1. Unicast packets are delivered to exactly one logical switch port
2144# (except that packets destined to their input ports are dropped).
eb6b08eb 2145#
31ed1192
JP
2146# 2. Broadcast and multicast are delivered to all logical switch ports
2147# except the input port.
eb6b08eb 2148#
ea46a4e9 2149# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
2150# switch ports with "unknown" among their MAC addresses (and port
2151# security disabled).
eb6b08eb
JP
2152for s in 1 2 3; do
2153 bcast=
2154 unknown=
2155 for d in 1 2 3; do
2156 if test $d != $s; then unicast=$d; else unicast=; fi
2157 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2158
2159 # The vtep (vif3) is the only one configured for "unknown"
2160 if test $d != $s && test $d = 3; then
2161 unknown="$unknown $d"
2162 fi
2163 bcast="$bcast $unicast"
2164 done
2165
2166 # Broadcast and multicast.
46ed1382
DB
2167 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2168 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
2169
2170 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2171done
2172
77adbb62
DB
2173# ARP request should not be responded to by logical switch router
2174# type arp responder on HV1 and HV2 and should reach directly to
2175# vif1 and vif2
2176ip_to_hex() {
2177 printf "%02x%02x%02x%02x" "$@"
2178}
2179sha=f00000000003
2180spa=`ip_to_hex 192 168 1 2`
2181tpa=`ip_to_hex 192 168 1 1`
2182request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2183as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2184echo $request >> 1.expected
2185echo $request >> 2.expected
2186
bb0c41d3
RM
2187# dump information with counters
2188echo "------ OVN dump ------"
2189ovn-nbctl show
2190ovn-sbctl show
2191
77adbb62
DB
2192echo "---------SB dump-----"
2193ovn-sbctl list datapath_binding
2194echo "---------------------"
2195ovn-sbctl list port_binding
2196echo "---------------------"
2197ovn-sbctl dump-flows
2198
bb0c41d3
RM
2199echo "------ hv1 dump ------"
2200as hv1 ovs-vsctl show
6195e2e7 2201as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2202as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2203
2204echo "------ hv2 dump ------"
2205as hv2 ovs-vsctl show
6195e2e7 2206as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2207as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2208
2209echo "------ hv3 dump ------"
2210as hv3 ovs-vsctl show
6754e92d
FF
2211# note: hv3 has no logical port bind, thus it should not have br-int
2212AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2213[ovs-ofctl: br-int is not a bridge or a socket
2214])
bb0c41d3 2215
eb6b08eb
JP
2216# Now check the packets actually received against the ones expected.
2217for i in 1 2 3; do
49d7c759 2218 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 2219done
fcde56f5
LR
2220
2221# Gracefully terminate daemons
7a8f15e0
LR
2222OVN_CLEANUP([hv1],[hv2],[vtep])
2223OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 2224
eb6b08eb 2225AT_CLEANUP
9975d7be 2226
184bc3ca
RB
2227# Similar test to "hardware GW"
2228AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2229AT_SKIP_IF([test $HAVE_PYTHON = no])
2230ovn_start
2231
2232# Configure the Northbound database
2233ovn-nbctl ls-add lsw0
2234
2235ovn-nbctl lsp-add lsw0 lp1
2236ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2237
2238ovn-nbctl lsp-add lsw0 lp2
2239ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2240
2241ovn-nbctl lsp-add lsw0 lp-gw
2242ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 2243ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
2244ovn-nbctl lsp-set-addresses lp-gw unknown
2245
2246net_add n1 # Network to connect hv1, hv2, and gw
2247net_add n2 # Network to connect gw and hv3
2248
2249# Create hypervisor hv1 connected to n1
2250sim_add hv1
2251as hv1
2252ovs-vsctl add-br br-phys
2253ovn_attach n1 br-phys 192.168.0.1
2254ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
2255
2256# Create hypervisor hv2 connected to n1
2257sim_add hv2
2258as hv2
2259ovs-vsctl add-br br-phys
2260ovn_attach n1 br-phys 192.168.0.2
2261ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
2262
2263# Create hypervisor hv_gw connected to n1 and n2
2264# connect br-phys bridge to n1; connect hv-gw bridge to n2
2265sim_add hv_gw
2266as hv_gw
2267ovs-vsctl add-br br-phys
2268ovn_attach n1 br-phys 192.168.0.3
2269ovs-vsctl add-br br-phys2
2270net_attach n2 br-phys2
2271ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2272
184bc3ca
RB
2273# Add hv3 on the other side of the GW
2274sim_add hv3
2275as hv3
2276ovs-vsctl add-br br-phys
2277net_attach n2 br-phys
2278ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
2279
2280
2281# Pre-populate the hypervisors' ARP tables so that we don't lose any
2282# packets for ARP resolution (native tunneling doesn't queue packets
2283# for ARP resolution).
74868f2c 2284OVN_POPULATE_ARP
184bc3ca
RB
2285
2286# Allow some time for ovn-northd and ovn-controller to catch up.
2287# XXX This should be more systematic.
2288sleep 1
2289
2290# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2291#
2292# This shell function causes a packet to be received on INPORT. The packet's
2293# content has Ethernet destination DST and source SRC (each exactly 12 hex
2294# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2295# more) list the VIFs on which the packet should be received. INPORT and the
2296# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
2297for i in 1 2 3; do
2298 : > $i.expected
2299done
2300test_packet() {
2301 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2302 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2303 hv=hv$inport
2304 vif=vif$inport
2305 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2306 for outport; do
e4543cfe 2307 echo $packet >> $outport.expected
184bc3ca
RB
2308 done
2309}
2310
2311# Send packets between all pairs of source and destination ports:
2312#
2313# 1. Unicast packets are delivered to exactly one lport (except that packets
2314# destined to their input ports are dropped).
2315#
2316# 2. Broadcast and multicast are delivered to all lports except the input port.
2317#
2318# 3. The lswitch delivers packets with an unknown destination to lports with
2319# "unknown" among their MAC addresses (and port security disabled).
2320for s in 1 2 3 ; do
2321 bcast=
2322 unknown=
2323 for d in 1 2 3 ; do
2324 if test $d != $s; then unicast=$d; else unicast=; fi
2325 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2326
2327 # The vtep (vif3) is the only one configured for "unknown"
2328 if test $d != $s && test $d = 3; then
2329 unknown="$unknown $d"
2330 fi
2331 bcast="$bcast $unicast"
2332 done
2333
2334 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2335 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2336 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2337done
2338
184bc3ca
RB
2339echo "------ ovn-nbctl show ------"
2340ovn-nbctl show
2341echo "------ ovn-sbctl show ------"
2342ovn-sbctl show
2343
2344echo "------ hv1 ------"
2345as hv1 ovs-vsctl show
2346echo "------ hv1 br-int ------"
2347as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2348echo "------ hv1 br-phys ------"
2349as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2350
2351echo "------ hv2 ------"
2352as hv2 ovs-vsctl show
2353echo "------ hv2 br-int ------"
2354as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2355echo "------ hv2 br-phys ------"
2356as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2357
2358echo "------ hv_gw ------"
2359as hv_gw ovs-vsctl show
2360echo "------ hv_gw br-phys ------"
2361as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2362echo "------ hv_gw br-phys2 ------"
2363as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2364
2365echo "------ hv3 ------"
2366as hv3 ovs-vsctl show
2367echo "------ hv3 br-phys ------"
2368as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2369
2370# Now check the packets actually received against the ones expected.
2371for i in 1 2 3; do
49d7c759 2372 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2373done
2374AT_CLEANUP
2375
9975d7be
BP
2376# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2377AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2378AT_SKIP_IF([test $HAVE_PYTHON = no])
2379ovn_start
2380
2381# Logical network:
2382#
2383# Three logical switches ls1, ls2, ls3.
86e98048
BP
2384# One logical router lr0 connected to ls[123],
2385# with nine subnets, three per logical switch:
2386#
2387# lrp11 on ls1 for subnet 192.168.11.0/24
2388# lrp12 on ls1 for subnet 192.168.12.0/24
2389# lrp13 on ls1 for subnet 192.168.13.0/24
2390# ...
2391# lrp33 on ls3 for subnet 192.168.33.0/24
2392#
2393# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2394# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2395for i in 1 2 3; do
ea46a4e9 2396 ovn-nbctl ls-add ls$i
9975d7be 2397 for j in 1 2 3; do
86e98048 2398 for k in 1 2 3; do
31ed1192
JP
2399 # Add "unknown" to MAC addresses for lp?11, so packets for
2400 # MAC-IP bindings discovered via ARP later have somewhere to go.
2401 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2402
2403 ovn-nbctl \
2404 -- lsp-add ls$i lp$i$j$k \
2405 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2406 192.168.$i$j.$k" $unknown
86e98048
BP
2407 done
2408 done
2409done
2410
fa2a27b2 2411ovn-nbctl lr-add lr0
86e98048
BP
2412for i in 1 2 3; do
2413 for j in 1 2 3; do
bf44c2cd 2414 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2415 ovn-nbctl \
31ed1192 2416 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2417 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2418 options:router-port=lrp$i$j \
86e98048 2419 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2420 done
2421done
2422
80f408f4 2423ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2424 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2425
9975d7be
BP
2426# Physical network:
2427#
2428# Three hypervisors hv[123].
86e98048
BP
2429# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2430# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2431# lp?3[123] all on hv3.
2432
9975d7be
BP
2433
2434# Given the name of a logical port, prints the name of the hypervisor
2435# on which it is located.
2436vif_to_hv() {
2437 case $1 in dnl (
86e98048
BP
2438 ?11) echo 1 ;; dnl (
2439 ?12 | ?21 | ?22) echo 2 ;; dnl (
2440 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2441 esac
2442}
2443
86e98048
BP
2444# Given the name of a logical port, prints the name of its logical router
2445# port, e.g. "vif_to_lrp 123" yields 12.
2446vif_to_lrp() {
2447 echo ${1%?}
2448}
2449
2450# Given the name of a logical port, prints the name of its logical
2451# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2452vif_to_ls() {
86e98048 2453 echo ${1%??}
e3393e3f
BP
2454}
2455
9975d7be
BP
2456net_add n1
2457for i in 1 2 3; do
2458 sim_add hv$i
2459 as hv$i
2460 ovs-vsctl add-br br-phys
2461 ovn_attach n1 br-phys 192.168.0.$i
2462done
2463for i in 1 2 3; do
2464 for j in 1 2 3; do
86e98048 2465 for k in 1 2 3; do
269ecccc
JP
2466 hv=`vif_to_hv $i$j$k`
2467 as hv$hv ovs-vsctl \
2468 -- add-port br-int vif$i$j$k \
2469 -- set Interface vif$i$j$k \
2470 external-ids:iface-id=lp$i$j$k \
2471 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2472 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2473 ofport-request=$i$j$k
86e98048 2474 done
9975d7be
BP
2475 done
2476done
2477
2478# Pre-populate the hypervisors' ARP tables so that we don't lose any
2479# packets for ARP resolution (native tunneling doesn't queue packets
2480# for ARP resolution).
74868f2c 2481OVN_POPULATE_ARP
9975d7be
BP
2482
2483# Allow some time for ovn-northd and ovn-controller to catch up.
2484# XXX This should be more systematic.
2485sleep 1
2486
e3393e3f 2487# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2488#
2489# This shell function causes a packet to be received on INPORT. The packet's
2490# content has Ethernet destination DST and source SRC (each exactly 12 hex
2491# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2492# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2493# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2494for i in 1 2 3; do
2495 for j in 1 2 3; do
86e98048
BP
2496 for k in 1 2 3; do
2497 : > $i$j$k.expected
269ecccc 2498 done
9975d7be
BP
2499 done
2500done
e3393e3f 2501test_ip() {
9975d7be
BP
2502 # This packet has bad checksums but logical L3 routing doesn't check.
2503 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2504 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2505 shift; shift; shift; shift; shift
2506 hv=hv`vif_to_hv $inport`
2507 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2508 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2509 in_ls=`vif_to_ls $inport`
2510 in_lrp=`vif_to_lrp $inport`
9975d7be 2511 for outport; do
269ecccc 2512 out_ls=`vif_to_ls $outport`
86e98048 2513 if test $in_ls = $out_ls; then
9975d7be
BP
2514 # Ports on the same logical switch receive exactly the same packet.
2515 echo $packet
2516 else
2517 # Routing decrements TTL and updates source and dest MAC
2518 # (and checksum).
269ecccc 2519 out_lrp=`vif_to_lrp $outport`
86e98048 2520 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2521 fi >> $outport.expected
9975d7be
BP
2522 done
2523}
2524
e3393e3f 2525as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2526as hv1 ovn-sbctl list port_binding
2527as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2528as hv1 ovn-sbctl dump-flows
2529as hv1 ovs-ofctl dump-flows br-int
2530
e3393e3f 2531# Send IP packets between all pairs of source and destination ports:
9975d7be 2532#
31ed1192
JP
2533# 1. Unicast IP packets are delivered to exactly one logical switch port
2534# (except that packets destined to their input ports are dropped).
9975d7be 2535#
31ed1192
JP
2536# 2. Broadcast IP packets are delivered to all logical switch ports
2537# except the input port.
86e98048
BP
2538ip_to_hex() {
2539 printf "%02x%02x%02x%02x" "$@"
2540}
9975d7be 2541for is in 1 2 3; do
269ecccc
JP
2542 for js in 1 2 3; do
2543 for ks in 1 2 3; do
2544 bcast=
2545 s=$is$js$ks
2546 smac=f00000000$s
2547 sip=`ip_to_hex 192 168 $is$js $ks`
2548 for id in 1 2 3; do
2549 for jd in 1 2 3; do
2550 for kd in 1 2 3; do
2551 d=$id$jd$kd
2552 dip=`ip_to_hex 192 168 $id$jd $kd`
2553 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2554 if test $d != $s; then unicast=$d; else unicast=; fi
2555
2556 test_ip $s $smac $dmac $sip $dip $unicast #1
2557
2558 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2559 done
2560 done
9975d7be 2561 done
269ecccc
JP
2562 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2563 done
2564 done
e3393e3f
BP
2565done
2566
0bac7164
BP
2567# 3. Send an IP packet from every logical port to every other subnet,
2568# to an IP address that does not have a static IP-MAC binding.
2569# This should generate a broadcast ARP request for the destination
2570# IP address in the destination subnet.
2571for is in 1 2 3; do
269ecccc
JP
2572 for js in 1 2 3; do
2573 for ks in 1 2 3; do
2574 s=$is$js$ks
2575 smac=f00000000$s
2576 sip=`ip_to_hex 192 168 $is$js $ks`
2577 for id in 1 2 3; do
2578 for jd in 1 2 3; do
2579 if test $is$js = $id$jd; then
2580 continue
2581 fi
2582
2583 # Send the packet.
2584 dmac=00000000ff$is$js
2585 # Calculate a 4th octet for the destination that is
2586 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2587 # that have static MAC bindings, and fits in the range
2588 # 0-255.
2589 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2590 dip=`ip_to_hex 192 168 $id$jd $o4`
2591 test_ip $s $smac $dmac $sip $dip
2592
2593 # Every LP on the destination subnet's lswitch should
2594 # receive the ARP request.
2595 lrmac=00000000ff$id$jd
2596 lrip=`ip_to_hex 192 168 $id$jd 254`
2597 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2598 for jd2 in 1 2 3; do
2599 for kd in 1 2 3; do
e4543cfe 2600 echo $arp >> $id$jd2$kd.expected
0bac7164 2601 done
269ecccc 2602 done
0bac7164 2603 done
269ecccc 2604 done
0bac7164 2605 done
269ecccc 2606 done
0bac7164
BP
2607done
2608
e3393e3f
BP
2609# test_arp INPORT SHA SPA TPA [REPLY_HA]
2610#
2611# Causes a packet to be received on INPORT. The packet is an ARP
2612# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2613# it should be the hardware address of the target to expect to receive in an
2614# ARP reply; otherwise no reply is expected.
2615#
31ed1192 2616# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2617# SHA and REPLY_HA are each 12 hex digits.
2618# SPA and TPA are each 8 hex digits.
2619test_arp() {
2620 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2621 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2622 hv=hv`vif_to_hv $inport`
2623 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2d9b49dd 2624 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
e3393e3f 2625
57d143eb 2626 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2627 # IP address is not configured to the switch patch port.
e3393e3f 2628 local i=`vif_to_ls $inport`
86e98048 2629 local j k
e3393e3f 2630 for j in 1 2 3; do
86e98048 2631 for k in 1 2 3; do
ea46a4e9 2632 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2633 # so no ARP flooding expected for it.
2634 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2635 echo $request >> $i$j$k.expected
2636 fi
2637 done
e3393e3f
BP
2638 done
2639
2640 # Expect to receive the reply, if any.
2641 if test X$reply_ha != X; then
86e98048
BP
2642 lrp=`vif_to_lrp $inport`
2643 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2644 echo $reply >> $inport.expected
2645 fi
2646}
2647
2648# Test router replies to ARP requests from all source ports:
2649#
0bac7164 2650# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2651#
0bac7164 2652# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2653# in its subnet.
2654#
0bac7164 2655# 6. Router replies to query for its MAC address from another subnet.
e3393e3f 2656#
0bac7164 2657# 7. No reply to query for IP address other than router IP.
e3393e3f 2658for i in 1 2 3; do
269ecccc
JP
2659 for j in 1 2 3; do
2660 for k in 1 2 3; do
2661 smac=f00000000$i$j$k # Source MAC
2662 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2663 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2664 rmac=00000000ff$i$j # Router MAC
2665 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2666 test_arp $i$j$k $smac $sip $rip $rmac #4
2667 test_arp $i$j$k $smac $otherip $rip $rmac #5
2668 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2669 test_arp $i$j$k $smac $sip $otherip #7
0bac7164 2670 done
269ecccc 2671 done
0bac7164
BP
2672done
2673
2674# Allow some time for packet forwarding.
2675# XXX This can be improved.
2676sleep 1
2677
2678# 8. Generate an ARP reply for each of the IP addresses ARPed for
2679# earlier as #3.
2680#
2681# Here, the $s is the VIF that originated the ARP request and $d is
2682# the VIF that sends the ARP reply, which is somewhat backward but
2683# it means that $s and $d are the same as #3.
2684: > mac_bindings.expected
2685for is in 1 2 3; do
269ecccc
JP
2686 for js in 1 2 3; do
2687 for ks in 1 2 3; do
2688 s=$is$js$ks
2689 for id in 1 2 3; do
2690 for jd in 1 2 3; do
2691 if test $is$js = $id$jd; then
2692 continue
2693 fi
2694
2695 kd=1
2696 d=$id$jd$kd
2697
2698 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2699 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2700 host_mac=8000000000$o4
2701
2702 lrmac=00000000ff$id$jd
2703 lrip=`ip_to_hex 192 168 $id$jd 254`
2704
2705 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2706
2707 echo
2708 echo
2709 echo
2710 hv=hv`vif_to_hv $d`
2711 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2712 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2713 #as $hv ovs-ofctl dump-flows br-int table=19
2714
2715 host_ip_pretty=192.168.$id$jd.$o4
2716 host_mac_pretty=80:00:00:00:00:$o4
2717 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2718 done
269ecccc 2719 done
9975d7be 2720 done
269ecccc 2721 done
9975d7be 2722done
0bac7164 2723
9975d7be
BP
2724# Allow some time for packet forwarding.
2725# XXX This can be improved.
2726sleep 1
2727
0bac7164
BP
2728# 9. Send an IP packet from every logical port to every other subnet. These
2729# are the same packets already sent as #3, but now the destinations' IP-MAC
2730# bindings have been discovered via ARP, so instead of provoking an ARP
2731# request, these packets now get routed to their destinations (which don't
2732# have static MAC bindings, so they go to the port we've designated as
2733# accepting "unknown" MACs.)
2734for is in 1 2 3; do
269ecccc
JP
2735 for js in 1 2 3; do
2736 for ks in 1 2 3; do
2737 s=$is$js$ks
2738 smac=f00000000$s
2739 sip=`ip_to_hex 192 168 $is$js $ks`
2740 for id in 1 2 3; do
2741 for jd in 1 2 3; do
2742 if test $is$js = $id$jd; then
2743 continue
2744 fi
2745
2746 # Send the packet.
2747 dmac=00000000ff$is$js
2748 # Calculate a 4th octet for the destination that is
2749 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2750 # that have static MAC bindings, and fits in the range
2751 # 0-255.
2752 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2753 dip=`ip_to_hex 192 168 $id$jd $o4`
2754 test_ip $s $smac $dmac $sip $dip
2755
2756 # Expect the packet egress.
2757 host_mac=8000000000$o4
2758 outport=${id}11
2759 out_lrp=$id$jd
e4543cfe 2760 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2761 done
269ecccc 2762 done
0bac7164 2763 done
269ecccc 2764 done
0bac7164
BP
2765done
2766
0bac7164
BP
2767ovn-sbctl -f csv -d bare --no-heading \
2768 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2769
9975d7be
BP
2770# Now check the packets actually received against the ones expected.
2771for i in 1 2 3; do
2772 for j in 1 2 3; do
86e98048 2773 for k in 1 2 3; do
abb37b6b
FF
2774 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2775 [$i$j$k.expected])
86e98048 2776 done
9975d7be
BP
2777 done
2778done
fcde56f5 2779
0bac7164
BP
2780# Check the MAC bindings against those expected.
2781AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2782])
2783
fcde56f5 2784# Gracefully terminate daemons
7a8f15e0 2785OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2786
9975d7be 2787AT_CLEANUP
685f4dfe
NS
2788
2789# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2790AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
2791AT_SKIP_IF([test $HAVE_PYTHON = no])
2792ovn_start
2793
2794# Create hypervisors hv[123].
2795# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2796# Add all of the vifs to a single logical switch lsw0.
2797# Turn off port security on vifs vif[123]1
2798# Turn on l2 port security on vifs vif[123]2
2799# Turn of l2 and l3 port security on vifs vif[123]3
2800# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 2801ovn-nbctl ls-add lsw0
685f4dfe
NS
2802net_add n1
2803for i in 1 2 3; do
2804 sim_add hv$i
2805 as hv$i
2806 ovs-vsctl add-br br-phys
2807 ovn_attach n1 br-phys 192.168.0.$i
2808
2809 for j in 1 2 3; do
2810 ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
31ed1192 2811 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 2812 if test $j = 1; then
31ed1192 2813 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 2814 elif test $j = 2; then
31ed1192
JP
2815 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2816 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
2817 else
2818 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
2819 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2820 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
685f4dfe
NS
2821 fi
2822 done
2823done
2824
685f4dfe
NS
2825# Pre-populate the hypervisors' ARP tables so that we don't lose any
2826# packets for ARP resolution (native tunneling doesn't queue packets
2827# for ARP resolution).
74868f2c 2828OVN_POPULATE_ARP
685f4dfe
NS
2829
2830# Allow some time for ovn-northd and ovn-controller to catch up.
2831# XXX This should be more systematic.
2832sleep 1
685f4dfe
NS
2833
2834# Given the name of a logical port, prints the name of the hypervisor
2835# on which it is located.
2836vif_to_hv() {
2837 echo hv${1%?}
2838}
2839
685f4dfe
NS
2840for i in 1 2 3; do
2841 for j in 1 2 3; do
2842 : > $i$j.expected
2843 done
2844done
2845
2846# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2847#
2848# This shell function causes an ip packet to be received on INPORT.
2849# The packet's content has Ethernet destination DST and source SRC
2850# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2851# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2852# be received. INPORT and the OUTPORTs are specified as logical switch
2853# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2854test_ip() {
2855 # This packet has bad checksums but logical L3 routing doesn't check.
2856 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 2857 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
2858 shift; shift; shift; shift; shift
2859 hv=`vif_to_hv $inport`
2860 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2861 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2862 for outport; do
e4543cfe 2863 echo $packet >> $outport.expected
685f4dfe
NS
2864 done
2865}
2866
2867# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2868#
2869# Causes a packet to be received on INPORT. The packet is an ARP
2870# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2871# it should be the hardware address of the target to expect to receive in an
2872# ARP reply; otherwise no reply is expected.
2873#
31ed1192 2874# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2875# SHA and REPLY_HA are each 12 hex digits.
2876# SPA and TPA are each 8 hex digits.
2877test_arp() {
2878 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2879 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2880 hv=`vif_to_hv $inport`
2881 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2882 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2883 if test $drop != 1; then
e137131a 2884 if test X$reply_ha = X; then
685f4dfe
NS
2885 # Expect to receive the broadcast ARP on the other logical switch ports
2886 # if no reply is expected.
2887 local i j
2888 for i in 1 2 3; do
2889 for j in 1 2 3; do
2890 if test $i$j != $inport; then
2891 echo $request >> $i$j.expected
2892 fi
2893 done
2894 done
2895 else
2896 # Expect to receive the reply, if any.
2897 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2898 echo $reply >> $inport.expected
2899 fi
2900 fi
2901}
2902
2903# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2904# This function is similar to test_ip() except that it sends
2905# ipv6 packet
2906test_ipv6() {
2907 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2908 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2909 shift; shift; shift; shift; shift
2910 hv=`vif_to_hv $inport`
2911 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2912 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2913 for outport; do
e4543cfe 2914 echo $packet >> $outport.expected
685f4dfe
NS
2915 done
2916}
2917
9e687b23
DL
2918# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2919# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2920# of the test packet
2921test_icmpv6() {
2922 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2923 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2924 shift; shift; shift; shift; shift; shift
2925 hv=`vif_to_hv $inport`
2926 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2927 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2928 for outport; do
e4543cfe 2929 echo $packet >> $outport.expected
9e687b23
DL
2930 done
2931}
2932
685f4dfe
NS
2933ip_to_hex() {
2934 printf "%02x%02x%02x%02x" "$@"
2935}
2936
2937# no port security
2938sip=`ip_to_hex 192 168 0 12`
2939tip=`ip_to_hex 192 168 0 13`
2940# the arp packet should be allowed even if lp[123]1 is
2941# not configured with mac f00000000023 and ip 192.168.0.12
2942for i in 1 2 3; do
2943 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2944 for j in 1 2 3; do
2945 if test $i != $j; then
2946 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2947 fi
2948 done
2949done
2950
2951# l2 port security
2952sip=`ip_to_hex 192 168 0 12`
2953tip=`ip_to_hex 192 168 0 13`
2954
2955# arp packet should be allowed since lp22 is configured with
2956# mac f00000000022
2957test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2958
2959# arp packet should not be allowed since lp32 is not configured with
2960# mac f00000000021
2961test_arp 32 f00000000021 f00000000021 $sip $tip 1
2962
2963# arp packet with sha set to f00000000021 should not be allowed
2964# for lp12
2965test_arp 12 f00000000012 f00000000021 $sip $tip 1
2966
2967# ip packets should be allowed and received since lp[123]2 do not
2968# have l3 port security
2969sip=`ip_to_hex 192 168 0 55`
2970tip=`ip_to_hex 192 168 0 66`
2971for i in 1 2 3; do
2972 for j in 1 2 3; do
2973 if test $i != $j; then
2974 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2975 fi
2976 done
2977done
2978
2979# ipv6 packets should be received by lp[123]2
2980# lp[123]1 can send ipv6 traffic as there is no port security
2981sip=fe800000000000000000000000000000
2982tip=ff020000000000000000000000000000
2983
2984for i in 1 2 3; do
2985 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2986done
2987
2988
2989# l2 and l3 port security
2990sip=`ip_to_hex 192 168 0 13`
2991tip=`ip_to_hex 192 168 0 22`
2992# arp packet should be allowed since lp13 is configured with
2993# f00000000013 and 192.168.0.13
2994test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2995
2996# the arp packet should be dropped because lp23 is not configured
2997# with mac f00000000022
2998sip=`ip_to_hex 192 168 0 13`
2999tip=`ip_to_hex 192 168 0 22`
3000test_arp 23 f00000000022 f00000000022 $sip $tip 1
3001
3002# the arp packet should be dropped because lp33 is not configured
3003# with ip 192.168.0.55
3004spa=`ip_to_hex 192 168 0 55`
3005tpa=`ip_to_hex 192 168 0 22`
3006test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3007
3008# ip packets should not be received by lp[123]3 since
3009# l3 port security is enabled
3010sip=`ip_to_hex 192 168 0 55`
3011tip=`ip_to_hex 192 168 0 66`
3012for i in 1 2 3; do
3013 for j in 1 2 3; do
3014 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3015 done
3016done
3017
3018# ipv6 packets should be dropped for lp[123]3 since
3019# it is configured with only ipv4 address
3020sip=fe800000000000000000000000000000
3021tip=ff020000000000000000000000000000
3022
3023for i in 1 2 3; do
3024 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3025done
3026
3027# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3028# lp[123]1 can send ipv6 traffic as there is no port security
3029for i in 1 2 3; do
3030 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3031done
3032
3033# lp13 has extra port security with mac f0000000113 and ipv6 addr
3034# fe80::ea2a:eaff:fe28:0012
3035
3036# ipv4 packet should be dropped for lp13 with mac f0000000113
3037sip=`ip_to_hex 192 168 0 13`
3038tip=`ip_to_hex 192 168 0 23`
3039test_ip 13 f00000000113 f00000000023 $sip $tip
3040
6d53e8a9
BP
3041# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3042# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
3043# lp11 can send ipv6 traffic as there is no port security
3044sip=ee800000000000000000000000000000
3045for i in 1 2 3; do
6d53e8a9
BP
3046 tip=fe80000000000000ea2aeafffe2800${i}3
3047 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
3048done
3049
3050
3051# ipv6 packet should not be received by lp33 with mac f0000000333
3052# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3053# configured with fe80::ea2a:eaff:fe28:0033
3054# lp11 can send ipv6 traffic as there is no port security
3055
3056sip=ee800000000000000000000000000000
3057tip=fe80000000000000ea2aeafffe280023
3058test_ipv6 11 f00000000011 f00000000333 $sip $tip
3059
6d53e8a9
BP
3060# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3061# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
3062# and should be dropped for any other ip6.src
3063# lp21 can receive ipv6 traffic as there is no port security
3064
3065tip=ee800000000000000000000000000000
3066for i in 1 2 3; do
3067 sip=fe80000000000000ea2aeafffe2800${i}3
3068 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3069
9e687b23 3070 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 3071 sip=00000000000000000000000000000000
9e687b23
DL
3072 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3073 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3074 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3075 # Traffic to non-multicast traffic should be dropped
3076 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3077 # Traffic of other ICMPv6 types should be dropped
3078 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
3079
3080 # should be dropped
3081 sip=ae80000000000000ea2aeafffe2800aa
3082 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3083done
3084
31ed1192
JP
3085# configure lsp13 to send and received IPv4 packets with an address range
3086ovn-nbctl lsp-set-port-security lp13 "f0:00:00:00:00:13 192.168.0.13 20.0.0.4/24 10.0.0.0/24"
7d9d86ad 3087
8ff5a966
NS
3088sleep 2
3089
7d9d86ad
NS
3090sip=`ip_to_hex 10 0 0 13`
3091tip=`ip_to_hex 192 168 0 22`
31ed1192 3092# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
3093test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3094
3095sip=`ip_to_hex 10 0 0 14`
3096tip=`ip_to_hex 192 168 0 23`
31ed1192 3097# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
3098# with dst ip 192.168.0.23 should be allowed
3099test_ip 13 f00000000013 f00000000023 $sip $tip 23
3100
3101sip=`ip_to_hex 192 168 0 33`
3102tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
3103# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3104# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
3105test_ip 33 f00000000033 f00000000013 $sip $tip 13
3106
3107sip=`ip_to_hex 192 168 0 33`
3108tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
3109# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3110# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
3111test_ip 33 f00000000033 f00000000013 $sip $tip 13
3112
3113sip=`ip_to_hex 192 168 0 33`
3114tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
3115# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3116# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
3117test_ip 33 f00000000033 f00000000013 $sip $tip
3118
3119sip=`ip_to_hex 192 168 0 33`
3120tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
3121# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3122# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
3123test_ip 33 f00000000033 f00000000013 $sip $tip 13
3124
3125sip=`ip_to_hex 192 168 0 33`
3126tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
3127# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3128# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
3129test_ip 33 f00000000033 f00000000013 $sip $tip
3130
3131sip=`ip_to_hex 192 168 0 33`
3132tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
3133# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3134# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 3135test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 3136
bb0c41d3
RM
3137#dump information including flow counters
3138ovn-nbctl show
3139ovn-sbctl dump-flows -- list multicast_group
3140
3141echo "------ hv1 dump ------"
3142as hv1 ovs-vsctl show
6195e2e7 3143as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3144as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3145
3146echo "------ hv2 dump ------"
3147as hv2 ovs-vsctl show
6195e2e7 3148as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3149as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3150
3151echo "------ hv3 dump ------"
3152as hv3 ovs-vsctl show
6195e2e7 3153as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3154as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3155
685f4dfe
NS
3156# Now check the packets actually received against the ones expected.
3157for i in 1 2 3; do
3158 for j in 1 2 3; do
49d7c759 3159 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
3160 done
3161done
3162
7a8f15e0 3163OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 3164
685f4dfe 3165AT_CLEANUP
509afdc3
GS
3166
3167AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
3168AT_SKIP_IF([test $HAVE_PYTHON = no])
3169ovn_start
3170
3171# Logical network:
3172# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3173# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3174# R2 has ls2 (172.16.1.0/24) connected to it.
3175
3c1ae70a
JP
3176ls1_lp1_mac="f0:00:00:01:02:03"
3177rp_ls1_mac="00:00:00:01:02:03"
3178rp_ls2_mac="00:00:00:01:02:04"
3179ls2_lp1_mac="f0:00:00:01:02:04"
3180
3181ls1_lp1_ip="192.168.1.2"
3182ls2_lp1_ip="172.16.1.2"
3183
fa2a27b2
JP
3184ovn-nbctl lr-add R1
3185ovn-nbctl lr-add R2
509afdc3 3186
ea46a4e9
JP
3187ovn-nbctl ls-add ls1
3188ovn-nbctl ls-add ls2
509afdc3
GS
3189
3190# Connect ls1 to R1
3c1ae70a 3191ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
509afdc3 3192
31ed1192 3193ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3c1ae70a 3194 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
509afdc3
GS
3195
3196# Connect ls2 to R2
3c1ae70a 3197ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
509afdc3 3198
31ed1192 3199ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3c1ae70a 3200 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
509afdc3
GS
3201
3202# Connect R1 to R2
4685e523
JP
3203ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3204ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 3205
6d9ecfa9
JP
3206ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3207ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
3208
3209# Create logical port ls1-lp1 in ls1
31ed1192 3210ovn-nbctl lsp-add ls1 ls1-lp1 \
3c1ae70a 3211-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
509afdc3
GS
3212
3213# Create logical port ls2-lp1 in ls2
31ed1192 3214ovn-nbctl lsp-add ls2 ls2-lp1 \
3c1ae70a 3215-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
509afdc3
GS
3216
3217# Create two hypervisor and create OVS ports corresponding to logical ports.
3218net_add n1
3219
3220sim_add hv1
3221as hv1
3222ovs-vsctl add-br br-phys
3223ovn_attach n1 br-phys 192.168.0.1
3224ovs-vsctl -- add-port br-int hv1-vif1 -- \
3225 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3226 options:tx_pcap=hv1/vif1-tx.pcap \
3227 options:rxq_pcap=hv1/vif1-rx.pcap \
3228 ofport-request=1
3229
3230sim_add hv2
3231as hv2
3232ovs-vsctl add-br br-phys
3233ovn_attach n1 br-phys 192.168.0.2
3234ovs-vsctl -- add-port br-int hv2-vif1 -- \
3235 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3236 options:tx_pcap=hv2/vif1-tx.pcap \
3237 options:rxq_pcap=hv2/vif1-rx.pcap \
3238 ofport-request=1
3239
3240
3241# Pre-populate the hypervisors' ARP tables so that we don't lose any
3242# packets for ARP resolution (native tunneling doesn't queue packets
3243# for ARP resolution).
74868f2c 3244OVN_POPULATE_ARP
509afdc3
GS
3245
3246# Allow some time for ovn-northd and ovn-controller to catch up.
3247# XXX This should be more systematic.
3248sleep 1
3249
509afdc3 3250# Packet to send.
3c1ae70a
JP
3251packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3252 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3253 udp && udp.src==53 && udp.dst==4369"
3254as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
509afdc3
GS
3255
3256
3257echo "---------NB dump-----"
3258ovn-nbctl show
3259echo "---------------------"
3260ovn-nbctl list logical_router
3261echo "---------------------"
3262ovn-nbctl list logical_router_port
3263echo "---------------------"
3264
3265echo "---------SB dump-----"
3266ovn-sbctl list datapath_binding
3267echo "---------------------"
3268ovn-sbctl list port_binding
3269echo "---------------------"
3270
3271echo "------ hv1 dump ----------"
8dab1022 3272as hv1 ovs-ofctl show br-int
509afdc3
GS
3273as hv1 ovs-ofctl dump-flows br-int
3274echo "------ hv2 dump ----------"
8dab1022 3275as hv2 ovs-ofctl show br-int
509afdc3
GS
3276as hv2 ovs-ofctl dump-flows br-int
3277
3278# Packet to Expect
3c1ae70a
JP
3279# The TTL should be decremented by 2.
3280packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3281 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3282 udp && udp.src==53 && udp.dst==4369"
3283echo $packet | ovstest test-ovn expr-to-packets > expected
509afdc3 3284
49d7c759 3285OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 3286
7ebfcd3d
NS
3287AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3288grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3289])
3290
3291# Disable the ls2-lp1 port.
3292ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3293
3294AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3295grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3296])
3297
3298# Generate the packet destined for ls2-lp1 and it should not be delivered.
3299# Packet to send.
3300packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3301 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3302 udp && udp.src==53 && udp.dst==4369"
3303
3304as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3305# The 2nd packet sent shound not be received.
3306OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3307
7a8f15e0 3308OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
3309
3310AT_CLEANUP
5412db30
J
3311
3312
4685e523
JP
3313AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3314AT_KEYWORDS([router-admin-state])
3315AT_SKIP_IF([test $HAVE_PYTHON = no])
3316ovn_start
3317
3318# Logical network:
3319# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3320# and 172.16.1.0/24) connected to it.
3321
3322ovn-nbctl lr-add R1
3323
3324ovn-nbctl ls-add ls1
3325
3326# Connect ls1 to R1
bf44c2cd 3327ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
3328ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3329 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3330
3331# Create logical port ls1-lp1 in ls1
3332ovn-nbctl lsp-add ls1 ls1-lp1 \
3333 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3334
3335# Create logical port ls1-lp2 in ls1
3336ovn-nbctl lsp-add ls1 ls1-lp2 \
3337 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3338
3339# Create one hypervisor and create OVS ports corresponding to logical ports.
3340net_add n1
3341
3342sim_add hv1
3343as hv1
3344ovs-vsctl add-br br-phys
3345ovn_attach n1 br-phys 192.168.0.1
3346ovs-vsctl -- add-port br-int vif1 -- \
3347 set interface vif1 external-ids:iface-id=ls1-lp1 \
3348 options:tx_pcap=hv1/vif1-tx.pcap \
3349 options:rxq_pcap=hv1/vif1-rx.pcap \
3350 ofport-request=1
3351
3352ovs-vsctl -- add-port br-int vif2 -- \
3353 set interface vif2 external-ids:iface-id=ls1-lp2 \
3354 options:tx_pcap=hv1/vif2-tx.pcap \
3355 options:rxq_pcap=hv1/vif2-rx.pcap \
3356 ofport-request=1
3357
3358
3359# Allow some time for ovn-northd and ovn-controller to catch up.
3360# XXX This should be more systematic.
3361sleep 1
3362
3363# Send ip packets between the two ports.
3364ip_to_hex() {
3365 printf "%02x%02x%02x%02x" "$@"
3366}
4685e523
JP
3367
3368# Packet to send.
3369src_mac="f00000010203"
3370dst_mac="000000010203"
3371src_ip=`ip_to_hex 192 168 1 2`
3372dst_ip=`ip_to_hex 172 16 1 2`
3373packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3374as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3375
3376
3377echo "---------NB dump-----"
3378ovn-nbctl show
3379echo "---------------------"
3380ovn-nbctl list logical_router
3381echo "---------------------"
3382ovn-nbctl list logical_router_port
3383echo "---------------------"
3384
3385echo "---------SB dump-----"
3386ovn-sbctl list datapath_binding
3387echo "---------------------"
3388ovn-sbctl list logical_flow
3389echo "---------------------"
3390
3391echo "------ hv1 dump ----------"
3392as hv1 ovs-ofctl dump-flows br-int
3393
3394
3395#Disable router R1
3396ovn-nbctl set Logical_Router R1 enabled=false
3397
3b8cd0ea
BP
3398# Allow some time for ovn-northd and ovn-controller to catch up.
3399# XXX This should be more systematic.
3400sleep 1
3401
4685e523
JP
3402echo "---------SB dump-----"
3403ovn-sbctl list datapath_binding
3404echo "---------------------"
3405ovn-sbctl list logical_flow
3406echo "---------------------"
3407
3408echo "------ hv1 dump ----------"
3409as hv1 ovs-ofctl dump-flows br-int
3410
3411as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3412
3413# Packet to Expect
3414expect_src_mac="000000010203"
3415expect_dst_mac="f00000010204"
49d7c759 3416echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3417
49d7c759 3418OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
3419
3420
3421as hv1
3422OVS_APP_EXIT_AND_WAIT([ovn-controller])
3423OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3424OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3425
3426as ovn-sb
3427OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3428
3429as ovn-nb
3430OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3431
3432as northd
3433OVS_APP_EXIT_AND_WAIT([ovn-northd])
3434
3435as main
3436OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3437OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3438
3439AT_CLEANUP
3440
3441
3442AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3443AT_KEYWORDS([router-admin-state])
3444AT_SKIP_IF([test $HAVE_PYTHON = no])
3445ovn_start
3446
3447# Logical network:
3448# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3449# and has switch ls2 (172.16.1.0/24) connected to it.
3450
fa2a27b2 3451ovn-nbctl lr-add R1
5412db30 3452
ea46a4e9
JP
3453ovn-nbctl ls-add ls1
3454ovn-nbctl ls-add ls2
5412db30
J
3455
3456# Connect ls1 to R1
bf44c2cd 3457ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3458ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3459 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3460
3461# Connect ls2 to R1
bf44c2cd 3462ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3463ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3464 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3465
3466# Create logical port ls1-lp1 in ls1
31ed1192
JP
3467ovn-nbctl lsp-add ls1 ls1-lp1 \
3468-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3469
3470# Create logical port ls2-lp1 in ls2
31ed1192
JP
3471ovn-nbctl lsp-add ls2 ls2-lp1 \
3472-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3473
3474# Create one hypervisor and create OVS ports corresponding to logical ports.
3475net_add n1
3476
3477sim_add hv1
3478as hv1
3479ovs-vsctl add-br br-phys
3480ovn_attach n1 br-phys 192.168.0.1
3481ovs-vsctl -- add-port br-int vif1 -- \
3482 set interface vif1 external-ids:iface-id=ls1-lp1 \
3483 options:tx_pcap=hv1/vif1-tx.pcap \
3484 options:rxq_pcap=hv1/vif1-rx.pcap \
3485 ofport-request=1
3486
3487ovs-vsctl -- add-port br-int vif2 -- \
3488 set interface vif2 external-ids:iface-id=ls2-lp1 \
3489 options:tx_pcap=hv1/vif2-tx.pcap \
3490 options:rxq_pcap=hv1/vif2-rx.pcap \
3491 ofport-request=1
3492
3493
3494# Allow some time for ovn-northd and ovn-controller to catch up.
3495# XXX This should be more systematic.
3496sleep 1
3497
3498# Send ip packets between the two ports.
3499ip_to_hex() {
3500 printf "%02x%02x%02x%02x" "$@"
3501}
5412db30
J
3502
3503# Packet to send.
3504src_mac="f00000010203"
3505dst_mac="000000010203"
3506src_ip=`ip_to_hex 192 168 1 2`
3507dst_ip=`ip_to_hex 172 16 1 2`
3508packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3509as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3510
3511
3512echo "---------NB dump-----"
3513ovn-nbctl show
3514echo "---------------------"
3515ovn-nbctl list logical_router
3516echo "---------------------"
3517ovn-nbctl list logical_router_port
3518echo "---------------------"
3519
3520echo "---------SB dump-----"
3521ovn-sbctl list datapath_binding
3522echo "---------------------"
3523ovn-sbctl list logical_flow
3524echo "---------------------"
3525
3526echo "------ hv1 dump ----------"
3527as hv1 ovs-ofctl dump-flows br-int
3528
5412db30
J
3529#Disable router R1
3530ovn-nbctl set Logical_Router R1 enabled=false
3531
3532echo "---------SB dump-----"
3533ovn-sbctl list datapath_binding
3534echo "---------------------"
3535ovn-sbctl list logical_flow
3536echo "---------------------"
3537
3538echo "------ hv1 dump ----------"
3539as hv1 ovs-ofctl dump-flows br-int
3540
a1361a6e
LR
3541# Allow some time for the disabling of logical router R1 to propagate.
3542# XXX This should be more systematic.
3543sleep 1
3544
5412db30
J
3545as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3546
3547# Packet to Expect
3548expect_src_mac="000000010204"
3549expect_dst_mac="f00000010204"
49d7c759 3550echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3551
49d7c759 3552OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3553
7a8f15e0 3554OVN_CLEANUP([hv1])
5412db30
J
3555
3556AT_CLEANUP
3557
28dc3fe9 3558AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3559AT_SKIP_IF([test $HAVE_PYTHON = no])
3560ovn_start
3561
3562# Logical network:
3563# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3564# network. R1 has switchess foo (192.168.1.0/24)
3565# connected to it.
3566# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3567
fa2a27b2
JP
3568ovn-nbctl lr-add R1
3569ovn-nbctl lr-add R2
28dc3fe9 3570
ea46a4e9
JP
3571ovn-nbctl ls-add foo
3572ovn-nbctl ls-add alice
3573ovn-nbctl ls-add bob
28dc3fe9
SR
3574
3575# Connect foo to R1
bf44c2cd 3576ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3577ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3578 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3579
3580# Connect alice to R2
bf44c2cd 3581ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3582ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3583 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3584
3585# Connect bob to R2
bf44c2cd 3586ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3587ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3588 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3589
3590# Connect R1 to R2
4685e523
JP
3591ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3592ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3593
3594#install static routes
e48ccf3c
JP
3595ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3596ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3597ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3598
3599# Create logical port foo1 in foo
31ed1192
JP
3600ovn-nbctl lsp-add foo foo1 \
3601-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3602
3603# Create logical port alice1 in alice
31ed1192
JP
3604ovn-nbctl lsp-add alice alice1 \
3605-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3606
3607# Create logical port bob1 in bob
31ed1192
JP
3608ovn-nbctl lsp-add bob bob1 \
3609-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3610
3611# Create two hypervisor and create OVS ports corresponding to logical ports.
3612net_add n1
3613
3614sim_add hv1
3615as hv1
3616ovs-vsctl add-br br-phys
3617ovn_attach n1 br-phys 192.168.0.1
3618ovs-vsctl -- add-port br-int hv1-vif1 -- \
3619 set interface hv1-vif1 external-ids:iface-id=foo1 \
3620 options:tx_pcap=hv1/vif1-tx.pcap \
3621 options:rxq_pcap=hv1/vif1-rx.pcap \
3622 ofport-request=1
3623
3624ovs-vsctl -- add-port br-int hv1-vif2 -- \
3625 set interface hv1-vif2 external-ids:iface-id=alice1 \
3626 options:tx_pcap=hv1/vif2-tx.pcap \
3627 options:rxq_pcap=hv1/vif2-rx.pcap \
3628 ofport-request=2
3629
3630sim_add hv2
3631as hv2
3632ovs-vsctl add-br br-phys
3633ovn_attach n1 br-phys 192.168.0.2
3634ovs-vsctl -- add-port br-int hv2-vif1 -- \
3635 set interface hv2-vif1 external-ids:iface-id=bob1 \
3636 options:tx_pcap=hv2/vif1-tx.pcap \
3637 options:rxq_pcap=hv2/vif1-rx.pcap \
3638 ofport-request=1
3639
3640
3641# Pre-populate the hypervisors' ARP tables so that we don't lose any
3642# packets for ARP resolution (native tunneling doesn't queue packets
3643# for ARP resolution).
74868f2c 3644OVN_POPULATE_ARP
28dc3fe9
SR
3645
3646# Allow some time for ovn-northd and ovn-controller to catch up.
3647# XXX This should be more systematic.
3648sleep 1
3649
3650ip_to_hex() {
3651 printf "%02x%02x%02x%02x" "$@"
3652}
28dc3fe9
SR
3653
3654# Send ip packets between foo1 and alice1
3655src_mac="f00000010203"
3656dst_mac="000000010203"
3657src_ip=`ip_to_hex 192 168 1 2`
3658dst_ip=`ip_to_hex 172 16 1 2`
3659packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3660as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3661
3662# Send ip packets between foo1 and bob1
3663src_mac="f00000010203"
3664dst_mac="000000010203"
3665src_ip=`ip_to_hex 192 168 1 2`
3666dst_ip=`ip_to_hex 172 16 2 2`
3667packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3668as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3669
3670echo "---------NB dump-----"
3671ovn-nbctl show
3672echo "---------------------"
3673ovn-nbctl list logical_router
3674echo "---------------------"
3675ovn-nbctl list logical_router_port
3676echo "---------------------"
3677
3678echo "---------SB dump-----"
3679ovn-sbctl list datapath_binding
3680echo "---------------------"
3681ovn-sbctl list port_binding
3682echo "---------------------"
3683
3684echo "------ hv1 dump ----------"
3685as hv1 ovs-ofctl dump-flows br-int
3686echo "------ hv2 dump ----------"
3687as hv2 ovs-ofctl dump-flows br-int
3688
3689# Packet to Expect at bob1
3690src_mac="000000010205"
3691dst_mac="f00000010205"
3692src_ip=`ip_to_hex 192 168 1 2`
3693dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3694echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3695
49d7c759 3696OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3697
3698# Packet to Expect at alice1
3699src_mac="000000010204"
3700dst_mac="f00000010204"
3701src_ip=`ip_to_hex 192 168 1 2`
3702dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3703echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3704
49d7c759 3705OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3706
7a8f15e0 3707OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3708
3709AT_CLEANUP
5412db30 3710
0ee8aaf6 3711AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3712AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3713ovn_start
ea46a4e9 3714ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3715net_add n1
3716sim_add hv
3717as hv
3718ovs-vsctl \
3719 -- add-br br-phys \
3720 -- add-br br-eth0
3721
3722ovn_attach n1 br-phys 192.168.0.1
3723
3724AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3725AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv/snoopvif-tx.pcap options:rxq_pcap=hv/snoopvif-rx.pcap])
3726
3727# Create a vif.
31ed1192
JP
3728AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3729AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3730AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3731
3732# Create a localnet port.
31ed1192
JP
3733AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3734AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3735AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3736AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3737
3738AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3739
3740# Wait for packet to be received.
49d7c759
BP
3741echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3742OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6 3743
5b57e12a
GL
3744# Check GARP packet when restart openflow connection.
3745as hv
3746OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3747
3748OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3749
3750as hv
3751start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3752
3753# Wait for packet to be received.
3754echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3755OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3756
0ee8aaf6
RR
3757# Delete the localnet ports.
3758AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3759AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3760
7a8f15e0 3761OVN_CLEANUP([hv])
0ee8aaf6
RR
3762
3763AT_CLEANUP
75cf9d2b
GS
3764
3765AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
3766AT_SKIP_IF([test $HAVE_PYTHON = no])
3767ovn_start
3768
3769# Logical network:
3770# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3771# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3772# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3773# connected to it.
3774
fa2a27b2
JP
3775ovn-nbctl lr-add R1
3776ovn-nbctl lr-add R2
3777ovn-nbctl lr-add R3
75cf9d2b 3778
ea46a4e9
JP
3779ovn-nbctl ls-add foo
3780ovn-nbctl ls-add alice
3781ovn-nbctl ls-add bob
3782ovn-nbctl ls-add join
75cf9d2b
GS
3783
3784# Connect foo to R1
31114af7 3785ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3786ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3787 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
3788
3789# Connect alice to R2
31114af7 3790ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3791ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3792 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
3793
3794# Connect bob to R3
31114af7 3795ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 3796ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 3797 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
3798
3799# Connect R1 to join
31114af7 3800ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3801ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3802 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
3803
3804# Connect R2 to join
31114af7 3805ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3806ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3807 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
3808
3809# Connect R3 to join
31114af7 3810ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 3811ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 3812 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
3813
3814#install static routes
e48ccf3c
JP
3815ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3816ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 3817
e48ccf3c
JP
3818ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3819ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 3820
e48ccf3c
JP
3821ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3822ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
3823
3824# Create logical port foo1 in foo
31ed1192
JP
3825ovn-nbctl lsp-add foo foo1 \
3826-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
3827
3828# Create logical port alice1 in alice
31ed1192
JP
3829ovn-nbctl lsp-add alice alice1 \
3830-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
3831
3832# Create logical port bob1 in bob
31ed1192
JP
3833ovn-nbctl lsp-add bob bob1 \
3834-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
3835
3836# Create two hypervisor and create OVS ports corresponding to logical ports.
3837net_add n1
3838
3839sim_add hv1
3840as hv1
3841ovs-vsctl add-br br-phys
3842ovn_attach n1 br-phys 192.168.0.1
3843ovs-vsctl -- add-port br-int hv1-vif1 -- \
3844 set interface hv1-vif1 external-ids:iface-id=foo1 \
3845 options:tx_pcap=hv1/vif1-tx.pcap \
3846 options:rxq_pcap=hv1/vif1-rx.pcap \
3847 ofport-request=1
3848
3849ovs-vsctl -- add-port br-int hv1-vif2 -- \
3850 set interface hv1-vif2 external-ids:iface-id=alice1 \
3851 options:tx_pcap=hv1/vif2-tx.pcap \
3852 options:rxq_pcap=hv1/vif2-rx.pcap \
3853 ofport-request=2
3854
3855sim_add hv2
3856as hv2
3857ovs-vsctl add-br br-phys
3858ovn_attach n1 br-phys 192.168.0.2
3859ovs-vsctl -- add-port br-int hv2-vif1 -- \
3860 set interface hv2-vif1 external-ids:iface-id=bob1 \
3861 options:tx_pcap=hv2/vif1-tx.pcap \
3862 options:rxq_pcap=hv2/vif1-rx.pcap \
3863 ofport-request=1
3864
3865
3866# Pre-populate the hypervisors' ARP tables so that we don't lose any
3867# packets for ARP resolution (native tunneling doesn't queue packets
3868# for ARP resolution).
74868f2c 3869OVN_POPULATE_ARP
75cf9d2b
GS
3870
3871# Allow some time for ovn-northd and ovn-controller to catch up.
3872# XXX This should be more systematic.
3873sleep 1
3874
3875ip_to_hex() {
3876 printf "%02x%02x%02x%02x" "$@"
3877}
75cf9d2b
GS
3878
3879# Send ip packets between foo1 and alice1
3880src_mac="f00000010203"
3881dst_mac="000001010203"
3882src_ip=`ip_to_hex 192 168 1 2`
3883dst_ip=`ip_to_hex 172 16 1 2`
3884packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3885as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3886as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3887
3888# Send ip packets between foo1 and bob1
3889src_mac="f00000010203"
3890dst_mac="000001010203"
3891src_ip=`ip_to_hex 192 168 1 2`
3892dst_ip=`ip_to_hex 10 32 1 2`
3893packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3894as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3895
3896echo "---------NB dump-----"
3897ovn-nbctl show
3898echo "---------------------"
3899ovn-nbctl list logical_router
3900echo "---------------------"
3901ovn-nbctl list logical_router_port
3902echo "---------------------"
3903
3904echo "---------SB dump-----"
3905ovn-sbctl list datapath_binding
3906echo "---------------------"
3907ovn-sbctl list port_binding
3908echo "---------------------"
3909ovn-sbctl dump-flows
3910echo "---------------------"
3911
3912echo "------ hv1 dump ----------"
3913as hv1 ovs-ofctl show br-int
3914as hv1 ovs-ofctl dump-flows br-int
3915echo "------ hv2 dump ----------"
3916as hv2 ovs-ofctl show br-int
3917as hv2 ovs-ofctl dump-flows br-int
3918echo "----------------------------"
3919
3920# Packet to Expect at bob1
3921src_mac="000003010203"
3922dst_mac="f00000010205"
3923src_ip=`ip_to_hex 192 168 1 2`
3924dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 3925echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3926
49d7c759 3927OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
3928
3929# Packet to Expect at alice1
3930src_mac="000002010203"
3931dst_mac="f00000010204"
3932src_ip=`ip_to_hex 192 168 1 2`
3933dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3934echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3935
49d7c759 3936OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 3937
7a8f15e0 3938OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
3939
3940AT_CLEANUP
c1645003 3941
281977f7 3942AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
3943AT_SKIP_IF([test $HAVE_PYTHON = no])
3944ovn_start
3945
3946ovn-nbctl ls-add ls1
3947
3948ovn-nbctl lsp-add ls1 ls1-lp1 \
3949-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3950
3951ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3952
3953ovn-nbctl lsp-add ls1 ls1-lp2 \
3954-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3955
3956ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3957
3958ovn-nbctl ls-add ls2
3959ovn-nbctl lsp-add ls2 ls2-lp1 \
3960-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3961ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3962ovn-nbctl lsp-add ls2 ls2-lp2 \
3963-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3964ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3965
9060fc9a 3966d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
281977f7 3967options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
9060fc9a 3968\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
281977f7 3969
9060fc9a
MM
3970ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3971ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3972
3973d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
281977f7 3974options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
9060fc9a
MM
3975\"lease_time\"=\"3600\"")"
3976
3977ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
281977f7
NS
3978
3979net_add n1
3980sim_add hv1
3981
3982as hv1
3983ovs-vsctl add-br br-phys
3984ovn_attach n1 br-phys 192.168.0.1
3985ovs-vsctl -- add-port br-int hv1-vif1 -- \
3986 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3987 options:tx_pcap=hv1/vif1-tx.pcap \
3988 options:rxq_pcap=hv1/vif1-rx.pcap \
3989 ofport-request=1
3990
3991ovs-vsctl -- add-port br-int hv1-vif2 -- \
3992 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3993 options:tx_pcap=hv1/vif2-tx.pcap \
3994 options:rxq_pcap=hv1/vif2-rx.pcap \
3995 ofport-request=2
3996
3997ovs-vsctl -- add-port br-int hv1-vif3 -- \
3998 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3999 options:tx_pcap=hv1/vif3-tx.pcap \
4000 options:rxq_pcap=hv1/vif3-rx.pcap \
4001 ofport-request=3
4002
4003ovs-vsctl -- add-port br-int hv1-vif4 -- \
4004 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4005 options:tx_pcap=hv1/vif4-tx.pcap \
4006 options:rxq_pcap=hv1/vif4-rx.pcap \
4007 ofport-request=4
4008
74868f2c 4009OVN_POPULATE_ARP
281977f7
NS
4010
4011sleep 2
4012
4013as hv1 ovs-vsctl show
4014
281977f7
NS
4015# This shell function sends a DHCP request packet
4016# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
4017test_dhcp() {
213615b3
NS
4018 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
4019 shift; shift; shift; shift; shift;
4020 if test $use_ip != 0; then
4021 src_ip=$1
4022 dst_ip=$2
4023 shift; shift;
4024 else
4025 src_ip=`ip_to_hex 0 0 0 0`
4026 dst_ip=`ip_to_hex 255 255 255 255`
4027 fi
4028 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
281977f7 4029 # udp header and dhcp header
ab187e7e
BP
4030 request=${request}0044004300fc0000
4031 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 4032 # client hardware padding
ab187e7e 4033 request=${request}00000000000000000000
281977f7 4034 # server hostname
ab187e7e
BP
4035 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4036 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4037 # boot file name
ab187e7e
BP
4038 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4039 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4040 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4041 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4042 # dhcp magic cookie
ab187e7e 4043 request=${request}63825363
281977f7 4044 # dhcp message type
ab187e7e 4045 request=${request}3501${dhcp_type}ff
281977f7
NS
4046
4047 if test $offer_ip != 0; then
213615b3 4048 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
281977f7
NS
4049 # total IP length will be the IP length of the request packet
4050 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4051 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4052 udp_len=`expr $ip_len - 20`
04d60f6e
YT
4053 ip_len=$(printf "%x" $ip_len)
4054 udp_len=$(printf "%x" $udp_len)
281977f7
NS
4055 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4056 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4057 # udp header and dhcp header.
4058 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 4059 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 4060 # your ip address
ab187e7e 4061 reply=${reply}${offer_ip}
281977f7 4062 # next server ip address, relay agent ip address, client mac address
ab187e7e 4063 reply=${reply}0000000000000000${src_mac}
281977f7 4064 # client hardware padding
ab187e7e 4065 reply=${reply}00000000000000000000
281977f7 4066 # server hostname
ab187e7e
BP
4067 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4068 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4069 # boot file name
ab187e7e
BP
4070 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4071 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4072 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4073 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4074 # dhcp magic cookie
ab187e7e 4075 reply=${reply}63825363
281977f7
NS
4076 # dhcp message type
4077 local dhcp_reply_type=02
4078 if test $dhcp_type = 03; then
4079 dhcp_reply_type=05
4080 fi
ab187e7e 4081 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
4082 echo $reply >> $inport.expected
4083 else
281977f7 4084 for outport; do
e4543cfe 4085 echo $request >> $outport.expected
281977f7
NS
4086 done
4087 fi
4088 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4089}
4090
4091reset_pcap_file() {
4092 local iface=$1
4093 local pcap_file=$2
4094 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4095options:rxq_pcap=dummy-rx.pcap
4096 rm -f ${pcap_file}*.pcap
4097 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4098options:rxq_pcap=${pcap_file}-rx.pcap
4099}
4100
4101ip_to_hex() {
4102 printf "%02x%02x%02x%02x" "$@"
4103}
4104
4105AT_CAPTURE_FILE([ofctl_monitor0.log])
4106as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4107--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4108
4109echo "---------NB dump-----"
4110ovn-nbctl show
4111echo "---------------------"
4112echo "---------SB dump-----"
4113ovn-sbctl list datapath_binding
4114echo "---------------------"
4115ovn-sbctl list logical_flow
4116echo "---------------------"
4117
4118echo "---------------------"
4119ovn-sbctl dump-flows
4120echo "---------------------"
4121
4122echo "------ hv1 dump ----------"
4123as hv1 ovs-ofctl dump-flows br-int
4124
4125# Send DHCPDISCOVER.
4126offer_ip=`ip_to_hex 10 0 0 4`
4127server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4128expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4129test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4130
4131# NXT_RESUMEs should be 1.
4132OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4133
4134$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4135cat 1.expected | cut -c -48 > expout
4136AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4137# Skipping the IPv4 checksum.
4138cat 1.expected | cut -c 53- > expout
4139AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4140
4141# ovs-ofctl also resumes the packets and this causes other ports to receive
4142# the DHCP request packet. So reset the pcap files so that its easier to test.
4143reset_pcap_file hv1-vif1 hv1/vif1
4144reset_pcap_file hv1-vif2 hv1/vif2
4145rm -f 1.expected
4146rm -f 2.expected
4147
4148# Send DHCPREQUEST.
4149offer_ip=`ip_to_hex 10 0 0 6`
4150server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4151expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4152test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4153
4154# NXT_RESUMEs should be 2.
4155OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4156
4157$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4158cat 2.expected | cut -c -48 > expout
4159AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4160# Skipping the IPv4 checksum.
4161cat 2.expected | cut -c 53- > expout
4162AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4163
4164reset_pcap_file hv1-vif1 hv1/vif1
4165reset_pcap_file hv1-vif2 hv1/vif2
4166rm -f 1.expected
4167rm -f 2.expected
4168
4169# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4170# but should be resumed without the reply.
4171# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4172# one from ovn-controller and the other from "ovs-ofctl resume."
4173offer_ip=0
213615b3 4174test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
281977f7
NS
4175
4176# NXT_RESUMEs should be 3.
4177OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4178
4179# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 4180OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
4181
4182reset_pcap_file hv1-vif1 hv1/vif1
4183reset_pcap_file hv1-vif2 hv1/vif2
4184rm -f 1.expected
4185rm -f 2.expected
4186
4187# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4188# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4189
213615b3 4190test_dhcp 3 f00000000003 01 0 4 0
281977f7
NS
4191
4192# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4193# this lport.
213615b3 4194test_dhcp 4 f00000000004 01 0 3 0
281977f7
NS
4195
4196# NXT_RESUMEs should be 3.
4197OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4198
49d7c759
BP
4199OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4200OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 4201
213615b3
NS
4202# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4203offer_ip=`ip_to_hex 10 0 0 6`
4204server_ip=`ip_to_hex 10 0 0 1`
4205expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4206src_ip=$offer_ip
4207dst_ip=$server_ip
4208test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4209
4210# NXT_RESUMEs should be 4.
4211OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4212
4213$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4214cat 2.expected | cut -c -48 > expout
4215AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4216# Skipping the IPv4 checksum.
4217cat 2.expected | cut -c 53- > expout
4218AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4219
4220reset_pcap_file hv1-vif1 hv1/vif1
4221reset_pcap_file hv1-vif2 hv1/vif2
4222rm -f 1.expected
4223rm -f 2.expected
4224
4225# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4226offer_ip=`ip_to_hex 10 0 0 6`
4227server_ip=`ip_to_hex 10 0 0 1`
4228expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4229src_ip=$offer_ip
4230dst_ip=`ip_to_hex 255 255 255 255`
4231test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4232
4233# NXT_RESUMEs should be 5.
4234OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4235
4236$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4237cat 2.expected | cut -c -48 > expout
4238AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4239# Skipping the IPv4 checksum.
4240cat 2.expected | cut -c 53- > expout
4241AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4242
4243reset_pcap_file hv1-vif1 hv1/vif1
4244reset_pcap_file hv1-vif2 hv1/vif2
4245rm -f 1.expected
4246rm -f 2.expected
4247
4248# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4249# The packet should not be received by ovn-controller.
4250src_ip=`ip_to_hex 10 0 0 6`
4251dst_ip=`ip_to_hex 10 0 0 4`
4252test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4253
4254# NXT_RESUMEs should be 5.
4255OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4256
4257# vif1-tx.pcap should have received the DHCPv4 request packet
4258OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4259
281977f7 4260as hv1
33ac3c83
NS
4261OVS_APP_EXIT_AND_WAIT([ovn-controller])
4262OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4263OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4264
4265as ovn-sb
4266OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4267
4268as ovn-nb
4269OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4270
4271as northd
4272OVS_APP_EXIT_AND_WAIT([ovn-northd])
4273
4274as main
4275OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4276OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4277
4278AT_CLEANUP
4279
40df4566 4280AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
4281AT_SKIP_IF([test $HAVE_PYTHON = no])
4282ovn_start
4283
4284ovn-nbctl ls-add ls1
4285ovn-nbctl lsp-add ls1 ls1-lp1 \
4286-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4287
4288ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4289
4290ovn-nbctl lsp-add ls1 ls1-lp2 \
4291-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4292
4293ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4294
40df4566
ZKL
4295ovn-nbctl lsp-add ls1 ls1-lp3 \
4296-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4297
4298ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4299
9060fc9a
MM
4300d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4301options="\"server_id\"=\"00:00:00:10:00:01\"")"
4302
4303ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4304ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4305
4306d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4307options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
33ac3c83 4308
9060fc9a 4309ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
40df4566 4310
33ac3c83
NS
4311ovn-nbctl ls-add ls2
4312ovn-nbctl lsp-add ls2 ls2-lp1 \
4313-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4314ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4315ovn-nbctl lsp-add ls2 ls2-lp2 \
4316-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4317ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4318
4319net_add n1
4320sim_add hv1
4321
4322as hv1
4323ovs-vsctl add-br br-phys
4324ovn_attach n1 br-phys 192.168.0.1
4325ovs-vsctl -- add-port br-int hv1-vif1 -- \
4326 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4327 options:tx_pcap=hv1/vif1-tx.pcap \
4328 options:rxq_pcap=hv1/vif1-rx.pcap \
4329 ofport-request=1
4330
4331ovs-vsctl -- add-port br-int hv1-vif2 -- \
4332 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4333 options:tx_pcap=hv1/vif2-tx.pcap \
4334 options:rxq_pcap=hv1/vif2-rx.pcap \
4335 ofport-request=2
4336
4337ovs-vsctl -- add-port br-int hv1-vif3 -- \
4338 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4339 options:tx_pcap=hv1/vif3-tx.pcap \
4340 options:rxq_pcap=hv1/vif3-rx.pcap \
4341 ofport-request=3
4342
4343ovs-vsctl -- add-port br-int hv1-vif4 -- \
4344 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4345 options:tx_pcap=hv1/vif4-tx.pcap \
4346 options:rxq_pcap=hv1/vif4-rx.pcap \
4347 ofport-request=4
4348
40df4566
ZKL
4349ovs-vsctl -- add-port br-int hv1-vif5 -- \
4350 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4351 options:tx_pcap=hv1/vif5-tx.pcap \
4352 options:rxq_pcap=hv1/vif5-rx.pcap \
4353 ofport-request=5
4354
74868f2c 4355OVN_POPULATE_ARP
33ac3c83
NS
4356
4357sleep 2
4358
4359trim_zeros() {
4360 sed 's/\(00\)\{1,\}$//'
4361}
4362
4363# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4364# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4365# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4366# packet should be received twice (one from ovn-controller and the other
4367# from the "ovs-ofctl monitor br-int resume"
4368test_dhcpv6() {
4369 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4370 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4371 # dst ip ff02::1:2
ab187e7e 4372 request=${request}ff020000000000000000000000010002
33ac3c83 4373 # udp header and dhcpv6 header
ab187e7e 4374 request=${request}02220223002affff${msg_code}010203
33ac3c83 4375 # Client identifier
ab187e7e 4376 request=${request}0001000a00030001${src_mac}
33ac3c83 4377 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 4378 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
4379 shift; shift; shift; shift; shift;
4380 if test $offer_ip != 0; then
4381 local server_mac=000000100001
4382 local server_lla=fe80000000000000020000fffe100001
4383 local reply_code=07
4384 if test $msg_code = 01; then
4385 reply_code=02
4386 fi
40df4566
ZKL
4387 local msg_len=54
4388 if test $offer_ip = 1; then
4389 msg_len=28
4390 fi
4391 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4392 # udp header and dhcpv6 header
ab187e7e 4393 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4394 # Client identifier
ab187e7e 4395 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4396 # IA-NA
40df4566 4397 if test $offer_ip != 1; then
ab187e7e 4398 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4399 fi
33ac3c83 4400 # Server identifier
ab187e7e 4401 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4402 echo $reply | trim_zeros >> $inport.expected
4403 else
4404 for outport; do
4405 echo $request | trim_zeros >> $outport.expected
4406 done
4407 fi
4408
4409 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4410}
4411
4412reset_pcap_file() {
4413 local iface=$1
4414 local pcap_file=$2
4415 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4416options:rxq_pcap=dummy-rx.pcap
4417 rm -f ${pcap_file}*.pcap
4418 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4419options:rxq_pcap=${pcap_file}-rx.pcap
4420}
4421
4422AT_CAPTURE_FILE([ofctl_monitor0.log])
4423as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4424--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4425
4426echo "---------NB dump-----"
4427ovn-nbctl show
4428echo "---------------------"
4429echo "---------SB dump-----"
4430ovn-sbctl list datapath_binding
4431echo "---------------------"
4432ovn-sbctl list logical_flow
4433echo "---------------------"
4434
4435echo "---------------------"
4436ovn-sbctl dump-flows
4437echo "---------------------"
4438
4439echo "------ hv1 dump ----------"
4440as hv1 ovs-ofctl dump-flows br-int
4441
4442src_mac=f00000000001
4443src_lla=fe80000000000000f20000fffe000001
4444offer_ip=ae700000000000000000000000000004
4445test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4446
4447# NXT_RESUMEs should be 1.
4448OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4449
4450$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4451# cat 1.expected | trim_zeros > expout
4452cat 1.expected | cut -c -120 > expout
4453AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4454# Skipping the UDP checksum
4455cat 1.expected | cut -c 125- > expout
4456AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4457
4458rm 1.expected
4459
4460# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4461# without any modifications and the packet should be received by ls1-lp1.
4462# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4463# resume and the other from ovs-ofctl monitor resume.
4464
4465reset_pcap_file hv1-vif1 hv1/vif1
4466reset_pcap_file hv1-vif2 hv1/vif2
4467
4468src_mac=f00000000002
4469src_lla=fe80000000000000f20000fffe000002
4470offer_ip=ae700000000000000000000000000005
4471# Set invalid msg_type
4472
4473test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4474
4475# NXT_RESUMEs should be 2.
4476OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4477
4478# vif2-tx.pcap should not have received the DHCPv6 reply packet
4479rm 2.packets
4480$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4481AT_CHECK([cat 2.packets], [0], [])
4482
4483# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4484$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4485cat 1.expected > expout
4486AT_CHECK([cat 1.packets], [0], [expout])
4487
4488# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4489# There should be no DHCPv6 reply from ovn-controller and the request packet
4490# should be received by ls2-lp2.
4491
4492src_mac=f00000000003
4493src_lla=fe80000000000000f20000fffe000003
4494test_dhcpv6 3 $src_mac $src_lla 01 0 4
4495
4496# NXT_RESUMEs should be 2 only.
4497OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4498
4499# vif3-tx.pcap should not have received the DHCPv6 reply packet
4500$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4501AT_CHECK([cat 3.packets], [0], [])
4502
4503# vif4-tx.pcap should have received the DHCPv6 request packet
4504$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4505cat 4.expected > expout
4506AT_CHECK([cat 4.packets], [0], [expout])
4507
40df4566
ZKL
4508# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4509# The DHCPv6 reply should doesn't contian offer_ip.
4510src_mac=f00000000022
4511src_lla=fe80000000000000f20000fffe000022
4512reset_pcap_file hv1-vif5 hv1/vif5
4513test_dhcpv6 5 $src_mac $src_lla 01 1 5
4514
4515# NXT_RESUMEs should be 3.
4516OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4517
4518$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4519# Skipping the UDP checksum
4520cat 5.expected | cut -c 1-120,125- > expout
4521AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4522
33ac3c83 4523as hv1
281977f7
NS
4524OVS_APP_EXIT_AND_WAIT([ovn-controller])
4525OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4526OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4527
4528as ovn-sb
4529OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4530
4531as ovn-nb
4532OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4533
4534as northd
4535OVS_APP_EXIT_AND_WAIT([ovn-northd])
4536
4537as main
4538OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4539OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4540
4541AT_CLEANUP
4542
c1645003 4543AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4544AT_SKIP_IF([test $HAVE_PYTHON = no])
4545ovn_start
4546
4547# Logical network:
4548# Two LRs - R1 and R2 that are connected to each other via LS "join"
4549# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4550# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4551# R2 is a gateway router.
4552
4553
4554
4555# Create two hypervisor and create OVS ports corresponding to logical ports.
4556net_add n1
4557
4558sim_add hv1
4559as hv1
4560ovs-vsctl add-br br-phys
4561ovn_attach n1 br-phys 192.168.0.1
4562ovs-vsctl -- add-port br-int hv1-vif1 -- \
4563 set interface hv1-vif1 external-ids:iface-id=foo1 \
4564 options:tx_pcap=hv1/vif1-tx.pcap \
4565 options:rxq_pcap=hv1/vif1-rx.pcap \
4566 ofport-request=1
4567
4568
4569sim_add hv2
4570as hv2
4571ovs-vsctl add-br br-phys
4572ovn_attach n1 br-phys 192.168.0.2
4573ovs-vsctl -- add-port br-int hv2-vif1 -- \
4574 set interface hv2-vif1 external-ids:iface-id=alice1 \
4575 options:tx_pcap=hv2/vif1-tx.pcap \
4576 options:rxq_pcap=hv2/vif1-rx.pcap \
4577 ofport-request=1
4578
4579# Pre-populate the hypervisors' ARP tables so that we don't lose any
4580# packets for ARP resolution (native tunneling doesn't queue packets
4581# for ARP resolution).
74868f2c 4582OVN_POPULATE_ARP
c1645003
GS
4583
4584ovn-nbctl create Logical_Router name=R1
4585ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4586
ea46a4e9
JP
4587ovn-nbctl ls-add foo
4588ovn-nbctl ls-add alice
4589ovn-nbctl ls-add join
c1645003
GS
4590
4591# Connect foo to R1
31114af7 4592ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4593ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4594 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4595
4596# Connect alice to R2
31114af7 4597ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4598ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4599 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4600
4601# Connect R1 to join
31114af7 4602ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4603ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4604 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4605
4606# Connect R2 to join
31114af7 4607ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4608ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4609 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4610
4611
4612#install static routes
4613ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4614ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4615R1 static_routes @lrt
4616
4617ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4618ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4619R2 static_routes @lrt
4620
4621# Create logical port foo1 in foo
31ed1192
JP
4622ovn-nbctl lsp-add foo foo1 \
4623-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4624
4625# Create logical port alice1 in alice
31ed1192
JP
4626ovn-nbctl lsp-add alice alice1 \
4627-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4628
4629
4630# Allow some time for ovn-northd and ovn-controller to catch up.
4631# XXX This should be more systematic.
4632sleep 2
4633
4634ip_to_hex() {
4635 printf "%02x%02x%02x%02x" "$@"
4636}
c1645003
GS
4637
4638# Send ip packets between foo1 and alice1
4639src_mac="f00000010203"
4640dst_mac="000001010203"
4641src_ip=`ip_to_hex 192 168 1 2`
4642dst_ip=`ip_to_hex 172 16 1 2`
4643packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4644
4645echo "---------NB dump-----"
4646ovn-nbctl show
4647echo "---------------------"
4648ovn-nbctl list logical_router
4649echo "---------------------"
4650ovn-nbctl list logical_router_port
4651echo "---------------------"
4652
4653echo "---------SB dump-----"
4654ovn-sbctl list datapath_binding
4655echo "---------------------"
4656ovn-sbctl list port_binding
4657echo "---------------------"
4658ovn-sbctl dump-flows
4659echo "---------------------"
4660ovn-sbctl list chassis
4661ovn-sbctl list encap
4662echo "---------------------"
4663
c1645003
GS
4664# Packet to Expect at alice1
4665src_mac="000002010203"
4666dst_mac="f00000010204"
4667src_ip=`ip_to_hex 192 168 1 2`
4668dst_ip=`ip_to_hex 172 16 1 2`
4669expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4670
4671
4672as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4673as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4674
ab39371d
RM
4675echo "------ hv1 dump after packet 1 ----------"
4676as hv1 ovs-ofctl show br-int
4677as hv1 ovs-ofctl dump-flows br-int
4678echo "------ hv2 dump after packet 1 ----------"
4679as hv2 ovs-ofctl show br-int
4680as hv2 ovs-ofctl dump-flows br-int
4681echo "----------------------------"
4682
49d7c759
BP
4683echo $expected > expected
4684OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4685
34114cf8
GS
4686# Delete the router and re-create it. Things should work as before.
4687ovn-nbctl lr-del R2
4688ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4689# Connect alice to R2
4690ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4691# Connect R2 to join
4692ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4693
4694ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4695ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4696R2 static_routes @lrt
4697
4698# Wait for ovn-controller to catch up.
4699sleep 1
4700
4701# Send the packet again.
4702as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4703
4704echo "------ hv1 dump after packet 2 ----------"
4705as hv1 ovs-ofctl show br-int
4706as hv1 ovs-ofctl dump-flows br-int
4707echo "------ hv2 dump after packet 2 ----------"
4708as hv2 ovs-ofctl show br-int
4709as hv2 ovs-ofctl dump-flows br-int
4710echo "----------------------------"
4711
49d7c759
BP
4712echo $expected >> expected
4713OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4714
7a8f15e0 4715OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4716
4717AT_CLEANUP
bb3c4568
FF
4718
4719AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4720AT_KEYWORDS([router-icmp-reply])
4721AT_SKIP_IF([test $HAVE_PYTHON = no])
4722ovn_start
4723
4724# Logical network:
4725# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4726# and has switch ls2 (172.16.1.0/24) connected to it.
4727
fa2a27b2 4728ovn-nbctl lr-add R1
bb3c4568 4729
ea46a4e9
JP
4730ovn-nbctl ls-add ls1
4731ovn-nbctl ls-add ls2
bb3c4568
FF
4732
4733# Connect ls1 to R1
31114af7 4734ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4735ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4736 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4737
4738# Connect ls2 to R1
31114af7 4739ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4740ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4741 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4742
4743# Create logical port ls1-lp1 in ls1
31ed1192
JP
4744ovn-nbctl lsp-add ls1 ls1-lp1 \
4745-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4746
4747# Create logical port ls2-lp1 in ls2
31ed1192
JP
4748ovn-nbctl lsp-add ls2 ls2-lp1 \
4749-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4750
4751# Create one hypervisor and create OVS ports corresponding to logical ports.
4752net_add n1
4753
4754sim_add hv1
4755as hv1
4756ovs-vsctl add-br br-phys
4757ovn_attach n1 br-phys 192.168.0.1
4758ovs-vsctl -- add-port br-int vif1 -- \
4759 set interface vif1 external-ids:iface-id=ls1-lp1 \
4760 options:tx_pcap=hv1/vif1-tx.pcap \
4761 options:rxq_pcap=hv1/vif1-rx.pcap \
4762 ofport-request=1
4763
4764ovs-vsctl -- add-port br-int vif2 -- \
4765 set interface vif2 external-ids:iface-id=ls2-lp1 \
4766 options:tx_pcap=hv1/vif2-tx.pcap \
4767 options:rxq_pcap=hv1/vif2-rx.pcap \
4768 ofport-request=1
4769
4770
4771# Allow some time for ovn-northd and ovn-controller to catch up.
4772# XXX This should be more systematic.
4773sleep 1
4774
4775
4776ip_to_hex() {
4777 printf "%02x%02x%02x%02x" "$@"
4778}
bb3c4568
FF
4779for i in 1 2; do
4780 : > vif$i.expected
4781done
4782# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4783#
4784# Causes a packet to be received on INPORT. The packet is an ICMPv4
4785# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4786# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4787# provided, then it should be the ip and icmp checksums of the packet
4788# responded; otherwise, no reply is expected.
4789# In the absence of an ip checksum calculation helpers, this relies
4790# on the caller to provide the checksums for the ip and icmp headers.
4791# XXX This should be more systematic.
4792#
4793# INPORT is an lport number, e.g. 11 for vif11.
4794# ETH_SRC and ETH_DST are each 12 hex digits.
4795# IPV4_SRC and IPV4_DST are each 8 hex digits.
4796# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4797# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4798test_ipv4_icmp_request() {
4799 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4800 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4801 shift; shift; shift; shift; shift; shift; shift
4802 shift; shift
4803
4804 # Use ttl to exercise section 4.2.2.9 of RFC1812
4805 local ip_ttl=01
4806 local icmp_id=5fbf
4807 local icmp_seq=0001
4808 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4809 local icmp_type_code_request=0800
4810 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4811 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4812
4813 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4814 if test X$exp_icmp_chksum != X; then
4815 # Expect to receive the reply, if any. In same port where packet was sent.
4816 # Note: src and dst fields are expected to be reversed.
4817 local icmp_type_code_response=0000
4818 local reply_icmp_ttl=fe
4819 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4820 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4821 echo $reply >> vif$inport.expected
4822 fi
4823}
4824
4825# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4826rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4827rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4828l1_ip=$(ip_to_hex 192 168 1 2)
4829l2_ip=$(ip_to_hex 172 16 1 2)
4830
4831# Ping router ip address that is on same subnet as the logical port
4832test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4833test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4834
4835# Ping router ip address that is on the other side of the logical ports
4836test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4837test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4838
4839echo "---------NB dump-----"
4840ovn-nbctl show
4841echo "---------------------"
4842ovn-nbctl list logical_router
4843echo "---------------------"
4844ovn-nbctl list logical_router_port
4845echo "---------------------"
4846
4847echo "---------SB dump-----"
4848ovn-sbctl list datapath_binding
4849echo "---------------------"
4850ovn-sbctl list logical_flow
4851echo "---------------------"
4852
4853echo "------ hv1 dump ----------"
4854as hv1 ovs-ofctl dump-flows br-int
4855
4856# Now check the packets actually received against the ones expected.
4857for inport in 1 2; do
49d7c759 4858 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4859done
4860
7a8f15e0 4861OVN_CLEANUP([hv1])
bb3c4568
FF
4862
4863AT_CLEANUP
94f79fcb
RB
4864
4865# 1 hypervisor, 1 port
4866# make sure that the port state is properly set to up and back down
4867# when created and deleted.
4868AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
4869ovn_start
4870
4871ovn-nbctl ls-add ls1
4872ovn-nbctl lsp-add ls1 lp1
4873ovn-nbctl lsp-set-addresses lp1 unknown
4874
4875net_add n1
4876sim_add hv1
4877as hv1 ovs-vsctl add-br br-phys
4878as hv1 ovn_attach n1 br-phys 192.168.0.1
4879
4880as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4881OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4882
4883as hv1 ovs-vsctl del-port br-int vif1
4884OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4885
7a8f15e0 4886OVN_CLEANUP([hv1])
94f79fcb 4887
94f79fcb 4888AT_CLEANUP
e75451fe 4889
ccc6e1db
FF
4890# 1 hypervisor, 1 port
4891# make sure that the OF rules created to support a datapath are added/cleared
4892# when logical switch is created and removed.
4893AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 4894AT_KEYWORDS([cleanup])
ccc6e1db
FF
4895ovn_start
4896
4897net_add n1
4898sim_add hv1
4899as hv1 ovs-vsctl add-br br-phys
4900as hv1 ovn_attach n1 br-phys 192.168.0.1
4901
4902# This shell function checks if OF rules in br-int have clauses
4903# related to OVN datapaths. The caller determines if it should find
4904# a match in the output, or not.
4905#
4906# EXPECT_DATAPATH param determines whether flows that refer to
4907# datapath to should be present or not. 0 means
4908# they should not be.
4909# STAGE_INFO param is a simple string to help identify the stage
4910# in the test when this function was invoked.
4911test_datapath_in_of_rules() {
4912 local expect_datapath=$1 stage_info=$2
4913 echo "------ ovn-nbctl show ${stage_info} ------"
4914 ovn-nbctl show
4915 echo "------ ovn-sbctl show ${stage_info} ------"
4916 ovn-sbctl show
4917 echo "------ OF rules ${stage_info} ------"
4918 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4919 # if there is a datapath mentioned in the output, check for the
4920 # magic keyword that represents one, based on the exit status of
4921 # a quiet grep
4922 if test $expect_datapath != 0; then
4618b102 4923 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 4924 else
4618b102 4925 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
4926 fi
4927}
4928
4929test_datapath_in_of_rules 0 "before ls+port create"
4930
4931ovn-nbctl ls-add ls1
4932ovn-nbctl lsp-add ls1 lp1
4933ovn-nbctl lsp-set-addresses lp1 unknown
4934
4935as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4936OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4937
4938test_datapath_in_of_rules 1 "after port is bound"
4939
4940as hv1 ovs-vsctl del-port br-int vif1
4941OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4942
4943ovn-nbctl lsp-set-addresses lp1
4944ovn-nbctl lsp-del lp1
4945ovn-nbctl ls-del ls1
4946
4947# wait for earlier changes to take effect
4948AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4949
4950# ensure OF rules are no longer present. There used to be a bug here.
4951test_datapath_in_of_rules 0 "after lport+ls removal"
4952
4953OVN_CLEANUP([hv1])
4954
4955AT_CLEANUP
4956
f8a8db39 4957AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
4958AT_SKIP_IF([test $HAVE_PYTHON = no])
4959ovn_start
4960
4961#TODO: since patch port for IPv6 logical router port is not ready not,
4962# so we are not going to test vifs on different lswitches cases. Try
4963# to update for that once relevant stuff implemented.
4964
4965# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4966# with. NS packet we test, from one VIF for another VIF, will be replied
4967# by local ovn-controller, but not by target VIF.
4968
4969# Create hypervisors and logical switch lsw0.
4970ovn-nbctl ls-add lsw0
4971net_add n1
4972sim_add hv1
4973as hv1
4974ovs-vsctl add-br br-phys
4975ovn_attach n1 br-phys 192.168.0.2
4976
4977# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4978ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
4979ovn-nbctl lsp-add lsw0 lp1
4980ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4981ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4982
4983# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4984ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv1/vif2-tx.pcap options:rxq_pcap=hv1/vif2-rx.pcap ofport-request=2
4985ovn-nbctl lsp-add lsw0 lp2
4986ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4987ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4988
4989# Add ACL rule for ICMPv6 on lsw0
4990ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4991ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4992ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4993
4994# Allow some time for ovn-northd and ovn-controller to catch up.
4995# XXX This should be more systematic.
4996sleep 1
4997
4998# Given the name of a logical port, prints the name of the hypervisor
4999# on which it is located.
5000vif_to_hv() {
5001 echo hv1${1%?}
5002}
e75451fe
ZKL
5003for i in 1 2; do
5004 : > $i.expected
5005done
5006
5007# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5008# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5009# vif2 will not receive NS packet, since ovn-controller will reply for it.
5010ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5011na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5012
5013as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 5014echo $na_packet >> 1.expected
e75451fe 5015
e75451fe
ZKL
5016echo "------ hv1 dump ------"
5017as hv1 ovs-vsctl show
5018as hv1 ovs-ofctl -O OpenFlow13 show br-int
5019as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5020
5021for i in 1 2; do
49d7c759 5022 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
5023done
5024
7a8f15e0 5025OVN_CLEANUP([hv1])
e75451fe
ZKL
5026
5027AT_CLEANUP
7417d147
RM
5028
5029AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
5030ovn_start
5031
5032net_add n1
5033
5034sim_add hv1
5035as hv1
5036ovs-vsctl add-br br-phys
5037ovn_attach n1 br-phys 192.168.0.1
5038
5039row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5040ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5041ovn-nbctl destroy Address_Set $row
5042
5043sleep 1
5044
5045# A bug previously existed in the address set support code
5046# that caused ovn-controller to crash after an address set
5047# was updated and then removed. This test case ensures
5048# that ovn-controller is at least still running after
5049# creating, updating, and deleting an address set.
5050AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5051
5052OVN_CLEANUP([hv1])
5053
5054AT_CLEANUP
8639f9be
ND
5055
5056AT_SETUP([ovn -- ipam])
8639f9be
ND
5057AT_SKIP_IF([test $HAVE_PYTHON = no])
5058ovn_start
5059
5060# Add a port to a switch that does not have a subnet set, then set the
5061# subnet which should result in an address being allocated for the port.
5062ovn-nbctl ls-add sw0
5063ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 5064ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
5065AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5066 ["0a:00:00:00:00:01 192.168.1.2"
5067])
5068
5069# Add 9 more ports to sw0, addresses should all be unique.
5070for n in `seq 1 9`; do
11547f85 5071 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5072done
5073AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5074 ["0a:00:00:00:00:02 192.168.1.3"
5075])
5076AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5077 ["0a:00:00:00:00:03 192.168.1.4"
5078])
5079AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5080 ["0a:00:00:00:00:04 192.168.1.5"
5081])
5082AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5083 ["0a:00:00:00:00:05 192.168.1.6"
5084])
5085AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5086 ["0a:00:00:00:00:06 192.168.1.7"
5087])
5088AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5089 ["0a:00:00:00:00:07 192.168.1.8"
5090])
5091AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5092 ["0a:00:00:00:00:08 192.168.1.9"
5093])
5094AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5095 ["0a:00:00:00:00:09 192.168.1.10"
5096])
5097AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5098 ["0a:00:00:00:00:0a 192.168.1.11"
5099])
5100
5101# Trying similar tests with a second switch. MAC addresses should be unique
5102# across both switches but IP's only need to be unique within the same switch.
5103ovn-nbctl ls-add sw1
5104ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 5105ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
5106AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
5107 ["0a:00:00:00:00:0b 192.168.1.2"
5108])
5109
5110for n in `seq 11 19`; do
11547f85 5111 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5112done
5113AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5114 ["0a:00:00:00:00:0c 192.168.1.3"
5115])
5116AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5117 ["0a:00:00:00:00:0d 192.168.1.4"
5118])
5119AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5120 ["0a:00:00:00:00:0e 192.168.1.5"
5121])
5122AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5123 ["0a:00:00:00:00:0f 192.168.1.6"
5124])
5125AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5126 ["0a:00:00:00:00:10 192.168.1.7"
5127])
5128AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5129 ["0a:00:00:00:00:11 192.168.1.8"
5130])
5131AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5132 ["0a:00:00:00:00:12 192.168.1.9"
5133])
5134AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5135 ["0a:00:00:00:00:13 192.168.1.10"
5136])
5137AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5138 ["0a:00:00:00:00:14 192.168.1.11"
5139])
5140
5141# Change a port's address to test for multiple ip's for a single address entry
5142# and addresses set by the user.
5143ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
11547f85 5144ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
5145AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5146 ["0a:00:00:00:00:16 192.168.1.13"
5147])
5148
5149# Test for logical router port address management.
5150ovn-nbctl create Logical_Router name=R1
5151ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5152network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5153-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5154-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 5155ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
5156AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5157 ["0a:00:00:00:00:18 192.168.1.15"
5158])
5159
5160# Test for address reuse after logical port is deleted.
5161ovn-nbctl lsp-del p0
11547f85 5162ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
5163AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5164 ["0a:00:00:00:00:19 192.168.1.2"
5165])
5166
5167# Test for multiple addresses to one logical port.
5168ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5169"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 5170ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
5171AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5172 ["0a:00:00:00:00:1c 192.168.1.16"
5173])
5174
5175# Test for exhausting subnet address space.
5176ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 5177ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
5178AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5179 ["0a:00:00:00:00:1d 172.16.1.2"
5180])
5181
11547f85 5182ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 5183AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
7cc0741e 5184 ["0a:00:00:00:00:1e"
8639f9be
ND
5185])
5186
5187# Test that address management does not add duplicate MAC for lsp/lrp peers.
5188ovn-nbctl create Logical_Router name=R2
5189ovn-nbctl ls-add sw3
5190ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
7cc0741e 5191"0a:00:00:00:00:1f"
8639f9be
ND
5192ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5193network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5194-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5195-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 5196ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
5197AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5198 ["0a:00:00:00:00:20 192.168.1.17"
5199])
5200
6374d518
LR
5201# Test static MAC address with dynamically allocated IP
5202ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5203"fe:dc:ba:98:76:54 dynamic"
5204AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5205 ["fe:dc:ba:98:76:54 192.168.1.18"
5206])
5207
6c4f7a8a
NS
5208# Update the static MAC address with dynamically allocated IP and check
5209# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5210ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5211ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5212
5213AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5214 ["fe:dc:ba:98:76:55 192.168.1.18"
5215])
5216
5217ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5218AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5219 ["fe:dc:ba:98:76:55 192.168.1.18"
5220])
5221
5222ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5223AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5224 ["fe:dc:ba:98:76:56 192.168.1.18"
5225])
5226
161ea2c8
NS
5227
5228# Test the exclude_ips from the IPAM list
5229ovn-nbctl --wait=sb set logical_switch sw0 \
5230other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5231
5232ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5233"dynamic"
5234# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5235AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5236 ["0a:00:00:00:00:21 192.168.1.20"
5237])
5238
5239ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5240"dynamic"
5241# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5242AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5243 ["0a:00:00:00:00:22 192.168.1.22"
5244])
5245
5246ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5247"dynamic"
5248# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5249AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5250 ["0a:00:00:00:00:23 192.168.1.51"
5251])
5252
5253# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5254ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5255ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5256"dynamic"
5257AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5258 ["0a:00:00:00:00:24 192.168.1.19"
5259])
5260
5261# Set invalid data in exclude_ips list. It should be ignored.
5262ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5263ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5264"dynamic"
5265# 192.168.1.21 should be assigned as that's the next free one.
5266AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5267 ["0a:00:00:00:00:25 192.168.1.21"
5268])
5269
5270# Clear the dynamic addresses assignment request.
5271ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5272AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5273 [[[]]
5274])
5275
7cc0741e
NS
5276# Set IPv6 prefix
5277ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5278ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5279"dynamic"
5280
5281# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5282# - aef0::800:ff:fe00:26 (EUI64)
5283AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5284 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5285])
5286
5287ovn-nbctl --wait=sb ls-add sw4
5288ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5289ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5290"dynamic"
5291
5292AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5293 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5294])
5295
5296ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5297"f0:00:00:00:10:12 dynamic"
5298
5299AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5300 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5301])
5302
5303# Clear the other_config for sw4. No dynamic ip should be assigned.
5304ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5305ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5306"dynamic"
5307
5308AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5309 [[[]]
5310])
5311
5312# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5313ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5314-- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5315
5316# Now p40 should be assigned with dynamic addresses.
5317AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5318 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5319])
5320
5321ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5322"dynamic"
5323# p41 should not have IPv4 address (as the pool is exhausted).
5324AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5325 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5326])
5327
8639f9be
ND
5328as ovn-sb
5329OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5330
5331as ovn-nb
5332OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5333
5334as northd
5335OVS_APP_EXIT_AND_WAIT([ovn-northd])
5336
5337AT_CLEANUP
5338
5339AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5340AT_SKIP_IF([test $HAVE_PYTHON = no])
5341ovn_start
5342
5343ovn-nbctl lr-add R1
5344
5345# Test for a ping using dynamically allocated addresses.
5346ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5347ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5348
5349# Connect foo to R1
5350ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5351ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5352 options:router-port=foo \
5353 -- lsp-set-addresses rp-foo router
8639f9be
ND
5354
5355# Connect alice to R1
5356ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5357ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5358 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5359
5360# Create logical port foo1 in foo
fd3b31e9 5361ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5362-- lsp-set-addresses foo1 "dynamic"
8bc2c143 5363AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:00:00:01 192.168.1.2"'], [0])
8639f9be
ND
5364
5365# Create logical port alice1 in alice
fd3b31e9 5366ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5367-- lsp-set-addresses alice1 "dynamic"
8bc2c143 5368AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
8639f9be
ND
5369
5370# Create logical port foo2 in foo
fd3b31e9 5371ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5372-- lsp-set-addresses foo2 "dynamic"
8bc2c143 5373AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
8639f9be
ND
5374
5375# Create a hypervisor and create OVS ports corresponding to logical ports.
5376net_add n1
5377
5378sim_add hv1
5379as hv1
5380ovs-vsctl add-br br-phys
5381ovn_attach n1 br-phys 192.168.0.1
5382ovs-vsctl -- add-port br-int hv1-vif1 -- \
5383 set interface hv1-vif1 external-ids:iface-id=foo1 \
5384 options:tx_pcap=hv1/vif1-tx.pcap \
5385 options:rxq_pcap=hv1/vif1-rx.pcap \
5386 ofport-request=1
5387
5388ovs-vsctl -- add-port br-int hv1-vif2 -- \
5389 set interface hv1-vif2 external-ids:iface-id=foo2 \
5390 options:tx_pcap=hv1/vif2-tx.pcap \
5391 options:rxq_pcap=hv1/vif2-rx.pcap \
5392 ofport-request=2
5393
5394ovs-vsctl -- add-port br-int hv1-vif3 -- \
5395 set interface hv1-vif3 external-ids:iface-id=alice1 \
5396 options:tx_pcap=hv1/vif3-tx.pcap \
5397 options:rxq_pcap=hv1/vif3-rx.pcap \
5398 ofport-request=3
5399
5400# Allow some time for ovn-northd and ovn-controller to catch up.
5401# XXX This should be more systematic.
5402sleep 1
5403
5404ip_to_hex() {
5405 printf "%02x%02x%02x%02x" "$@"
5406}
8639f9be
ND
5407
5408# Send ip packets between foo1 and foo2
5409src_mac="0a0000000001"
5410dst_mac="0a0000000003"
5411src_ip=`ip_to_hex 192 168 1 2`
5412dst_ip=`ip_to_hex 192 168 1 3`
5413packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5414as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5415
5416# Send ip packets between foo1 and alice1
5417src_mac="0a0000000001"
5418dst_mac="000000010203"
5419src_ip=`ip_to_hex 192 168 1 2`
5420dst_ip=`ip_to_hex 192 168 2 2`
5421packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5422as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5423
5424echo "---------NB dump-----"
5425ovn-nbctl show
5426echo "---------------------"
5427ovn-nbctl list logical_router
5428echo "---------------------"
5429ovn-nbctl list logical_router_port
5430echo "---------------------"
5431
5432echo "---------SB dump-----"
5433ovn-sbctl list datapath_binding
5434echo "---------------------"
5435ovn-sbctl list port_binding
5436echo "---------------------"
5437
5438echo "------ hv1 dump ----------"
5439as hv1 ovs-ofctl dump-flows br-int
5440
5441# Packet to Expect at foo2
5442src_mac="0a0000000001"
5443dst_mac="0a0000000003"
5444src_ip=`ip_to_hex 192 168 1 2`
5445dst_ip=`ip_to_hex 192 168 1 3`
5446expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5447
e4543cfe
DDP
5448$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5449echo $expected > expout
8639f9be
ND
5450AT_CHECK([cat received1.packets], [0], [expout])
5451
5452# Packet to Expect at alice1
5453src_mac="000000010204"
5454dst_mac="0a0000000002"
5455src_ip=`ip_to_hex 192 168 1 2`
5456dst_ip=`ip_to_hex 192 168 2 2`
5457expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5458
e4543cfe
DDP
5459$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5460echo $expected > expout
8639f9be
ND
5461AT_CHECK([cat received2.packets], [0], [expout])
5462
5463OVN_CLEANUP([hv1])
5464
5465AT_CLEANUP
f5792c3f
NS
5466
5467AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5468AT_KEYWORDS([vswitchd])
f5792c3f
NS
5469AT_SKIP_IF([test $HAVE_PYTHON = no])
5470ovn_start
5471
5472ovn-nbctl ls-add ls1
5473
5474ovn-nbctl lsp-add ls1 ls1-lp1 \
5475-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5476
5477ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5478
5479net_add n1
5480sim_add hv1
5481
5482as hv1
5483ovs-vsctl add-br br-phys
5484ovn_attach n1 br-phys 192.168.0.1
5485ovs-vsctl -- add-port br-int hv1-vif1 -- \
5486 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5487 options:tx_pcap=hv1/vif1-tx.pcap \
5488 options:rxq_pcap=hv1/vif1-rx.pcap \
5489 ofport-request=1
5490
74868f2c 5491OVN_POPULATE_ARP
f5792c3f
NS
5492sleep 2
5493
5494as hv1 ovs-vsctl show
5495
5496echo "---------------------"
5497ovn-sbctl dump-flows
5498echo "---------------------"
5499
5500echo "------ hv1 dump ----------"
5501as hv1 ovs-ofctl dump-flows br-int
5502total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5503
5504echo "Total flows before vswitchd restart = " $total_flows
5505
5506# Code taken from ovs-save utility
5507save_flows () {
5508 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5509 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5510 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5511 echo "EOF" >> restore_flows.sh
5512}
5513
5514restart_vswitchd () {
5515 restore_flows=$1
5516
5517 if test $restore_flows = true; then
5518 save_flows
5519 fi
5520
5521 as hv1
5522 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5523
5524 if test $restore_flows = true; then
5525 as hv1
5526 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5527 fi
5528
5529 as hv1
5530 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5531 ovs-ofctl dump-flows br-int
5532
5533 if test $restore_flows = true; then
5534 sh ./restore_flows.sh
5535 echo "Flows after restore"
5536 as hv1
5537 ovs-ofctl dump-flows br-int
5538 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5539 flow-restore-wait="true"
5540 fi
5541}
5542
5543# Save the flows, restart vswitchd and restore the flows
5544restart_vswitchd true
5545OVS_WAIT_UNTIL([
5546 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5547 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5548 test "${total_flows}" = "${total_flows_after_restart}"
5549])
5550
5551# Restart vswitchd without restoring
5552restart_vswitchd false
5553OVS_WAIT_UNTIL([
5554 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5555 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5556 test "${total_flows}" = "${total_flows_after_restart}"
5557])
5558
5559OVN_CLEANUP([hv1])
5560AT_CLEANUP
47021598
CSV
5561
5562AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5563AT_SKIP_IF([test $HAVE_PYTHON = no])
5564ovn_start
5565
5566# Topology: Two LSs - ls1 and ls2 are connected via router r0
5567
5568# Create logical switches
5569ovn-nbctl ls-add ls1
5570ovn-nbctl ls-add ls2
5571
5572# Create router
5573ovn-nbctl create Logical_Router name=lr0
5574
5575# Add router ls1p1 port to gateway router
5576ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5577ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5578 type=router options:router-port=lrp-ls1lp1 \
5579 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5580
5581# Add router ls2p2 port to gateway router
5582ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5583ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5584 type=router options:router-port=lrp-ls2lp1 \
5585 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5586
5587# Set default gateway (nexthop) to 192.168.1.254
5588ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5589
5590# Create logical port ls1lp2 in ls1
5591ovn-nbctl lsp-add ls1 ls1lp2 \
5592-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5593
5594# Create logical port ls2lp2 in ls2
5595ovn-nbctl lsp-add ls2 ls2lp2 \
5596-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5597
5598net_add n1
5599sim_add hv1
5600as hv1
5601ovs-vsctl add-br br-phys
5602ovn_attach n1 br-phys 192.168.0.1
5603ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5604 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5605 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5606 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5607 ofport-request=1
5608ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5609 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5610 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5611 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5612 ofport-request=2
5613
5614# Allow some time for ovn-northd and ovn-controller to catch up.
5615# XXX This should be more systematic.
5616sleep 1
5617
5618echo "---------NB dump-----"
5619ovn-nbctl show
5620echo "---------------------"
5621ovn-nbctl list logical_router
5622echo "---------------------"
5623ovn-nbctl list logical_router_port
5624echo "---------------------"
5625
5626echo "---------SB dump-----"
5627ovn-sbctl list datapath_binding
5628echo "---------------------"
5629ovn-sbctl list port_binding
5630echo "---------------------"
5631ovn-sbctl dump-flows
5632echo "---------------------"
5633ovn-sbctl list chassis
5634ovn-sbctl list encap
5635echo "---------------------"
5636
5637echo "------Flows dump-----"
5638as hv1
5639ovs-ofctl dump-flows
5640echo "---------------------"
5641
5642ip_to_hex() {
5643 printf "%02x%02x%02x%02x" "$@"
5644}
5645
5646src_mac="f00000000003"
5647dst_mac="f00000000001"
5648src_ip=`ip_to_hex 192 168 0 2`
5649dst_ip=`ip_to_hex 8 8 8 8`
5650packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5651
5652# Send IP packet destined to 8.8.8.8 from lsp1lp2
5653as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5654
5655trim_zeros() {
5656 sed 's/\(00\)\{1,\}$//'
5657}
5658
5659# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5660# not 8.8.8.8
5661
5662$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5663expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5664echo $expected > expout
5665AT_CHECK([cat packets], [0], [expout])
5666cat packets
5667
5668OVN_CLEANUP([hv1])
5669
5670AT_CLEANUP
8439c2eb
CSV
5671
5672AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5673AT_SKIP_IF([test $HAVE_PYTHON = no])
5674ovn_start
5675# Create logical switch
5676ovn-nbctl ls-add ls0
5677# Create gateway router
5678ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5679# Add router port to gateway router
5680ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5681ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5682 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
5683# Add nat-address option
5684ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5685
5686net_add n1
5687sim_add hv1
5688as hv1
5689ovs-vsctl \
5690 -- add-br br-phys \
5691 -- add-br br-eth0
5692
5693ovn_attach n1 br-phys 192.168.0.1
5694
5695AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5696AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
5697
5698# Create a localnet port.
5699AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5700AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5701AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5702AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5703
5704
5705# Wait for packet to be received.
5706OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5707trim_zeros() {
5708 sed 's/\(00\)\{1,\}$//'
5709}
5710$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5711expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5712echo $expected > expout
5713AT_CHECK([sort packets], [0], [expout])
5714cat packets
5715
5716OVN_CLEANUP([hv1])
5717
5718AT_CLEANUP
6e31816f 5719
e914fb54
MS
5720AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5721AT_SKIP_IF([test $HAVE_PYTHON = no])
5722ovn_start
5723# Create logical switch
5724ovn-nbctl ls-add ls0
5725# Create gateway router
5726ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5727# Add router port to gateway router
5728ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5729ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5730 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
5731# Add nat-address option
5732ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5733# Add NAT rules
5734AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5735AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5736# Add load balancers
5737AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5738AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5739AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5740AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5741
5742net_add n1
5743sim_add hv1
5744as hv1
5745ovs-vsctl \
5746 -- add-br br-phys \
5747 -- add-br br-eth0
5748
5749ovn_attach n1 br-phys 192.168.0.1
5750
5751AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5752AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
5753
5754# Create a localnet port.
5755AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5756AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5757AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5758AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5759
5760
5761# Wait for packet to be received.
5762OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5763trim_zeros() {
5764 sed 's/\(00\)\{1,\}$//'
5765}
5766$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5767expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5768echo $expected > expout
5769expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5770echo $expected >> expout
5771expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5772echo $expected >> expout
5773AT_CHECK([sort packets], [0], [expout])
5774cat packets
5775
5776OVN_CLEANUP([hv1])
5777
5778AT_CLEANUP
5779
6e31816f 5780AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
5781ovn_start
5782net_add n1
5783sim_add hv1
5784as hv1
5785ovs-vsctl -- add-br br-phys
5786ovn_attach n1 br-phys 192.168.0.1
5787# Create logical switch ls0
5788ovn-nbctl ls-add ls0
5789# Create ports lp0, lp1 in ls0
5790ovn-nbctl lsp-add ls0 lp0
5791ovn-nbctl lsp-add ls0 lp1
5792ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5793ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5794dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5795ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5796ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5797ovn-sbctl find MAC_Binding
093aa761 5798# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5799ovn-nbctl lsp-del lp0
5800ovn-sbctl find MAC_Binding
093aa761
BP
5801OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5802# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5803ovn-nbctl ls-del ls0
5804ovn-sbctl find MAC_Binding
093aa761 5805OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
5806
5807OVN_CLEANUP([hv1])
5808
5809AT_CLEANUP
926c34fd
RM
5810
5811AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
5812AT_SKIP_IF([test $HAVE_PYTHON = no])
5813ovn_start
5814
5815# Logical network:
5816# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5817# connected to a router R1.
5818# foo has foo1 to act as a client.
5819# bar has bar1, bar2, bar3 to act as servers.
5820
5821net_add n1
5822
5823sim_add hv1
5824as hv1
5825ovs-vsctl add-br br-phys
5826ovn_attach n1 br-phys 192.168.0.1
5827for i in foo1 bar1 bar2 bar3; do
5828 ovs-vsctl -- add-port br-int $i -- \
5829 set interface $i external-ids:iface-id=$i \
5830 options:tx_pcap=hv1/$i-tx.pcap \
5831 options:rxq_pcap=hv1/$i-rx.pcap
5832done
5833
5834ovn-nbctl create Logical_Router name=R1
5835ovn-nbctl ls-add foo
5836ovn-nbctl ls-add bar
5837
5838# Connect foo to R1
5839ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5840ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5841 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5842
5843# Connect bar to R1
5844ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5845ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5846 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5847
5848# Create logical port foo1 in foo
5849ovn-nbctl lsp-add foo foo1 \
5850-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5851
5852# Create logical port bar1, bar2 and bar3 in bar
5853for i in `seq 1 3`; do
5854 ip=`expr $i + 1`
5855 ovn-nbctl lsp-add bar bar$i \
5856 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5857done
5858
5859OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5860
5861OVN_CLEANUP([hv1])
5862
5863AT_CLEANUP
b511690b
GS
5864
5865AT_SETUP([ovn -- tag allocation])
b511690b
GS
5866ovn_start
5867
5868AT_CHECK([ovn-nbctl ls-add ls0])
5869AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5870AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5871AT_CHECK([ovn-nbctl ls-add ls1])
5872
5873dnl When a tag is provided, no allocation is done
5874AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5875AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5876])
5877dnl The same 'tag' gets created in southbound database.
5878AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5879logical_port="c0"], [0], [3
5880])
5881
5882dnl Allocate tags and see it getting created in both NB and SB
5883AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5884AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5885])
5886AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5887logical_port="c1"], [0], [1
5888])
5889
5890AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5891AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5892])
5893AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5894logical_port="c2"], [0], [2
5895])
5896AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5897AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5898])
5899AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5900logical_port="c3"], [0], [4
5901])
5902
5903dnl A different parent.
5904AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5905AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5906])
5907AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5908logical_port="c4"], [0], [1
5909])
5910
5911AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5912AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5913])
5914AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5915logical_port="c5"], [0], [2
5916])
5917
5918dnl Delete a logical port and create a new one.
5919AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5920AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5921AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5922])
5923AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5924logical_port="c6"], [0], [1
5925])
5926
5927dnl Restart northd to see that the same allocation remains.
5928as northd
5929OVS_APP_EXIT_AND_WAIT([ovn-northd])
5930start_daemon ovn-northd \
5931 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5932 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5933
5934dnl Create a switch to make sure that ovn-northd has run through the main loop.
5935AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5936AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5937])
5938AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5939])
5940AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5941])
5942AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5943])
5944AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5945])
5946AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5947])
5948
5949dnl Create a switch port with a tag that has already been allocated.
5950dnl It should go through fine with a duplicate tag.
5951AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5952AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5953])
5954AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5955logical_port="c7"], [0], [2
5956])
5957AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5958])
5959
5960AT_CHECK([ovn-nbctl ls-add ls2])
5961dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5962dnl gets copied to 'tag'
5963AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5964AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5965])
5966dnl The same 'tag' gets created in southbound database.
5967AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5968logical_port="local0"], [0], [25
5969])
5970dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5971AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5972AT_CHECK([ovn-nbctl lsp-get-tag local1])
5973dnl change the tag_request.
5974AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5975AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5976])
5977
5978AT_CLEANUP
57afd0c0
RR
5979
5980AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
5981ovn_start
5982ovn-nbctl ls-add lsw0
5983net_add n1
5984for i in 1 2; do
5985 sim_add hv$i
5986 as hv$i
5987 ovs-vsctl add-br br-phys
5988 ovn_attach n1 br-phys 192.168.0.$i
5989 ovs-vsctl add-br br-eth0
5990 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5991done
5992
5993# Create a localnet port.
5994AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5995AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5996AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5997AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5998
5999
6000# Create 3 vifs.
6001AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6002AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6003AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6004AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
6005AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
6006AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6007AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6008AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6009AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6010
6011# Bind the localvif1 to hv1.
6012as hv1
6013AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6014
6015# On hv1, check that there are no flows outputting bcast to tunnel
6016OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6017
1ea9b847 6018# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 6019as hv2
1ea9b847 6020OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
6021
6022# Now bind vif2 on hv2.
6023AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6024
6025# At this point, the broadcast flow on vif2 should be deleted.
6026# because, there is now a localnet vif bound (table=32 programming logic)
6027OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6028
6029# Verify that the local net patch port exists on hv2.
6030OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6031
6032# Now bind vif3 on hv2.
6033AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6034
6035# Verify that the local net patch port still exists on hv2
6036OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6037
6038# Delete localvif2
6039AT_CHECK([ovn-nbctl lsp-del localvif2])
6040
6041# Verify that the local net patch port still exists on hv2,
6042# because, localvif3 is still bound.
6043OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6044
57afd0c0 6045OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
6046
6047AT_CLEANUP
6048
d383eed5
JP
6049
6050AT_SETUP([ovn -- ACL logging])
6051AT_KEYWORDS([ovn])
6052ovn_start
6053
6054net_add n1
6055
6056sim_add hv
6057as hv
6058ovs-vsctl add-br br-phys
6059ovn_attach n1 br-phys 192.168.0.1
6060for i in lp1 lp2; do
6061 ovs-vsctl -- add-port br-int $i -- \
6062 set interface $i external-ids:iface-id=$i \
6063 options:tx_pcap=hv/$i-tx.pcap \
6064 options:rxq_pcap=hv/$i-rx.pcap
6065done
6066
6067lp1_mac="f0:00:00:00:00:01"
6068lp1_ip="192.168.1.2"
6069
6070lp2_mac="f0:00:00:00:00:02"
6071lp2_ip="192.168.1.3"
6072
6073ovn-nbctl ls-add lsw0
6074ovn-nbctl --wait=sb lsp-add lsw0 lp1
6075ovn-nbctl --wait=sb lsp-add lsw0 lp2
6076ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6077ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6078ovn-nbctl --wait=sb sync
6079
6080ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6081ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6082
6083ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6084ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6085
6086ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6087ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6088
6089ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6090ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6091
6092ovn-sbctl dump-flows
6093
6094
6095# Send packet that should be dropped without logging.
6096packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6097 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6098 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6099as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6100
6101# Send packet that should be dropped with logging.
6102packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6103 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6104 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6105as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6106
6107# Send packet that should be allowed without logging.
6108packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6109 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6110 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6111as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6112
6113# Send packet that should be allowed with logging.
6114packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6115 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6116 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6117as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6118
6119# Send packet that should allow related flows without logging.
6120packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6121 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6122 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6123as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6124
6125# Send packet that should allow related flows with logging.
6126packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6127 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6128 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6129as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6130
df48cfc7 6131# Send packet that should be rejected without logging.
d383eed5
JP
6132packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6133 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6134 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6135as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6136
df48cfc7 6137# Send packet that should be rejected with logging.
d383eed5
JP
6138packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6139 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6140 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6141as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6142
c1f272f9
NS
6143OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6144
d383eed5
JP
6145AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6146name="drop-flow", verdict=drop, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4361,tp_dst=81,tcp_flags=syn
6147name="allow-flow", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4363,tp_dst=83,tcp_flags=syn
6148name="<unnamed>", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4365,tp_dst=85,tcp_flags=syn
6149name="reject-flow", verdict=reject, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4367,tp_dst=87,tcp_flags=syn
6150])
6151
6152OVN_CLEANUP([hv])
6153AT_CLEANUP
6154
6155
66d89287 6156AT_SETUP([ovn -- DSCP marking and meter check])
1a03fc7d
BS
6157AT_KEYWORDS([ovn])
6158ovn_start
6159
6160ovn-nbctl ls-add lsw0
6161ovn-nbctl --wait=sb lsp-add lsw0 lp1
6162ovn-nbctl --wait=sb lsp-add lsw0 lp2
e50ed58a 6163ovn-nbctl --wait=sb lsp-add lsw0 lp3
1a03fc7d
BS
6164ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6165ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
e50ed58a 6166ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
1a03fc7d
BS
6167ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6168ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6169ovn-nbctl --wait=sb sync
6170net_add n1
6171sim_add hv
6172as hv
6173ovs-vsctl add-br br-phys
6174ovn_attach n1 br-phys 192.168.0.1
6175ovs-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
6176ovs-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
6177
6178AT_CAPTURE_FILE([trace])
6179ovn_trace () {
6180 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6181}
6182
6183# Extracts nw_tos from the final flow from ofproto/trace output and prints
6184# it on stdout. Prints "none" if no nw_tos was included.
6185get_final_nw_tos() {
6186 if flow=$(grep '^Final flow:' stdout); then :; else
6187 # The output didn't have a final flow.
6188 return 99
6189 fi
6190
6191 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6192 case $tos in
6193 '') echo none ;;
5a0e4aec 6194 *) echo $tos ;;
1a03fc7d
BS
6195 esac
6196}
6197
6198# check_tos TOS
6199#
6200# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6201check_tos() {
6202 # First check with ovn-trace for logical flows.
6203 echo "checking for tos $1"
6204 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6205 echo 'output("lp2");') > expout
6206 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])
6207
6208 # Then re-check with ofproto/trace for a physical packet.
6209 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])
6210 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6211])
6212}
6213
6214# check at L2
6215AT_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");
6216])
6217AT_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])
6218AT_CHECK([get_final_nw_tos], [0], [none
6219])
6220
6221# check at L3 without dscp marking
6222check_tos 0
6223
6224# Mark DSCP with a valid value
e50ed58a 6225qos_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
6226AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6227])
1a03fc7d
BS
6228check_tos 48
6229
66d89287
GL
6230# check at hv without qos meter
6231AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6232])
6233
6234# Update the meter rate
6235ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6236
6237# check at hv with a qos meter table
6238AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6239])
6240AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6241])
6242
1a03fc7d
BS
6243# Update the DSCP marking
6244ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6245check_tos 63
6246
66d89287
GL
6247# Update the meter rate
6248ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6249
6250# check at hv with a qos meter table
6251AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6252])
6253AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6254])
6255
1a03fc7d
BS
6256ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6257check_tos 63
6258
6259# Disable DSCP marking
5ee33cbd
GL
6260ovn-nbctl --wait=hv qos-del lsw0
6261AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6262])
1a03fc7d
BS
6263check_tos 0
6264
66d89287
GL
6265# check at hv without qos meter
6266AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6267])
6268
e50ed58a
GL
6269# check meter with chassis not resident
6270ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6271AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6272])
6273
6274# check no meter table
6275AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6276])
6277AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6278])
6279
1a03fc7d 6280OVN_CLEANUP([hv])
57afd0c0 6281AT_CLEANUP
7fff4eb7
LR
6282
6283AT_SETUP([ovn -- read-only sb db:ptcp access])
6284AT_SKIP_IF([test $HAVE_PYTHON = no])
6285
6286: > .$1.db.~lock~
6287ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6288
6289# Add read-only remote to sb ovsdb-server
6290AT_CHECK(
6291 [ovsdb-tool transact ovn-sb.db \
6292 ['["OVN_Southbound",
6293 {"op": "insert",
6294 "table": "SB_Global",
6295 "row": {
6296 "connections": ["set", [["named-uuid", "xyz"]]]}},
6297 {"op": "insert",
6298 "table": "Connection",
6299 "uuid-name": "xyz",
6300 "row": {"target": "ptcp:0:127.0.0.1",
6301 "read_only": true}}]']], [0], [ignore], [ignore])
6302
6303start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6304
6305PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6306
6307# read-only accesses should succeed
6308AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6309AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6310
6311# write access should fail
6312AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6313[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6314])
6315
6316OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6317AT_CLEANUP
6318
6319AT_SETUP([ovn -- read-only sb db:pssl access])
6320AT_SKIP_IF([test $HAVE_PYTHON = no])
6321AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6322PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6323AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6324\\]"])
6325
6326: > .$1.db.~lock~
6327ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6328
6329# Add read-only remote to sb ovsdb-server
6330AT_CHECK(
6331 [ovsdb-tool transact ovn-sb.db \
6332 ['["OVN_Southbound",
6333 {"op": "insert",
6334 "table": "SB_Global",
6335 "row": {
6336 "connections": ["set", [["named-uuid", "xyz"]]]}},
6337 {"op": "insert",
6338 "table": "Connection",
6339 "uuid-name": "xyz",
6340 "row": {"target": "pssl:0:127.0.0.1",
6341 "read_only": true}}]']], [0], [ignore], [ignore])
6342
6343start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6344 --remote=db:OVN_Southbound,SB_Global,connections \
6345 --private-key="$PKIDIR/testpki-privkey2.pem" \
6346 --certificate="$PKIDIR/testpki-cert2.pem" \
6347 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6348 ovn-sb.db
6349
6350PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6351
6352# read-only accesses should succeed
6353AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6354 --private-key=$PKIDIR/testpki-privkey.pem \
6355 --certificate=$PKIDIR/testpki-cert.pem \
6356 --ca-cert=$PKIDIR/testpki-cacert.pem \
6357 list SB_Global], [0], [stdout], [ignore])
6358AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6359 --private-key=$PKIDIR/testpki-privkey.pem \
6360 --certificate=$PKIDIR/testpki-cert.pem \
6361 --ca-cert=$PKIDIR/testpki-cacert.pem \
6362 list Connection], [0], [stdout], [ignore])
6363
6364# write access should fail
6365AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6366 --private-key=$PKIDIR/testpki-privkey.pem \
6367 --certificate=$PKIDIR/testpki-cert.pem \
6368 --ca-cert=$PKIDIR/testpki-cacert.pem \
6369 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6370[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6371])
6372
6373OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6374AT_CLEANUP
6375
821302cf
LR
6376AT_SETUP([ovn -- nb connection/ssl commands])
6377AT_SKIP_IF([test $HAVE_PYTHON = no])
6378AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6379PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6380AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6381\\]"])
6382
6383: > .$1.db.~lock~
6384ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6385
6386# Start nb db server using db connection/ssl entries (unpopulated initially)
6387start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6388 --remote=db:OVN_Northbound,NB_Global,connections \
6389 --private-key=db:OVN_Northbound,SSL,private_key \
6390 --certificate=db:OVN_Northbound,SSL,certificate \
6391 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6392 ovn-nb.db
6393
6394# Populate SSL configuration entries in nb db
6395AT_CHECK(
6396 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6397 $PKIDIR/testpki-cert.pem \
6398 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6399
6400# Populate a passive SSL connection in nb db
6401AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6402
6403PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6404
6405# Verify SSL connetivity to nb db server
6406AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6407 --private-key=$PKIDIR/testpki-privkey.pem \
6408 --certificate=$PKIDIR/testpki-cert.pem \
6409 --ca-cert=$PKIDIR/testpki-cacert.pem \
6410 list NB_Global],
6411 [0], [stdout], [ignore])
6412AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6413 --private-key=$PKIDIR/testpki-privkey.pem \
6414 --certificate=$PKIDIR/testpki-cert.pem \
6415 --ca-cert=$PKIDIR/testpki-cacert.pem \
6416 list Connection],
6417 [0], [stdout], [ignore])
6418AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6419 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6420 --certificate=$PKIDIR/testpki-cert.pem \
6421 --ca-cert=$PKIDIR/testpki-cacert.pem \
6422 get-connection],
6423 [0], [stdout], [ignore])
6424
6425OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6426AT_CLEANUP
6427
6428AT_SETUP([ovn -- sb connection/ssl commands])
6429AT_SKIP_IF([test $HAVE_PYTHON = no])
6430AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6431PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6432AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6433\\]"])
6434
6435: > .$1.db.~lock~
6436ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6437
6438# Start sb db server using db connection/ssl entries (unpopulated initially)
6439start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6440 --remote=db:OVN_Southbound,SB_Global,connections \
6441 --private-key=db:OVN_Southbound,SSL,private_key \
6442 --certificate=db:OVN_Southbound,SSL,certificate \
6443 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6444 ovn-sb.db
6445
6446# Populate SSL configuration entries in sb db
6447AT_CHECK(
6448 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6449 $PKIDIR/testpki-cert.pem \
6450 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6451
6452# Populate a passive SSL connection in sb db
6453AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6454
6455PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6456
6457# Verify SSL connetivity to sb db server
6458AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6459 --private-key=$PKIDIR/testpki-privkey.pem \
6460 --certificate=$PKIDIR/testpki-cert.pem \
6461 --ca-cert=$PKIDIR/testpki-cacert.pem \
6462 list SB_Global],
6463 [0], [stdout], [ignore])
6464AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6465 --private-key=$PKIDIR/testpki-privkey.pem \
6466 --certificate=$PKIDIR/testpki-cert.pem \
6467 --ca-cert=$PKIDIR/testpki-cacert.pem \
6468 list Connection],
6469 [0], [stdout], [ignore])
6470AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6471 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
6472 --certificate=$PKIDIR/testpki-cert.pem \
6473 --ca-cert=$PKIDIR/testpki-cacert.pem \
6474 get-connection],
6475 [0], [stdout], [ignore])
6476
6477OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6478AT_CLEANUP
6479
75fd74f8
GS
6480AT_SETUP([ovn -- nested containers])
6481ovn_start
6482
6483# Physical network:
6484# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6485
6486# Logical network:
6487# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6488# and "bar" (192.168.2.0/24). They are all connected to router R1.
6489
6490ovn-nbctl lr-add R1
6491ovn-nbctl ls-add mgmt
6492ovn-nbctl ls-add foo
6493ovn-nbctl ls-add bar
6494
6495# Connect mgmt to R1
6496ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6497ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6498 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6499
6500# Connect foo to R1
6501ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6502ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6503 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6504
6505# Connect bar to R1
6506ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6507ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6508 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6509
6510# "mgmt" has VM1 and VM2 connected
6511ovn-nbctl lsp-add mgmt vm1 \
6512-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6513
6514ovn-nbctl lsp-add mgmt vm2 \
6515-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6516
6517# "foo1" and "foo2" are containers belonging to switch "foo"
6518# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6519ovn-nbctl lsp-add foo foo1 vm1 1 \
6520-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6521
6522ovn-nbctl lsp-add foo foo2 vm2 2 \
6523-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6524
6525# "bar1" and "bar2" are containers belonging to switch "bar"
6526# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6527ovn-nbctl lsp-add bar bar1 vm1 2 \
6528-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6529
6530ovn-nbctl lsp-add bar bar2 vm2 1 \
6531-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6532
6533# bar3 is a standalone VM belonging to switch "bar"
6534ovn-nbctl lsp-add bar bar3 \
6535-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6536
6537# Create two hypervisor and create OVS ports corresponding to logical ports.
6538net_add n1
6539
6540sim_add hv1
6541as hv1
6542ovs-vsctl add-br br-phys
6543ovn_attach n1 br-phys 192.168.0.1
6544ovs-vsctl -- add-port br-int vm1 -- \
6545 set interface vm1 external-ids:iface-id=vm1 \
6546 options:tx_pcap=hv1/vm1-tx.pcap \
6547 options:rxq_pcap=hv1/vm1-rx.pcap \
6548 ofport-request=1
6549
6550ovs-vsctl -- add-port br-int bar3 -- \
6551 set interface bar3 external-ids:iface-id=bar3 \
6552 options:tx_pcap=hv1/bar3-tx.pcap \
6553 options:rxq_pcap=hv1/bar3-rx.pcap \
6554 ofport-request=2
6555
6556sim_add hv2
6557as hv2
6558ovs-vsctl add-br br-phys
6559ovn_attach n1 br-phys 192.168.0.2
6560ovs-vsctl -- add-port br-int vm2 -- \
6561 set interface vm2 external-ids:iface-id=vm2 \
6562 options:tx_pcap=hv2/vm2-tx.pcap \
6563 options:rxq_pcap=hv2/vm2-rx.pcap \
6564 ofport-request=1
6565
6566# Pre-populate the hypervisors' ARP tables so that we don't lose any
6567# packets for ARP resolution (native tunneling doesn't queue packets
6568# for ARP resolution).
74868f2c 6569OVN_POPULATE_ARP
75fd74f8
GS
6570
6571# Allow some time for ovn-northd and ovn-controller to catch up.
6572# XXX This should be more systematic.
6573sleep 1
6574
6575ip_to_hex() {
6576 printf "%02x%02x%02x%02x" "$@"
6577}
6578
6579# Send ip packets between foo1 and foo2 (same switch, different HVs and
6580# different VLAN tags).
6581src_mac="f00000010205"
6582dst_mac="f00000010206"
6583src_ip=`ip_to_hex 192 168 1 2`
6584dst_ip=`ip_to_hex 192 168 1 3`
6585packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6586as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6587
6588# expected packet at foo2
6589packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6590echo $packet > expected
6591OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6592
6593# Send ip packets between foo1 and bar2 (different switch, different HV)
6594src_mac="f00000010205"
6595dst_mac="000000010203"
6596src_ip=`ip_to_hex 192 168 1 2`
6597dst_ip=`ip_to_hex 192 168 2 3`
6598packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6599as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6600
6601# expected packet at bar2
6602src_mac="000000010204"
6603dst_mac="f00000010208"
6604packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6605echo $packet >> expected
6606OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6607
6608# Send ip packets between foo1 and bar1
6609# (different switch, loopback to same vm but different tag)
6610src_mac="f00000010205"
6611dst_mac="000000010203"
6612src_ip=`ip_to_hex 192 168 1 2`
6613dst_ip=`ip_to_hex 192 168 2 2`
6614packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6615as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6616
6617# expected packet at bar1
6618src_mac="000000010204"
6619dst_mac="f00000010207"
6620packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6621echo $packet > expected1
6622OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6623
6624# Send ip packets between bar1 and bar3
6625# (same switch. But one is container and another is a standalone VM)
6626src_mac="f00000010207"
6627dst_mac="f00000010209"
6628src_ip=`ip_to_hex 192 168 2 2`
6629dst_ip=`ip_to_hex 192 168 2 3`
6630packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6631as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6632
6633# expected packet at bar3
6634packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6635echo $packet > expected
6636OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6637
6638# Send ip packets between foo1 and vm1.
6639(different switch, container to the VM hosting it.)
6640src_mac="f00000010205"
6641dst_mac="000000010203"
6642src_ip=`ip_to_hex 192 168 1 2`
6643dst_ip=`ip_to_hex 172 16 1 2`
6644packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6645as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6646
6647# expected packet at vm1
6648src_mac="000000010202"
6649dst_mac="f00000010203"
6650packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6651echo $packet >> expected1
6652OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6653
6654# Send packets from vm1 to bar1.
6655(different switch, A hosting VM to a container inside it)
6656src_mac="f00000010203"
6657dst_mac="000000010202"
6658src_ip=`ip_to_hex 172 16 1 2`
6659dst_ip=`ip_to_hex 192 168 2 2`
6660packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6661as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6662
6663# expected packet at vm1
6664src_mac="000000010204"
6665dst_mac="f00000010207"
6666packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6667echo $packet >> expected1
6668OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6669
6670OVN_CLEANUP([hv1],[hv2])
6671
6672AT_CLEANUP
440a9f4b
GS
6673
6674AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6675AT_SKIP_IF([test $HAVE_PYTHON = no])
6676ovn_start
6677
6678# Logical network:
6679# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6680# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6681# (192.168.2.0/24) connected to it.
6682#
6683# R2 and R3 are gateway routers.
6684# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6685# connected to it. Note how both alice and bob have the same subnet behind it.
6686# We are trying to simulate external network via those 2 switches. In real
6687# world the switch ports of these switches will have addresses set as "unknown"
6688# to make them learning switches. Or those switches will be "localnet" ones.
6689
6690# Create three hypervisors and create OVS ports corresponding to logical ports.
6691net_add n1
6692
6693sim_add hv1
6694as hv1
6695ovs-vsctl add-br br-phys
6696ovn_attach n1 br-phys 192.168.0.1
6697ovs-vsctl -- add-port br-int hv1-vif1 -- \
6698 set interface hv1-vif1 external-ids:iface-id=foo1 \
6699 options:tx_pcap=hv1/vif1-tx.pcap \
6700 options:rxq_pcap=hv1/vif1-rx.pcap \
6701 ofport-request=1
6702
6703ovs-vsctl -- add-port br-int hv1-vif2 -- \
6704 set interface hv1-vif2 external-ids:iface-id=bar1 \
6705 options:tx_pcap=hv1/vif2-tx.pcap \
6706 options:rxq_pcap=hv1/vif2-rx.pcap \
6707 ofport-request=2
6708
6709sim_add hv2
6710as hv2
6711ovs-vsctl add-br br-phys
6712ovn_attach n1 br-phys 192.168.0.2
6713ovs-vsctl -- add-port br-int hv2-vif1 -- \
6714 set interface hv2-vif1 external-ids:iface-id=alice1 \
6715 options:tx_pcap=hv2/vif1-tx.pcap \
6716 options:rxq_pcap=hv2/vif1-rx.pcap \
6717 ofport-request=1
6718
6719sim_add hv3
6720as hv3
6721ovs-vsctl add-br br-phys
6722ovn_attach n1 br-phys 192.168.0.3
6723ovs-vsctl -- add-port br-int hv3-vif1 -- \
6724 set interface hv3-vif1 external-ids:iface-id=bob1 \
6725 options:tx_pcap=hv3/vif1-tx.pcap \
6726 options:rxq_pcap=hv3/vif1-rx.pcap \
6727 ofport-request=1
6728
6729
6730ovn-nbctl create Logical_Router name=R1
6731ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6732ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6733
6734ovn-nbctl ls-add foo
6735ovn-nbctl ls-add bar
6736ovn-nbctl ls-add alice
6737ovn-nbctl ls-add bob
6738ovn-nbctl ls-add join
6739
6740# Connect foo to R1
6741ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6742ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6743 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6744
6745# Connect bar to R1
6746ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6747ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6748 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6749
6750# Connect alice to R2
6751ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6752ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6753 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6754
6755# Connect bob to R3
6756ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6757ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6758 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6759
6760# Connect R1 to join
6761ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6762ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6763 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6764
6765# Connect R2 to join
6766ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6767ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6768 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6769
6770# Connect R3 to join
6771ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6772ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6773 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6774
6775# Install static routes with source ip address as the policy for routing.
6776# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6777ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6778ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6779
6780# Install static routes with destination ip address as the policy for routing.
6781ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6782
6783ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6784
6785# Create logical port foo1 in foo
6786ovn-nbctl lsp-add foo foo1 \
6787-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6788
6789# Create logical port bar1 in bar
6790ovn-nbctl lsp-add bar bar1 \
6791-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6792
6793# Create logical port alice1 in alice
6794ovn-nbctl lsp-add alice alice1 \
6795-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6796
6797# Create logical port bob1 in bob
6798ovn-nbctl lsp-add bob bob1 \
6799-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6800
6801# Pre-populate the hypervisors' ARP tables so that we don't lose any
6802# packets for ARP resolution (native tunneling doesn't queue packets
6803# for ARP resolution).
74868f2c 6804OVN_POPULATE_ARP
440a9f4b
GS
6805
6806# Allow some time for ovn-northd and ovn-controller to catch up.
6807# XXX This should be more systematic.
6808sleep 1
6809
6810ip_to_hex() {
6811 printf "%02x%02x%02x%02x" "$@"
6812}
6813trim_zeros() {
6814 sed 's/\(00\)\{1,\}$//'
6815}
6816
6817# Send ip packets between foo1 and bar1
6818# (East-west traffic should flow normally)
6819src_mac="f00000010203"
6820dst_mac="000001010203"
6821src_ip=`ip_to_hex 192 168 1 2`
6822dst_ip=`ip_to_hex 192 168 2 2`
6823packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6824as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6825
6826# Send ip packets between foo1 and alice1
6827src_mac="f00000010203"
6828dst_mac="000001010203"
6829src_ip=`ip_to_hex 192 168 1 2`
6830dst_ip=`ip_to_hex 172 16 1 3`
6831packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6832as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 6833as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
6834
6835# Send ip packets between bar1 and bob1
6836src_mac="f00000010204"
6837dst_mac="000001010204"
6838src_ip=`ip_to_hex 192 168 2 2`
6839dst_ip=`ip_to_hex 172 16 1 4`
6840packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6841as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6842#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6843
6844# Packet to expect at bar1
6845src_mac="000001010204"
6846dst_mac="f00000010204"
6847src_ip=`ip_to_hex 192 168 1 2`
6848dst_ip=`ip_to_hex 192 168 2 2`
6849expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6850echo $expected > expected
6851OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6852
6853# Packet to Expect at alice1
6854src_mac="000002010203"
6855dst_mac="f00000010205"
6856src_ip=`ip_to_hex 192 168 1 2`
6857dst_ip=`ip_to_hex 172 16 1 3`
6858expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6859echo $expected > expected
6860OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6861
6862# Packet to Expect at bob1
6863src_mac="000003010203"
6864dst_mac="f00000010206"
6865src_ip=`ip_to_hex 192 168 2 2`
6866dst_ip=`ip_to_hex 172 16 1 4`
6867expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6868echo $expected > expected
6869OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6870
6871for sim in hv1 hv2 hv3; do
6872 as $sim
6873 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6874 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6875 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6876done
6877
6878as ovn-sb
6879OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6880
6881as ovn-nb
6882OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6883
6884as northd
6885OVS_APP_EXIT_AND_WAIT([ovn-northd])
6886
6887as main
6888OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6889OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6890
6891AT_CLEANUP
41a15b71 6892
302eda27
NS
6893AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6894AT_SKIP_IF([test $HAVE_PYTHON = no])
6895ovn_start
6896
6897ovn-nbctl ls-add ls1
6898
6899ovn-nbctl lsp-add ls1 ls1-lp1 \
6900-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6901
6902ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6903
6904ovn-nbctl lsp-add ls1 ls1-lp2 \
6905-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6906
6907ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6908
6909DNS1=`ovn-nbctl create DNS records={}`
6910DNS2=`ovn-nbctl create DNS records={}`
6911
6912ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6913ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6914ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6915
6916ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6917
6918net_add n1
6919sim_add hv1
6920
6921as hv1
6922ovs-vsctl add-br br-phys
6923ovn_attach n1 br-phys 192.168.0.1
6924ovs-vsctl -- add-port br-int hv1-vif1 -- \
6925 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6926 options:tx_pcap=hv1/vif1-tx.pcap \
6927 options:rxq_pcap=hv1/vif1-rx.pcap \
6928 ofport-request=1
6929
6930ovs-vsctl -- add-port br-int hv1-vif2 -- \
6931 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6932 options:tx_pcap=hv1/vif2-tx.pcap \
6933 options:rxq_pcap=hv1/vif2-rx.pcap \
6934 ofport-request=2
6935
74868f2c 6936OVN_POPULATE_ARP
302eda27
NS
6937sleep 2
6938as hv1 ovs-vsctl show
6939
6940echo "*************************"
6941ovn-sbctl list DNS
6942echo "*************************"
6943
6944ip_to_hex() {
6945 printf "%02x%02x%02x%02x" "$@"
6946}
6947
6948reset_pcap_file() {
6949 local iface=$1
6950 local pcap_file=$2
6951 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6952options:rxq_pcap=dummy-rx.pcap
6953 rm -f ${pcap_file}*.pcap
6954 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6955options:rxq_pcap=${pcap_file}-rx.pcap
6956}
6957
6958# set_dns_params host_name
6959# Sets the dns_req_data and dns_resp_data
6960set_dns_params() {
6961 local hname=$1
6962 local ttl=00000e10
6963 an_count=0001
6964 type=0001
6965 case $hname in
6966 vm1)
6967 # vm1.ovn.org
6968 query_name=03766d31036f766e036f726700
6969 # IPv4 address - 10.0.0.4
6970 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6971 ;;
6972 vm2)
6973 # vm2.ovn.org
6974 query_name=03766d32036f766e036f726700
6975 # IPv4 address - 10.0.0.6
6976 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6977 # IPv4 address - 20.0.0.4
6978 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6979 an_count=0002
6980 ;;
6981 vm3)
6982 # vm3.ovn.org
6983 query_name=03766d33036f766e036f726700
6984 # IPv4 address - 40.0.0.4
6985 expected_dns_answer=${query_name}00010001${ttl}000428000004
6986 ;;
6987 vm1_ipv6_only)
6988 # vm1.ovn.org
6989 query_name=03766d31036f766e036f726700
6990 # IPv6 address - aef0::4
6991 type=001c
6992 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6993 ;;
6994 vm1_ipv4_v6)
6995 # vm1.ovn.org
6996 query_name=03766d31036f766e036f726700
6997 type=00ff
6998 an_count=0002
6999 # IPv4 address - 10.0.0.4
7000 # IPv6 address - aef0::4
7001 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7002 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7003 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7004 ;;
7005 vm1_invalid_type)
7006 # vm1.ovn.org
7007 query_name=03766d31036f766e036f726700
7008 # IPv6 address - aef0::4
7009 type=0002
7010 ;;
7011 vm1_incomplete)
7012 # set type to none
7013 type=''
7014 esac
7015 # TTL - 3600
7016 local dns_req_header=010201200001000000000000
7017 local dns_resp_header=010281200001${an_count}00000000
7018 dns_req_data=${dns_req_header}${query_name}${type}0001
7019 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7020}
7021
7022# This shell function sends a DNS request packet
7023# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7024test_dns() {
7025 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7026 local dns_query_data=$7
7027 shift; shift; shift; shift; shift; shift; shift;
7028 # Packet size => IPv4 header (20) + UDP header (8) +
7029 # DNS data (header + query)
7030 ip_len=`expr 28 + ${#dns_query_data} / 2`
7031 udp_len=`expr $ip_len - 20`
7032 ip_len=$(printf "%x" $ip_len)
7033 udp_len=$(printf "%x" $udp_len)
7034 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7035 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7036 # dns data
7037 request=${request}${dns_query_data}
7038
7039 if test $dns_reply != 0; then
7040 local dns_reply=$1
7041 ip_len=`expr 28 + ${#dns_reply} / 2`
7042 udp_len=`expr $ip_len - 20`
7043 ip_len=$(printf "%x" $ip_len)
7044 udp_len=$(printf "%x" $udp_len)
7045 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7046 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7047 echo $reply >> $inport.expected
7048 else
7049 for outport; do
7050 echo $request >> $outport.expected
7051 done
7052 fi
7053 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7054}
7055
f8e79d82
MM
7056test_dns6() {
7057 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7058 local dns_query_data=$7
7059 shift; shift; shift; shift; shift; shift; shift;
7060 # Packet size => UDP header (8) +
7061 # DNS data (header + query)
7062 ip_len=`expr 8 + ${#dns_query_data} / 2`
7063 udp_len=$ip_len
7064 ip_len=$(printf "%x" $ip_len)
7065 udp_len=$(printf "%x" $udp_len)
7066 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7067 request=${request}9234003500${udp_len}0000
7068 #dns data
7069 request=${request}${dns_query_data}
7070
7071 if test $dns_reply != 0; then
7072 local dns_reply=$1
7073 ip_len=`expr 8 + ${#dns_reply} / 2`
7074 udp_len=$ip_len
7075 ip_len=$(printf "%x" $ip_len)
7076 udp_len=$(printf "%x" $udp_len)
7077 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7078 reply=${reply}0035923400${udp_len}0000${dns_reply}
7079 echo $reply >> $inport.expected
7080 else
7081 for outport; do
7082 echo $request >> $outport.expected
7083 done
7084 fi
7085 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7086}
7087
302eda27
NS
7088AT_CAPTURE_FILE([ofctl_monitor0.log])
7089as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7090--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7091
7092set_dns_params vm2
7093src_ip=`ip_to_hex 10 0 0 4`
7094dst_ip=`ip_to_hex 10 0 0 1`
7095dns_reply=1
7096test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7097
7098# NXT_RESUMEs should be 1.
7099OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7100
7101$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7102cat 1.expected | cut -c -48 > expout
7103AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7104# Skipping the IPv4 checksum.
7105cat 1.expected | cut -c 53- > expout
7106AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7107
7108reset_pcap_file hv1-vif1 hv1/vif1
7109reset_pcap_file hv1-vif2 hv1/vif2
7110rm -f 1.expected
7111rm -f 2.expected
7112
7113set_dns_params vm1
7114src_ip=`ip_to_hex 10 0 0 6`
7115dst_ip=`ip_to_hex 10 0 0 1`
7116dns_reply=1
7117test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7118
7119# NXT_RESUMEs should be 2.
7120OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7121
7122$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7123cat 2.expected | cut -c -48 > expout
7124AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7125# Skipping the IPv4 checksum.
7126cat 2.expected | cut -c 53- > expout
7127AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7128
7129reset_pcap_file hv1-vif1 hv1/vif1
7130reset_pcap_file hv1-vif2 hv1/vif2
7131rm -f 1.expected
7132rm -f 2.expected
7133
7134# Clear the query name options for ls1-lp2
7135ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7136
7137set_dns_params vm2
7138src_ip=`ip_to_hex 10 0 0 4`
7139dst_ip=`ip_to_hex 10 0 0 1`
7140dns_reply=0
7141test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7142
7143# NXT_RESUMEs should be 3.
7144OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7145
7146$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7147AT_CHECK([cat 1.packets], [0], [])
7148
7149reset_pcap_file hv1-vif1 hv1/vif1
7150reset_pcap_file hv1-vif2 hv1/vif2
7151rm -f 1.expected
7152rm -f 2.expected
7153
7154# Clear the query name for ls1-lp1
7155# Since ls1 has no query names configued,
7156# ovn-northd should not add the DNS flows.
7157ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7158
7159set_dns_params vm1
7160src_ip=`ip_to_hex 10 0 0 6`
7161dst_ip=`ip_to_hex 10 0 0 1`
7162dns_reply=0
7163test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7164
7165# NXT_RESUMEs should be 3 only.
7166OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7167
7168$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7169AT_CHECK([cat 2.packets], [0], [])
7170
7171reset_pcap_file hv1-vif1 hv1/vif1
7172reset_pcap_file hv1-vif2 hv1/vif2
7173rm -f 1.expected
7174rm -f 2.expected
7175
7176# Test IPv6 (AAAA records) using IPv4 packet.
7177# Add back the DNS options for ls1-lp1.
4f4ac4bb 7178ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
302eda27
NS
7179
7180set_dns_params vm1_ipv6_only
7181src_ip=`ip_to_hex 10 0 0 6`
7182dst_ip=`ip_to_hex 10 0 0 1`
7183dns_reply=1
7184test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7185
7186# NXT_RESUMEs should be 4.
7187OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7188
7189$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7190cat 2.expected | cut -c -48 > expout
7191AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7192# Skipping the IPv4 checksum.
7193cat 2.expected | cut -c 53- > expout
7194AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7195
7196reset_pcap_file hv1-vif1 hv1/vif1
7197reset_pcap_file hv1-vif2 hv1/vif2
7198rm -f 1.expected
7199rm -f 2.expected
7200
7201# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7202set_dns_params vm1_ipv4_v6
7203src_ip=`ip_to_hex 10 0 0 6`
7204dst_ip=`ip_to_hex 10 0 0 1`
7205dns_reply=1
7206test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7207
7208# NXT_RESUMEs should be 5.
7209OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7210
7211$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7212cat 2.expected | cut -c -48 > expout
7213AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7214# Skipping the IPv4 checksum.
7215cat 2.expected | cut -c 53- > expout
7216AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7217
7218reset_pcap_file hv1-vif1 hv1/vif1
7219reset_pcap_file hv1-vif2 hv1/vif2
7220rm -f 1.expected
7221rm -f 2.expected
7222
7223# Invalid type.
7224set_dns_params vm1_invalid_type
7225src_ip=`ip_to_hex 10 0 0 6`
7226dst_ip=`ip_to_hex 10 0 0 1`
7227dns_reply=0
7228test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7229
7230# NXT_RESUMEs should be 6.
7231OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7232
7233$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7234AT_CHECK([cat 2.packets], [0], [])
7235
7236reset_pcap_file hv1-vif1 hv1/vif1
7237reset_pcap_file hv1-vif2 hv1/vif2
7238rm -f 1.expected
7239rm -f 2.expected
7240
7241# Incomplete DNS packet.
7242set_dns_params vm1_incomplete
7243src_ip=`ip_to_hex 10 0 0 6`
7244dst_ip=`ip_to_hex 10 0 0 1`
7245dns_reply=0
7246test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7247
7248# NXT_RESUMEs should be 7.
7249OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7250
7251$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7252AT_CHECK([cat 2.packets], [0], [])
7253
7254reset_pcap_file hv1-vif1 hv1/vif1
7255reset_pcap_file hv1-vif2 hv1/vif2
7256rm -f 1.expected
7257rm -f 2.expected
7258
7259# Add one more DNS record to the ls1.
7260ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7261
7262set_dns_params vm3
7263src_ip=`ip_to_hex 10 0 0 4`
7264dst_ip=`ip_to_hex 10 0 0 1`
7265dns_reply=1
7266test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7267
7268# NXT_RESUMEs should be 8.
7269OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7270
7271$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7272cat 1.expected | cut -c -48 > expout
7273AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7274# Skipping the IPv4 checksum.
7275cat 1.expected | cut -c 53- > expout
7276AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7277
7278reset_pcap_file hv1-vif1 hv1/vif1
7279reset_pcap_file hv1-vif2 hv1/vif2
7280rm -f 1.expected
7281rm -f 2.expected
7282
f8e79d82
MM
7283# Try DNS query over IPv6
7284set_dns_params vm1
7285src_ip=aef00000000000000000000000000004
7286dst_ip=aef00000000000000000000000000001
7287dns_reply=1
7288test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7289
7290# NXT_RESUMEs should be 9.
7291OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7292
7293$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
b75f2651
MM
7294# Skipping the UDP checksum.
7295cat 1.expected | cut -c 1-120,125- > expout
7296AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
f8e79d82
MM
7297
7298reset_pcap_file hv1-vif1 hv1/vif1
7299reset_pcap_file hv1-vif2 hv1/vif2
7300rm -f 1.expected
7301rm -f 2.expected
7302
302eda27
NS
7303as hv1
7304 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7305OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7306OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7307
7308as ovn-sb
7309OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7310
7311as ovn-nb
7312OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7313
7314as northd
7315OVS_APP_EXIT_AND_WAIT([ovn-northd])
7316
7317as main
7318OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7319OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7320AT_CLEANUP
7321
75f9e007 7322AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 7323AT_SKIP_IF([test $HAVE_PYTHON = no])
7324ovn_start
7325
7326net_add n1
7327
7328sim_add hv1
7329as hv1
7330ovs-vsctl add-br br-phys
7331ovn_attach n1 br-phys 192.168.0.1
7332ovs-vsctl -- add-port br-int hv1-vif1 -- \
7333 set interface hv1-vif1 external-ids:iface-id=foo1 \
7334 options:tx_pcap=hv1/vif1-tx.pcap \
7335 options:rxq_pcap=hv1/vif1-rx.pcap \
7336 ofport-request=1
7337
7338sim_add gw1
7339as gw1
7340ovs-vsctl add-br br-phys
7341ovn_attach n1 br-phys 192.168.0.2
7342
7343sim_add gw2
7344as gw2
7345ovs-vsctl add-br br-phys
7346ovn_attach n1 br-phys 192.168.0.4
7347
7348sim_add ext1
7349as ext1
7350ovs-vsctl add-br br-phys
7351ovn_attach n1 br-phys 192.168.0.3
7352ovs-vsctl -- add-port br-int ext1-vif1 -- \
7353 set interface ext1-vif1 external-ids:iface-id=outside1 \
7354 options:tx_pcap=ext1/vif1-tx.pcap \
7355 options:rxq_pcap=ext1/vif1-rx.pcap \
7356 ofport-request=1
7357
7358# Pre-populate the hypervisors' ARP tables so that we don't lose any
7359# packets for ARP resolution (native tunneling doesn't queue packets
7360# for ARP resolution).
74868f2c 7361OVN_POPULATE_ARP
1da17a0b 7362
7363ovn-nbctl create Logical_Router name=R1
7364
7365ovn-nbctl ls-add foo
7366ovn-nbctl ls-add alice
7367ovn-nbctl ls-add outside
7368
7369# Connect foo to R1
7370ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7371ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7372 type=router options:router-port=foo \
7373 -- lsp-set-addresses rp-foo router
7374
7375# Connect alice to R1 as distributed router gateway port on gw1
7376ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7377
7378ovn-nbctl \
7379 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7380 chassis_name=gw1 \
7381 priority=20 -- \
7382 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7383 chassis_name=gw2 \
7384 priority=10 -- \
7385 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7386
7387ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7388 type=router options:router-port=alice \
7389 -- lsp-set-addresses rp-alice router
7390
7391# Create logical port foo1 in foo
7392ovn-nbctl lsp-add foo foo1 \
7393-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7394
7395# Create logical port outside1 in outside
7396ovn-nbctl lsp-add outside outside1 \
7397-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7398
7399# Create localnet port in alice
7400ovn-nbctl lsp-add alice ln-alice
7401ovn-nbctl lsp-set-addresses ln-alice unknown
7402ovn-nbctl lsp-set-type ln-alice localnet
7403ovn-nbctl lsp-set-options ln-alice network_name=phys
7404
7405# Create localnet port in outside
7406ovn-nbctl lsp-add outside ln-outside
7407ovn-nbctl lsp-set-addresses ln-outside unknown
7408ovn-nbctl lsp-set-type ln-outside localnet
7409ovn-nbctl lsp-set-options ln-outside network_name=phys
7410
7411# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7412# mapping to the external network, is the one generating packets
7413as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7414as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7415as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7416
7417AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7418
7419# Allow some time for ovn-northd and ovn-controller to catch up.
7420# XXX This should be more systematic.
7421sleep 2
7422
7423ip_to_hex() {
7424 printf "%02x%02x%02x%02x" "$@"
7425}
7426
7427reset_pcap_file() {
7428 local iface=$1
7429 local pcap_file=$2
7430 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7431options:rxq_pcap=dummy-rx.pcap
7432 rm -f ${pcap_file}*.pcap
7433 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7434options:rxq_pcap=${pcap_file}-rx.pcap
7435}
7436
7437test_ip_packet()
7438{
7439 local active_gw=$1
7440 local backup_gw=$2
7441
7442 # Send ip packet between foo1 and outside1
7443 src_mac="f00000010203" # foo1 mac
7444 dst_mac="000001010203" # rp-foo mac (internal router leg)
7445 src_ip=`ip_to_hex 192 168 1 2`
7446 dst_ip=`ip_to_hex 172 16 1 3`
7447 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7448
7449 # ARP request packet to expect at outside1
7450 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7451
7452 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7453
7454 # Send ARP reply from outside1 back to the router
7455 # XXX: note, we could avoid this if we plug this port into a netns
7456 # and setup the IP address into the port, so the kernel would simply reply
7457 src_mac="000002010203"
7458 reply_mac="f00000010204"
7459 dst_ip=`ip_to_hex 172 16 1 3`
7460 src_ip=`ip_to_hex 172 16 1 1`
7461 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7462
7463 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7464
86c9d79a
NS
7465 OVS_WAIT_UNTIL([
7466 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7467grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7468 ])
7469
1da17a0b 7470 # Packet to Expect at ext1 chassis, outside1 port
7471 src_mac="000002010203"
7472 dst_mac="f00000010204"
7473 src_ip=`ip_to_hex 192 168 1 2`
7474 dst_ip=`ip_to_hex 172 16 1 3`
7475 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7476 echo $expected > ext1-vif1.expected
7477
7478 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7479 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7480 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7481
7482 # Resend packet from foo1 to outside1
7483 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7484
7485 sleep 1
7486
7487 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7488 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7489 AT_CHECK([grep $expected packets | sort], [0], [expout])
7490 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7491 AT_CHECK([grep $expected packets | sort], [0], [])
7492}
7493
7494test_ip_packet gw1 gw2
7495
75f9e007
GZ
7496ovn-nbctl --timeout=3 --wait=hv \
7497 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7498 chassis_name=gw1 \
7499 priority=10 -- \
7500 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7501 chassis_name=gw2 \
7502 priority=20 -- \
7503 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7504
7505test_ip_packet gw2 gw1
7506
7507OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7508AT_CLEANUP
7509
7510AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7511AT_SKIP_IF([test $HAVE_PYTHON = no])
7512ovn_start
7513
7514net_add n1
7515
7516sim_add hv1
7517as hv1
7518ovs-vsctl add-br br-phys
7519ovn_attach n1 br-phys 192.168.0.1
7520ovs-vsctl -- add-port br-int hv1-vif1 -- \
7521 set interface hv1-vif1 external-ids:iface-id=foo1 \
7522 options:tx_pcap=hv1/vif1-tx.pcap \
7523 options:rxq_pcap=hv1/vif1-rx.pcap \
7524 ofport-request=1
7525
7526sim_add gw1
7527as gw1
7528ovs-vsctl add-br br-phys
7529ovn_attach n1 br-phys 192.168.0.2
7530
7531sim_add gw2
7532as gw2
7533ovs-vsctl add-br br-phys
7534ovn_attach n1 br-phys 192.168.0.4
7535
7536sim_add ext1
7537as ext1
7538ovs-vsctl add-br br-phys
7539ovn_attach n1 br-phys 192.168.0.3
7540ovs-vsctl -- add-port br-int ext1-vif1 -- \
7541 set interface ext1-vif1 external-ids:iface-id=outside1 \
7542 options:tx_pcap=ext1/vif1-tx.pcap \
7543 options:rxq_pcap=ext1/vif1-rx.pcap \
7544 ofport-request=1
7545
7546# Pre-populate the hypervisors' ARP tables so that we don't lose any
7547# packets for ARP resolution (native tunneling doesn't queue packets
7548# for ARP resolution).
74868f2c 7549OVN_POPULATE_ARP
75f9e007
GZ
7550
7551ovn-nbctl create Logical_Router name=R0
7552ovn-nbctl create Logical_Router name=R1
7553
7554ovn-nbctl ls-add foo
7555ovn-nbctl ls-add join
7556ovn-nbctl ls-add alice
7557ovn-nbctl ls-add outside
7558
7559#Connect foo to R0
7560ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7561ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7562 type=router options:router-port=R0-foo \
7563 -- lsp-set-addresses foo-R0 router
7564
7565#Connect R0 to join
7566ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7567ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7568 type=router options:router-port=R0-join \
7569 -- lsp-set-addresses join-R0 router
7570
7571#Connect join to R1
7572ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7573ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7574 type=router options:router-port=R1-join \
7575 -- lsp-set-addresses join-R1 router
7576
7577#add route rules
7578ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7579ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7580
7581# Connect alice to R1 as distributed router gateway port on gw1
7582ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7583
7584ovn-nbctl \
7585 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7586 chassis_name=gw1 \
7587 priority=20 -- \
7588 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7589 chassis_name=gw2 \
7590 priority=10 -- \
7591 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7592
7593ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7594 type=router options:router-port=alice \
7595 -- lsp-set-addresses rp-alice router
7596
7597# Create logical port foo1 in foo
7598ovn-nbctl lsp-add foo foo1 \
7599-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7600
7601# Create logical port outside1 in outside
7602ovn-nbctl lsp-add outside outside1 \
7603-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7604
7605# Create localnet port in alice
7606ovn-nbctl lsp-add alice ln-alice
7607ovn-nbctl lsp-set-addresses ln-alice unknown
7608ovn-nbctl lsp-set-type ln-alice localnet
7609ovn-nbctl lsp-set-options ln-alice network_name=phys
7610
7611# Create localnet port in outside
7612ovn-nbctl lsp-add outside ln-outside
7613ovn-nbctl lsp-set-addresses ln-outside unknown
7614ovn-nbctl lsp-set-type ln-outside localnet
7615ovn-nbctl lsp-set-options ln-outside network_name=phys
7616
7617# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7618# mapping to the external network, is the one generating packets
7619as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7620as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7621as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7622
7623AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7624
7625# Allow some time for ovn-northd and ovn-controller to catch up.
7626# XXX This should be more systematic.
7627sleep 2
7628
7629ip_to_hex() {
7630 printf "%02x%02x%02x%02x" "$@"
7631}
7632
7633reset_pcap_file() {
7634 local iface=$1
7635 local pcap_file=$2
7636 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7637options:rxq_pcap=dummy-rx.pcap
7638 rm -f ${pcap_file}*.pcap
7639 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7640options:rxq_pcap=${pcap_file}-rx.pcap
7641}
7642
7643test_ip_packet()
7644{
7645 local active_gw=$1
7646 local backup_gw=$2
7647
7648 # Send ip packet between foo1 and outside1
7649 src_mac="f00000010203" # foo1 mac
7650 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7651 src_ip=`ip_to_hex 192 168 1 2`
7652 dst_ip=`ip_to_hex 172 16 1 3`
7653 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7654
7655 # ARP request packet to expect at outside1
7656 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7657
7658 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7659
7660 # Send ARP reply from outside1 back to the router
7661 # XXX: note, we could avoid this if we plug this port into a netns
7662 # and setup the IP address into the port, so the kernel would simply reply
7663 src_mac="000002010203"
7664 reply_mac="f00000010204"
7665 dst_ip=`ip_to_hex 172 16 1 3`
7666 src_ip=`ip_to_hex 172 16 1 1`
7667 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7668
7669 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7670
86c9d79a
NS
7671 OVS_WAIT_UNTIL([
7672 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7673grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7674 ])
7675
75f9e007
GZ
7676 # Packet to Expect at ext1 chassis, outside1 port
7677 src_mac="000002010203"
7678 dst_mac="f00000010204"
7679 src_ip=`ip_to_hex 192 168 1 2`
7680 dst_ip=`ip_to_hex 172 16 1 3`
7681 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7682 echo $expected > ext1-vif1.expected
7683
7684 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7685 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7686 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7687
7688 # Resend packet from foo1 to outside1
7689 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7690
7691 sleep 1
7692
7693 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7694 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7695 AT_CHECK([grep $expected packets | sort], [0], [expout])
7696 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7697 AT_CHECK([grep $expected packets | sort], [0], [])
7698}
7699
7700test_ip_packet gw1 gw2
7701
8e1d9349 7702ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 7703 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7704 chassis_name=gw1 \
7705 priority=10 -- \
7706 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7707 chassis_name=gw2 \
7708 priority=20 -- \
7709 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7710
7711test_ip_packet gw2 gw1
7712
7713OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7714AT_CLEANUP
7715
41a15b71
MS
7716AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7717AT_SKIP_IF([test $HAVE_PYTHON = no])
7718ovn_start
7719
7720# Logical network:
7721# One LR R1 that has switches foo (192.168.1.0/24) and
7722# alice (172.16.1.0/24) connected to it. The logical port
7723# between R1 and alice has a "redirect-chassis" specified,
7724# i.e. it is the distributed router gateway port.
7725# Switch alice also has a localnet port defined.
7726# An additional switch outside has a localnet port and the
7727# same subnet as alice (172.16.1.0/24).
7728
7729# Physical network:
7730# Three hypervisors hv[123].
7731# hv1 hosts vif foo1.
7732# hv2 is the "redirect-chassis" that hosts the distributed
7733# router gateway port.
7734# hv3 hosts vif outside1.
7735# In order to show that connectivity works only through hv2,
7736# an initial round of tests is run without any bridge-mapping
7737# defined for the localnet on hv2. These tests are expected
7738# to fail.
7739# Subsequent tests are run after defining the bridge-mapping
7740# for the localnet on hv2. These tests are expected to succeed.
7741
7742# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 7743# to logical ports.
41a15b71
MS
7744net_add n1
7745
7746sim_add hv1
7747as hv1
7748ovs-vsctl add-br br-phys
7749ovn_attach n1 br-phys 192.168.0.1
7750ovs-vsctl -- add-port br-int hv1-vif1 -- \
7751 set interface hv1-vif1 external-ids:iface-id=foo1 \
7752 options:tx_pcap=hv1/vif1-tx.pcap \
7753 options:rxq_pcap=hv1/vif1-rx.pcap \
7754 ofport-request=1
7755
7756sim_add hv2
7757as hv2
7758ovs-vsctl add-br br-phys
7759ovn_attach n1 br-phys 192.168.0.2
7760
7761sim_add hv3
7762as hv3
7763ovs-vsctl add-br br-phys
7764ovn_attach n1 br-phys 192.168.0.3
7765ovs-vsctl -- add-port br-int hv3-vif1 -- \
7766 set interface hv3-vif1 external-ids:iface-id=outside1 \
7767 options:tx_pcap=hv3/vif1-tx.pcap \
7768 options:rxq_pcap=hv3/vif1-rx.pcap \
7769 ofport-request=1
7770
7771# Pre-populate the hypervisors' ARP tables so that we don't lose any
7772# packets for ARP resolution (native tunneling doesn't queue packets
7773# for ARP resolution).
74868f2c 7774OVN_POPULATE_ARP
41a15b71
MS
7775
7776ovn-nbctl create Logical_Router name=R1
7777
7778ovn-nbctl ls-add foo
7779ovn-nbctl ls-add alice
7780ovn-nbctl ls-add outside
7781
7782# Connect foo to R1
7783ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7784ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7785 type=router options:router-port=foo \
7786 -- lsp-set-addresses rp-foo router
7787
7788# Connect alice to R1 as distributed router gateway port on hv2
7789ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7790 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7791ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7792 type=router options:router-port=alice \
7793 -- lsp-set-addresses rp-alice router
7794
7795# Create logical port foo1 in foo
7796ovn-nbctl lsp-add foo foo1 \
7797-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7798
7799# Create logical port outside1 in outside
7800ovn-nbctl lsp-add outside outside1 \
7801-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7802
7803# Create localnet port in alice
7804ovn-nbctl lsp-add alice ln-alice
7805ovn-nbctl lsp-set-addresses ln-alice unknown
7806ovn-nbctl lsp-set-type ln-alice localnet
7807ovn-nbctl lsp-set-options ln-alice network_name=phys
7808
7809# Create localnet port in outside
7810ovn-nbctl lsp-add outside ln-outside
7811ovn-nbctl lsp-set-addresses ln-outside unknown
7812ovn-nbctl lsp-set-type ln-outside localnet
7813ovn-nbctl lsp-set-options ln-outside network_name=phys
7814
7815# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7816as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7817as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7818
7819
7820# Allow some time for ovn-northd and ovn-controller to catch up.
7821# XXX This should be more systematic.
7822sleep 2
7823
7824echo "---------NB dump-----"
7825ovn-nbctl show
7826echo "---------------------"
7827ovn-nbctl list logical_router
7828echo "---------------------"
7829ovn-nbctl list logical_router_port
7830echo "---------------------"
7831
7832echo "---------SB dump-----"
7833ovn-sbctl list datapath_binding
7834echo "---------------------"
7835ovn-sbctl list port_binding
7836echo "---------------------"
7837ovn-sbctl dump-flows
7838echo "---------------------"
7839ovn-sbctl list chassis
7840ovn-sbctl list encap
1da17a0b 7841echo "------ Gateway_Chassis dump (SBDB) -------"
7842ovn-sbctl list Gateway_Chassis
7843echo "------ Port_Binding chassisredirect -------"
7844ovn-sbctl find Port_Binding type=chassisredirect
7845echo "-------------------------------------------"
41a15b71
MS
7846
7847echo "------ hv1 dump ----------"
7848as hv1 ovs-ofctl show br-int
7849as hv1 ovs-ofctl dump-flows br-int
7850echo "------ hv2 dump ----------"
7851as hv2 ovs-ofctl show br-int
7852as hv2 ovs-ofctl dump-flows br-int
7853echo "------ hv3 dump ----------"
7854as hv3 ovs-ofctl show br-int
7855as hv3 ovs-ofctl dump-flows br-int
7856echo "--------------------------"
7857
1da17a0b 7858
41a15b71
MS
7859# Check that redirect mapping is programmed only on hv2
7860AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7861])
7862AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7863])
7864# Check that hv1 sends chassisredirect port traffic to hv2
7865AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7866])
7867AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7868])
7869# Check that arp reply on distributed gateway port is only programmed on hv2
7870AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7871])
7872AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7873])
7874
7875
7876ip_to_hex() {
7877 printf "%02x%02x%02x%02x" "$@"
7878}
7879
7880
7881: > hv2-vif1.expected
7882: > hv3-vif1.expected
7883
7884# test_arp INPORT SHA SPA TPA [REPLY_HA]
7885#
7886# Causes a packet to be received on INPORT. The packet is an ARP
7887# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7888# it should be the hardware address of the target to expect to receive in an
7889# ARP reply; otherwise no reply is expected.
7890#
7891# INPORT is an logical switch port number, e.g. 11 for vif11.
7892# SHA and REPLY_HA are each 12 hex digits.
7893# SPA and TPA are each 8 hex digits.
7894test_arp() {
7895 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7896 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7897 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7898
7899 if test X$reply_ha != X; then
7900 # Expect to receive the reply, if any.
7901 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7902 echo $reply >> hv${hv}-vif$inport.expected
7903 fi
7904}
7905
7906rtr_ip=$(ip_to_hex 172 16 1 1)
7907foo_ip=$(ip_to_hex 192 168 1 2)
7908outside_ip=$(ip_to_hex 172 16 1 3)
7909
7910echo $rtr_ip
7911echo $foo_ip
7912echo $outside_ip
7913
7914# ARP for router IP address from outside1, no response expected
7915test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7916
7917# Now check the packets actually received against the ones expected.
7918OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7919
7920# Send ip packet between foo1 and outside1
7921src_mac="f00000010203"
7922dst_mac="000001010203"
7923src_ip=`ip_to_hex 192 168 1 2`
7924dst_ip=`ip_to_hex 172 16 1 3`
7925packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7926
7927# Now check the packets actually received against the ones expected.
7928OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7929
7930# Now add bridge-mappings on hv2, which should make everything work
7931as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7932
7933# Allow some time for ovn-northd and ovn-controller to catch up.
7934# XXX This should be more systematic.
7935sleep 2
7936
7937# ARP for router IP address from outside1
7938test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7939
7940# Now check the packets actually received against the ones expected.
7941OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7942
7943# Send ip packet between foo1 and outside1
7944src_mac="f00000010203"
7945dst_mac="000001010203"
7946src_ip=`ip_to_hex 192 168 1 2`
7947dst_ip=`ip_to_hex 172 16 1 3`
7948packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7949
7950# ARP request packet to expect at outside1
7951src_mac="000002010203"
7952src_ip=`ip_to_hex 172 16 1 1`
7953arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7954
7955as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7956
7957echo $arp_request >> hv3-vif1.expected
7958OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7959
7960# Send ARP reply from outside1 back to the router
7961reply_mac="f00000010204"
7962arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7963
7964as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7965
7966# Allow some time for ovn-northd and ovn-controller to catch up.
7967# XXX This should be more systematic.
7968sleep 1
7969
7970# Packet to Expect at outside1
7971src_mac="000002010203"
7972dst_mac="f00000010204"
7973src_ip=`ip_to_hex 192 168 1 2`
7974dst_ip=`ip_to_hex 172 16 1 3`
7975expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7976
7977# Resend packet from foo1 to outside1
7978as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7979
7980echo "------ hv1 dump ----------"
7981as hv1 ovs-ofctl show br-int
7982as hv1 ovs-ofctl dump-flows br-int
7983echo "------ hv2 dump ----------"
7984as hv2 ovs-ofctl show br-int
7985as hv2 ovs-ofctl dump-flows br-int
7986echo "------ hv3 dump ----------"
7987as hv3 ovs-ofctl show br-int
7988as hv3 ovs-ofctl dump-flows br-int
7989echo "----------------------------"
7990
7991echo $expected >> hv3-vif1.expected
7992OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7993
7994#Check ovn-trace over "chassisredirect" port
7995AT_CAPTURE_FILE([trace])
7996ovn_trace () {
7997 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7998}
7999
8000echo 'ip.ttl--;' > expout
8001echo 'eth.src = 00:00:02:01:02:03;' >> expout
8002echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8003echo 'output("ln-alice");' >> expout
8004AT_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])
8005
8006# Create logical port alice1 in alice on hv1
8007as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8008 set interface hv1-vif2 external-ids:iface-id=alice1 \
8009 options:tx_pcap=hv1/vif2-tx.pcap \
8010 options:rxq_pcap=hv1/vif2-rx.pcap \
8011 ofport-request=1
8012
8013ovn-nbctl lsp-add alice alice1 \
8014-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8015
8016# Create logical port foo2 in foo on hv2
8017as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8018 set interface hv2-vif1 external-ids:iface-id=foo2 \
8019 options:tx_pcap=hv2/vif1-tx.pcap \
8020 options:rxq_pcap=hv2/vif1-rx.pcap \
8021 ofport-request=1
8022
8023ovn-nbctl lsp-add foo foo2 \
8024-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8025
8026# Allow some time for ovn-northd and ovn-controller to catch up.
8027# XXX This should be more systematic.
8028sleep 1
8029
8030: > hv1-vif2.expected
8031
8032# Send ip packet between alice1 and foo2
8033src_mac="f00000010205"
8034dst_mac="000002010203"
8035src_ip=`ip_to_hex 172 16 1 4`
8036dst_ip=`ip_to_hex 192 168 1 3`
8037packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8038
8039as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8040
8041# Packet to Expect at foo2
8042src_mac="000001010203"
8043dst_mac="f00000010206"
8044src_ip=`ip_to_hex 172 16 1 4`
8045dst_ip=`ip_to_hex 192 168 1 3`
8046expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8047
8048echo $expected >> hv2-vif1.expected
f5f64552 8049OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 8050
0d31e5be 8051AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 8052])
8053
8e1d9349 8054ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 8055
0d31e5be 8056AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 8057])
8058
41a15b71
MS
8059OVN_CLEANUP([hv1],[hv2],[hv3])
8060
8061AT_CLEANUP
26b9e08d
MS
8062
8063AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8064AT_SKIP_IF([test $HAVE_PYTHON = no])
8065ovn_start
8066# Create logical switches
8067ovn-nbctl ls-add ls0
8068ovn-nbctl ls-add ls1
8069# Create distributed router
8070ovn-nbctl create Logical_Router name=lr0
8071# Add distributed gateway port to distributed router
8072ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8073 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8074ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8075 type=router options:router-port=lrp0 addresses="router"
8076# Add router port to ls1
8077ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8078ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8079 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
8080# Add logical ports for NAT rules
8081ovn-nbctl lsp-add ls1 foo1 \
8082-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8083ovn-nbctl lsp-add ls1 foo2 \
8084-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
8085# Add nat-addresses option
8086ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8087# Add NAT rules
8088AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8089AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8090AT_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 8091AT_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
8092
8093net_add n1
8094sim_add hv1
8095as hv1
8096ovs-vsctl add-br br-phys
8097ovn_attach n1 br-phys 192.168.0.1
8098
8099AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8100AT_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])
8101
8102sim_add hv2
8103as hv2
8104ovs-vsctl add-br br-phys
8105ovn_attach n1 br-phys 192.168.0.2
8106# Initially test with no bridge-mapping on hv2, expect to receive no packets
8107
f40c5588
MS
8108sim_add hv3
8109as hv3
8110ovs-vsctl add-br br-phys
8111ovn_attach n1 br-phys 192.168.0.3
8112# Initially test with no bridge-mapping on hv3
8113
26b9e08d
MS
8114# Create a localnet port.
8115AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8116AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8117AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8118AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8119
8120# Allow some time for ovn-northd and ovn-controller to catch up.
8121# XXX This should be more systematic.
8122sleep 2
8123
8124# Expect no packets when hv2 bridge-mapping is not present
8125: > packets
8126OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8127
8128# Add bridge-mapping on hv2
f40c5588 8129AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
8130
8131# Wait for packets to be received.
8132OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8133trim_zeros() {
8134 sed 's/\(00\)\{1,\}$//'
8135}
8136$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8137expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8138echo $expected > expout
8139expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8140echo $expected >> expout
8141AT_CHECK([sort packets], [0], [expout])
f40c5588 8142sort packets | cat
26b9e08d 8143
f40c5588
MS
8144# Temporarily remove nat-addresses option to avoid race conditions
8145# due to GARP backoff
8146ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8147
8148reset_pcap_file() {
8149 local iface=$1
8150 local pcap_file=$2
8151 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8152options:rxq_pcap=dummy-rx.pcap
8153 rm -f ${pcap_file}*.pcap
8154 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8155options:rxq_pcap=${pcap_file}-rx.pcap
8156}
8157
8158as hv1 reset_pcap_file snoopvif hv1/snoopvif
8159
8160# Add OVS ports for foo1 and foo2 on hv3
8161ovs-vsctl -- add-port br-int hv3-vif1 -- \
8162 set interface hv3-vif1 external-ids:iface-id=foo1 \
8163 ofport-request=1
8164ovs-vsctl -- add-port br-int hv3-vif2 -- \
8165 set interface hv3-vif2 external-ids:iface-id=foo2 \
8166 ofport-request=2
8167
8168# Add bridge-mapping on hv3
8169AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8170
8171# Re-add nat-addresses option
8172ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8173
8174# Wait for packets to be received.
8175OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8176trim_zeros() {
8177 sed 's/\(00\)\{1,\}$//'
8178}
8179
8180$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8181expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8182echo $expected >> expout
8183expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8184echo $expected >> expout
8185AT_CHECK([sort packets], [0], [expout])
8186sort packets | cat
8187
8188OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
8189
8190AT_CLEANUP
6b785fd8 8191
4364646c
ZKL
8192AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8193AT_KEYWORDS([ovn-nd_ra])
8194AT_SKIP_IF([test $HAVE_PYTHON = no])
8195ovn_start
8196
8197# In this test case we create 1 lswitch with 3 VIF ports attached,
8198# and a lrouter connected to the lswitch.
8199# We generate the Router solicitation packet and verify the Router Advertisement
8200# reply packet from the ovn-controller.
8201
8202# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8203# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8204# 'slaac' to allow lrp0 send RA for SLAAC mode.
8205ovn-nbctl ls-add lsw0
8206ovn-nbctl lr-add lr0
8207ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8208ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8209ovn-nbctl \
8210 -- lsp-add lsw0 lsp0 \
8211 -- set Logical_Switch_Port lsp0 type=router \
8212 options:router-port=lrp0 \
8213 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8214net_add n1
8215sim_add hv1
8216as hv1
8217ovs-vsctl add-br br-phys
8218ovn_attach n1 br-phys 192.168.0.2
8219
8220ovn-nbctl lsp-add lsw0 lp1
8221ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8222ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8223
8224ovn-nbctl lsp-add lsw0 lp2
8225ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8226ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8227
8228ovn-nbctl lsp-add lsw0 lp3
8229ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8230ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8231
8232# Add ACL rule for ICMPv6 on lsw0
8233ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8234ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8235ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8236ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8237
8238ovs-vsctl -- add-port br-int hv1-vif1 -- \
8239 set interface hv1-vif1 external-ids:iface-id=lp1 \
8240 options:tx_pcap=hv1/vif1-tx.pcap \
8241 options:rxq_pcap=hv1/vif1-rx.pcap \
8242 ofport-request=1
8243
8244ovs-vsctl -- add-port br-int hv1-vif2 -- \
8245 set interface hv1-vif2 external-ids:iface-id=lp2 \
8246 options:tx_pcap=hv1/vif2-tx.pcap \
8247 options:rxq_pcap=hv1/vif2-rx.pcap \
8248 ofport-request=2
8249
8250ovs-vsctl -- add-port br-int hv1-vif3 -- \
8251 set interface hv1-vif3 external-ids:iface-id=lp3 \
8252 options:tx_pcap=hv1/vif3-tx.pcap \
8253 options:rxq_pcap=hv1/vif3-rx.pcap \
8254 ofport-request=3
8255
8256# Allow some time for ovn-northd and ovn-controller to catch up.
8257# XXX This should be more systematic.
8258sleep 1
8259
8260reset_pcap_file() {
8261 local iface=$1
8262 local pcap_file=$2
8263 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8264options:rxq_pcap=dummy-rx.pcap
8265 rm -f ${pcap_file}*.pcap
8266 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8267options:rxq_pcap=${pcap_file}-rx.pcap
8268}
8269
8270# Make sure that ovn-controller has installed the corresponding OF Flow.
8271OVS_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"`])
8272
8273# This shell function sends a Router Solicitation packet.
8274# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8275test_ipv6_ra() {
8276 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8277 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8278
8279 local len=24
8280 local mtu_opt=""
8281 if test $mtu != 0; then
8282 len=`expr $len + 8`
8283 mtu_opt=05010000${mtu}
8284 fi
8285
8286 if test ${#prefix_opt} != 0; then
8287 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8288 len=`expr $len + ${#prefix_opt} / 2`
8289 fi
8290
8291 len=$(printf "%x" $len)
8292 local lrp_mac=fa163e000001
8293 local lrp_lla=fe80000000000000f8163efffe000001
8294 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8295 echo $reply >> $inport.expected
8296
8297 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8298}
8299
8300AT_CAPTURE_FILE([ofctl_monitor0.log])
8301as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8302--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8303
8304# MTU is not set and the address mode is set to slaac
8305addr_mode=00
8306default_prefix_option_config=030440c0ffffffffffffffff00000000
8307src_mac=fa163e000002
8308src_lla=fe80000000000000f8163efffe000002
8309test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8310
8311# NXT_RESUME should be 1.
8312OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8313
8314$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8315
8316cat 1.expected | cut -c -112 > expout
8317AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8318
8319# Skipping the ICMPv6 checksum.
8320cat 1.expected | cut -c 117- > expout
8321AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8322
8323rm -f *.expected
8324reset_pcap_file hv1-vif1 hv1/vif1
8325reset_pcap_file hv1-vif2 hv1/vif2
8326reset_pcap_file hv1-vif3 hv1/vif3
8327
8328# Set the MTU to 1500
8329ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8330
8331# Make sure that ovn-controller has installed the corresponding OF Flow.
8332OVS_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"`])
8333
8334addr_mode=00
8335default_prefix_option_config=030440c0ffffffffffffffff00000000
8336src_mac=fa163e000003
8337src_lla=fe80000000000000f8163efffe000003
8338mtu=000005dc
8339
8340test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8341
8342# NXT_RESUME should be 2.
8343OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8344
8345$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8346
8347cat 2.expected | cut -c -112 > expout
8348AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8349
8350# Skipping the ICMPv6 checksum.
8351cat 2.expected | cut -c 117- > expout
8352AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8353
8354rm -f *.expected
8355reset_pcap_file hv1-vif1 hv1/vif1
8356reset_pcap_file hv1-vif2 hv1/vif2
8357reset_pcap_file hv1-vif3 hv1/vif3
8358
8359# Set the address mode to dhcpv6_stateful
8360ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8361# Make sure that ovn-controller has installed the corresponding OF Flow.
8362OVS_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"`])
8363
8364addr_mode=80
8365default_prefix_option_config=""
8366src_mac=fa163e000004
8367src_lla=fe80000000000000f8163efffe000004
8368mtu=000005dc
8369
8370test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8371
8372# NXT_RESUME should be 3.
8373OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8374
8375$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8376
8377cat 3.expected | cut -c -112 > expout
8378AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8379
8380# Skipping the ICMPv6 checksum.
8381cat 3.expected | cut -c 117- > expout
8382AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8383
8384rm -f *.expected
8385reset_pcap_file hv1-vif1 hv1/vif1
8386reset_pcap_file hv1-vif2 hv1/vif2
8387reset_pcap_file hv1-vif3 hv1/vif3
8388
8389# Set the address mode to dhcpv6_stateless
8390ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8391# Make sure that ovn-controller has installed the corresponding OF Flow.
8392OVS_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"`])
8393
8394addr_mode=40
8395default_prefix_option_config=030440c0ffffffffffffffff00000000
8396src_mac=fa163e000002
8397src_lla=fe80000000000000f8163efffe000002
8398mtu=000005dc
8399
8400test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8401
8402# NXT_RESUME should be 4.
8403OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8404
8405$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8406
8407cat 1.expected | cut -c -112 > expout
8408AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8409
8410# Skipping the ICMPv6 checksum.
8411cat 1.expected | cut -c 117- > expout
8412AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8413
8414rm -f *.expected
8415reset_pcap_file hv1-vif1 hv1/vif1
8416reset_pcap_file hv1-vif2 hv1/vif2
8417reset_pcap_file hv1-vif3 hv1/vif3
8418
8419# Set the address mode to invalid.
8420ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8421# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8422OVS_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"`])
8423
8424addr_mode=40
8425default_prefix_option_config=""
8426src_mac=fa163e000002
8427src_lla=fe80000000000000f8163efffe000002
8428mtu=000005dc
8429
8430test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8431
8432# NXT_RESUME should be 4 only.
8433OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8434
8435$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8436AT_CHECK([cat 1.packets], [0], [])
8437
8438OVN_CLEANUP([hv1])
8439AT_CLEANUP
8440
6b785fd8
GS
8441AT_SETUP([ovn -- /32 router IP address])
8442AT_SKIP_IF([test $HAVE_PYTHON = no])
8443ovn_start
8444
8445# Logical network:
8446# 2 LS 'foo' and 'alice' connected via router R1.
8447# R1 connects to 'alice' with a /32 IP address. We use static routes and
8448# nexthop to push traffic to a logical port in switch 'alice'
8449
8450ovn-nbctl lr-add R1
8451
8452ovn-nbctl ls-add foo
8453ovn-nbctl ls-add alice
8454
8455# Connect foo to R1
8456ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8457ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8458 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8459
8460# Connect alice to R1.
8461ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8462ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8463 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8464
8465# Create logical port foo1 in foo
8466ovn-nbctl lsp-add foo foo1 \
8467-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8468
8469# Create logical port alice1 in alice
8470ovn-nbctl lsp-add alice alice1 \
8471-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8472
8473#install default route in R1 to use alice1's IP address as nexthop
8474ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8475
8476# Create two hypervisor and create OVS ports corresponding to logical ports.
8477net_add n1
8478
8479sim_add hv1
8480as hv1
8481ovs-vsctl add-br br-phys
8482ovn_attach n1 br-phys 192.168.0.1
8483ovs-vsctl -- add-port br-int hv1-vif1 -- \
8484 set interface hv1-vif1 external-ids:iface-id=foo1 \
8485 options:tx_pcap=hv1/vif1-tx.pcap \
8486 options:rxq_pcap=hv1/vif1-rx.pcap \
8487 ofport-request=1
8488
8489sim_add hv2
8490as hv2
8491ovs-vsctl add-br br-phys
8492ovn_attach n1 br-phys 192.168.0.2
8493ovs-vsctl -- add-port br-int hv2-vif1 -- \
8494 set interface hv2-vif1 external-ids:iface-id=alice1 \
8495 options:tx_pcap=hv2/vif1-tx.pcap \
8496 options:rxq_pcap=hv2/vif1-rx.pcap \
8497 ofport-request=1
8498
8499
8500# Pre-populate the hypervisors' ARP tables so that we don't lose any
8501# packets for ARP resolution (native tunneling doesn't queue packets
8502# for ARP resolution).
74868f2c 8503OVN_POPULATE_ARP
6b785fd8
GS
8504
8505# Allow some time for ovn-northd and ovn-controller to catch up.
8506# XXX This should be more systematic.
8507sleep 1
8508
8509ip_to_hex() {
8510 printf "%02x%02x%02x%02x" "$@"
8511}
8512
8513# Send ip packets between foo1 and alice1
8514src_mac="f00000010203"
8515dst_mac="000000010203"
8516src_ip=`ip_to_hex 192 168 1 2`
8517dst_ip=`ip_to_hex 10 0 0 2`
8518packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8519
8520# Send the first packet to trigger a ARP response and population of
8521# mac_bindings table.
8522as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8523OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
b0b27a83 8524ovn-nbctl --wait=hv sync
6b785fd8
GS
8525# Send the second packet to reach the destination.
8526as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8527
8528# Packet to Expect at 'alice1'
8529src_mac="000000010204"
8530dst_mac="f00000010204"
8531src_ip=`ip_to_hex 192 168 1 2`
8532dst_ip=`ip_to_hex 10 0 0 2`
8533echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8534
8535OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8536
8537OVN_CLEANUP([hv1],[hv2])
8538
8539AT_CLEANUP
2a38ef45
DA
8540
8541AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8542AT_SKIP_IF([test $HAVE_PYTHON = no])
8543ovn_start
8544
8545ovn-nbctl ls-add ls1
8546
8547# Add localport to the switch
8548ovn-nbctl lsp-add ls1 lp01
8549ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8550ovn-nbctl lsp-set-type lp01 localport
8551
8552net_add n1
8553
8554for i in 1 2; do
8555 sim_add hv$i
8556 as hv$i
8557 ovs-vsctl add-br br-phys
8558 ovn_attach n1 br-phys 192.168.0.$i
8559 ovs-vsctl add-port br-int vif01 -- \
8560 set Interface vif01 external-ids:iface-id=lp01 \
8561 options:tx_pcap=hv${i}/vif01-tx.pcap \
8562 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8563 ofport-request=${i}0
8564
8565 ovs-vsctl add-port br-int vif${i}1 -- \
8566 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8567 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8568 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8569 ofport-request=${i}1
8570
8571 ovn-nbctl lsp-add ls1 lp${i}1
8572 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8573 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8574
8575 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8576done
8577
8578ovn-nbctl --wait=sb sync
8579ovn-sbctl dump-flows
8580
74868f2c 8581OVN_POPULATE_ARP
2a38ef45
DA
8582
8583# Given the name of a logical port, prints the name of the hypervisor
8584# on which it is located.
8585vif_to_hv() {
8586 echo hv${1%?}
8587}
8588#
8589# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8590#
8591# This shell function causes a packet to be received on INPORT. The packet's
8592# content has Ethernet destination DST and source SRC (each exactly 12 hex
8593# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8594# logical switch port numbers, e.g. 11 for vif11.
8595#
8596# EOUT is the end-to-end output port, that is, where the packet will end up
8597# after possibly bouncing through one or more localnet ports. LOUT is the
8598# logical output port, which might be a localnet port, as seen by ovn-trace
8599# (which doesn't know what localnet ports are connected to and therefore can't
8600# figure out the end-to-end answer).
8601#
8602# DEFHV is the default hypervisor from where the packet is going to be sent
8603# if the source port is a localport.
8604for i in 1 2; do
8605 for j in 0 1; do
8606 : > $i$j.expected
8607 done
8608done
8609test_packet() {
8610 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8611 echo "$@"
8612
8613 # First try tracing the packet.
8614 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8615 if test $lout != drop; then
8616 echo "output(\"$lout\");"
8617 fi > expout
8618 AT_CAPTURE_FILE([trace])
8619 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8620
8621 # Then actually send a packet, for an end-to-end test.
8622 local packet=$(echo $dst$src | sed 's/://g')${eth}
8623 hv=`vif_to_hv $inport`
8624 # If hypervisor 0 (localport) use the defhv parameter
da88b550 8625 if test $hv = hv0; then
2a38ef45
DA
8626 hv=$defhv
8627 fi
8628 vif=vif$inport
8629 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8630 if test $eout != drop; then
8631 echo $packet >> ${eout#lp}.expected
8632 fi
8633}
8634
8635
8636# lp11 and lp21 are on different hypervisors
8637test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8638test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8639
8640# Both VIFs should be able to reach the localport on their own HV
8641test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8642test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8643
8644# Packet sent from localport on same hv should reach the vif
8645test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8646test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8647
8648# Packet sent from localport on different hv should be dropped
8649test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8650test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8651
8652# Now check the packets actually received against the ones expected.
8653for i in 1 2; do
8654 for j in 0 1; do
8655 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8656 done
8657done
8658
8659OVN_CLEANUP([hv1],[hv2])
8660
8661AT_CLEANUP
1da17a0b 8662
8663AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8664AT_SKIP_IF([test $HAVE_PYTHON = no])
8665ovn_start
8666
8667net_add n1
8668
8669# create gateways with external network connectivity
8670
8671for i in 1 2; do
8672 sim_add gw$i
8673 as gw$i
8674 ovs-vsctl add-br br-phys
8675 ovn_attach n1 br-phys 192.168.0.$i
8676 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8677done
8678
8679ovn-nbctl ls-add inside
8680ovn-nbctl ls-add outside
8681
8682# create hypervisors with a vif port each to an internal network
8683
8684for i in 1 2; do
8685 sim_add hv$i
8686 as hv$i
8687 ovs-vsctl add-br br-phys
8688 ovn_attach n1 br-phys 192.168.0.1$i
8689 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8690 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8691 options:tx_pcap=hv$i/vif1-tx.pcap \
8692 options:rxq_pcap=hv$i/vif1-rx.pcap \
8693 ofport-request=1
8694
8695 ovn-nbctl lsp-add inside inside$i \
8696 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8697
8698done
8699
74868f2c 8700OVN_POPULATE_ARP
1da17a0b 8701
8702ovn-nbctl create Logical_Router name=R1
8703
8704# Connect inside to R1
8705ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8706ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8707 type=router options:router-port=inside \
8708 -- lsp-set-addresses rp-inside router
8709
8710# Connect outside to R1 as distributed router gateway port on gw1+gw2
8711ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8712
8713ovn-nbctl --id=@gc0 create Gateway_Chassis \
8714 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8715 --id=@gc1 create Gateway_Chassis \
8716 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8717 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8718
8719ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8720 type=router options:router-port=outside \
8721 -- lsp-set-addresses rp-outside router
8722
8723# Create localnet port in outside
8724ovn-nbctl lsp-add outside ln-outside
8725ovn-nbctl lsp-set-addresses ln-outside unknown
8726ovn-nbctl lsp-set-type ln-outside localnet
8727ovn-nbctl lsp-set-options ln-outside network_name=phys
8728
8729# Allow some time for ovn-northd and ovn-controller to catch up.
8730# XXX This should be more systematic.
8e1d9349 8731ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8732
8733echo "---------NB dump-----"
8734ovn-nbctl show
8735echo "---------------------"
8736ovn-nbctl list logical_router
8737echo "---------------------"
8738ovn-nbctl list logical_router_port
8739echo "---------------------"
8740
8741echo "---------SB dump-----"
8742ovn-sbctl list datapath_binding
8743echo "---------------------"
8744ovn-sbctl list port_binding
8745echo "---------------------"
8746ovn-sbctl dump-flows
8747echo "---------------------"
8748ovn-sbctl list chassis
8749ovn-sbctl list encap
8750echo "---------------------"
8751echo "------ Gateway_Chassis dump (SBDB) -------"
8752ovn-sbctl list Gateway_Chassis
8753echo "------ Port_Binding chassisredirect -------"
8754ovn-sbctl find Port_Binding type=chassisredirect
8755echo "-------------------------------------------"
8756
3475695e
VA
8757for chassis in gw1 gw2 hv1 hv2; do
8758 as $chassis
8759 echo "------ $chassis dump ----------"
8760 ovs-ofctl show br-int
8761 ovs-ofctl dump-flows br-int
3475695e
VA
8762 echo "--------------------------"
8763done
508b7f96 8764function bfd_dump() {
8765 for chassis in gw1 gw2 hv1 hv2; do
8766 as $chassis
8767 echo "------ $chassis dump (BFD)----"
8768 echo "BFD (from $chassis):"
8769 # dump BFD config and status to the other chassis
8770 for chassis2 in gw1 gw2 hv1 hv2; do
8771 if [[ "$chassis" != "$chassis2" ]]; then
8772 echo " -> $chassis2:"
8773 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8774 fi
8775 done
8776 echo "--------------------------"
8777 done
8778}
8779
8780bfd_dump
1da17a0b 8781
8782hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8783hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8784hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8785hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8786
8787echo $hv1_gw1_ofport
8788echo $hv1_gw2_ofport
8789echo $hv2_gw1_ofport
8790echo $hv2_gw2_ofport
8791
8792echo "--- hv1 ---"
8793as hv1 ovs-ofctl dump-flows br-int table=32
8794
8795echo "--- hv2 ---"
8796as hv2 ovs-ofctl dump-flows br-int table=32
8797
508b7f96 8798gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8799gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8800
1da17a0b 8801AT_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
8802])
8803
8804AT_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
8805])
8806
508b7f96 8807sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8808
8809# make sure that flows for handling the outside router port reside on gw1
66d89287 8810AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8811]])
66d89287 8812AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8813]])
8814
8815# make sure ARP responder flows for outside router port reside on gw1 too
8816AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8817]])
8818AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8819]])
8820
8821
8822
8823# check that the chassis redirect port has been claimed by the gw1 chassis
8824AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8825 [0],[[1
8826]])
8827
8828
8829# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 8830
8831ovn-nbctl --id=@gc0 create Gateway_Chassis \
8832 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8833 --id=@gc1 create Gateway_Chassis \
8834 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8835 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8836
508b7f96 8837
1da17a0b 8838# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 8839ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8840
508b7f96 8841# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 8842AT_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
8843])
8844
8845AT_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
8846])
8847
508b7f96 8848# check that the chassis redirect port has been reclaimed by the gw2 chassis
8849AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8850 [0],[[1
8851]])
1da17a0b 8852
3475695e
VA
8853# check BFD enablement on tunnel ports from gw1 #########
8854as gw1
8855for chassis in gw2 hv1 hv2; do
8856 echo "checking gw1 -> $chassis"
8857 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8858 [[enable=true
8859]])
8860done
8861
8862
8863# check BFD enablement on tunnel ports from gw2 ##########
8864as gw2
8865for chassis in gw1 hv1 hv2; do
8866 echo "checking gw2 -> $chassis"
8867 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8868 [[enable=true
8869]])
8870done
8871
8872# check BFD enablement on tunnel ports from hv1 ###########
8873as hv1
8874for chassis in gw1 gw2; do
8875 echo "checking hv1 -> $chassis"
8876 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8877 [[enable=true
8878]])
8879done
8880# make sure BFD is not enabled to hv2, we don't need it
8881AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8882 [[enable=false
8883]])
8884
8885
8886# check BFD enablement on tunnel ports from hv2 ##########
8887as hv2
8888for chassis in gw1 gw2; do
8889 echo "checking hv2 -> $chassis"
8890 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8891 [[enable=true
8892]])
8893done
8894# make sure BFD is not enabled to hv1, we don't need it
8895AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8896 [[enable=false
8897]])
8898
508b7f96 8899sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8900
8901# make sure that flows for handling the outside router port reside on gw2 now
66d89287 8902AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8903]])
66d89287 8904AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8905]])
8906
8907# disconnect GW2 from the network, GW1 should take over
8908as gw2
8909port=${sandbox}_br-phys
8910as main ovs-vsctl del-port n1 $port
8911sleep 4
8912
8913bfd_dump
8914
8915# make sure that flows for handling the outside router port reside on gw2 now
66d89287 8916AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8917]])
66d89287 8918AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8919]])
8920
8921# check that the chassis redirect port has been reclaimed by the gw1 chassis
8922AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8923 [0],[[1
8924]])
8925
1da17a0b 8926OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8927
8928AT_CLEANUP
acfc41ff
VAK
8929
8930AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8931AT_SKIP_IF([test $HAVE_PYTHON = no])
8932ovn_start
8933ovn-nbctl ls-add ls0
8934ovn-nbctl ls-add ls1
8935ovn-nbctl create Logical_Router name=lr0
8936ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8937
8938ovn-nbctl --id=@gc0 create Gateway_Chassis \
8939 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8940 --id=@gc1 create Gateway_Chassis \
8941 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8942 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8943
8944ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8945 type=router options:router-port=lrp0 addresses="router"
8946ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8947ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8948 type=router options:router-port=lrp1 addresses="router"
8949
8950# Add NAT rules
8951AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8952
8953net_add n1
8954sim_add hv1
8955as hv1
8956ovs-vsctl add-br br-phys
8957ovn_attach n1 br-phys 192.168.0.1
8958AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8959AT_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])
8960
8961sim_add hv2
8962as hv2
8963ovs-vsctl add-br br-phys
8964ovn_attach n1 br-phys 192.168.0.2
8965AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8966
8967sim_add hv3
8968as hv3
8969ovs-vsctl add-br br-phys
8970ovn_attach n1 br-phys 192.168.0.3
8971AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8972
8973# Create a localnet port.
8974AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8975AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8976AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8977AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8978
8979# wait for earlier changes to take effect
6c8d3d69 8980AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
acfc41ff
VAK
8981
8982reset_pcap_file() {
8983 local iface=$1
8984 local pcap_file=$2
8985 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8986options:rxq_pcap=dummy-rx.pcap
8987 rm -f ${pcap_file}*.pcap
8988 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8989options:rxq_pcap=${pcap_file}-rx.pcap
8990}
8991
8992as hv1 reset_pcap_file snoopvif hv1/snoopvif
8993as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8994as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8995# add nat-addresses option
6c8d3d69 8996ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
acfc41ff
VAK
8997
8998# Wait for packets to be received through hv2.
8999OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9000trim_zeros() {
9001 sed 's/\(00\)\{1,\}$//'
9002}
9003
2db7bb2c 9004only_broadcast_from_lrp1() {
9005 grep "fffffffffffff00000000001"
9006}
9007
acfc41ff 9008garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 9009echo $garp > expout
9010
9011$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
9012echo "packets on hv1-snoopvif:"
9013cat hv1_snoop_tx
9014AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 9015$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
9016echo "packets on hv2 br-phys tx"
9017cat hv2_br_phys_tx
9018AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 9019$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
9020echo "packets on hv3 br-phys tx"
9021cat hv3_br_phys_tx
9022AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9023
9024
9025# at this point, we invert the priority of the gw chassis between hv2 and hv3
9026
9027ovn-nbctl --wait=hv \
9028 --id=@gc0 create Gateway_Chassis \
9029 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9030 --id=@gc1 create Gateway_Chassis \
9031 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9032 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9033
9034
9035as hv1 reset_pcap_file snoopvif hv1/snoopvif
9036as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9037as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9038
9039# Wait for packets to be received.
9040OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9041trim_zeros() {
9042 sed 's/\(00\)\{1,\}$//'
9043}
9044
2db7bb2c 9045$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 9046AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 9047$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 9048AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 9049$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 9050AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
9051
9052# change localnet port tag.
9053AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9054
9055# wait for earlier changes to take effect
6c8d3d69 9056AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
03b85a58
GL
9057
9058# update nat-addresses option
6c8d3d69
HZ
9059ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9060ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
03b85a58
GL
9061
9062as hv1 reset_pcap_file snoopvif hv1/snoopvif
9063as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9064as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9065
9066# Wait for packets to be received.
9067OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9068trim_zeros() {
9069 sed 's/\(00\)\{1,\}$//'
9070}
9071
9072garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9073echo $garp > expout
9074
9075$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9076AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9077$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9078AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9079$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9080AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9081
acfc41ff
VAK
9082OVN_CLEANUP([hv1],[hv2],[hv3])
9083
9084AT_CLEANUP
79371ff5 9085
9086AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9087AT_SKIP_IF([test $HAVE_PYTHON = no])
9088ovn_start
9089
9090net_add n1
9091
9092# create two gateways with external network connectivity
9093for i in 1 2; do
9094 sim_add gw$i
9095 as gw$i
9096 ovs-vsctl add-br br-phys
9097 ovn_attach n1 br-phys 192.168.0.$i
9098 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9099done
9100
9101ovn-nbctl ls-add inside
9102ovn-nbctl ls-add outside
9103
9104# create one hypervisors with a vif port the internal network
9105sim_add hv1
9106as hv1
9107ovs-vsctl add-br br-phys
9108ovn_attach n1 br-phys 192.168.0.11
9109ovs-vsctl -- add-port br-int hv1-vif1 -- \
9110 set interface hv1-vif1 external-ids:iface-id=inside1 \
9111 options:tx_pcap=hv1/vif1-tx.pcap \
9112 options:rxq_pcap=hv1/vif1-rx.pcap \
9113 ofport-request=1
9114
9115ovn-nbctl lsp-add inside inside1 \
9116 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9117
9118
74868f2c 9119OVN_POPULATE_ARP
79371ff5 9120
9121ovn-nbctl create Logical_Router name=R1
9122
9123# Connect inside to R1
9124ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9125ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9126 type=router options:router-port=inside \
9127 -- lsp-set-addresses rp-inside router
9128
9129# Connect outside to R1 as distributed router gateway port on gw1+gw2
9130ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9131
9132ovn-nbctl --id=@gc0 create Gateway_Chassis \
9133 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9134 --id=@gc1 create Gateway_Chassis \
9135 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9136 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9137
9138ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9139 type=router options:router-port=outside \
9140 -- lsp-set-addresses rp-outside router
9141
9142# Create localnet port in outside
9143ovn-nbctl lsp-add outside ln-outside
9144ovn-nbctl lsp-set-addresses ln-outside unknown
9145ovn-nbctl lsp-set-type ln-outside localnet
9146ovn-nbctl lsp-set-options ln-outside network_name=phys
9147
9148# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 9149ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 9150
9151# currently when ovn-controller is restarted, the old entry is deleted
9152# and a new one is created, which leaves the Gateway_Chassis with
9153# an empty chassis for a while. NOTE: restarting ovn-controller in tests
9154# doesn't have the same effect because "name" is conserved, and the
9155# Chassis entry is not replaced.
9156
3a0c5805 9157> gw1/ovn-controller.log
325b2b1a 9158
79371ff5 9159gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9160ovn-sbctl destroy Chassis $gw2_chassis
9161
9162# Ensure ovn-controller has processed latest sbdb update
9163# ovn-nbctl --wait=hv sync
9164
9165AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9166
9167OVN_CLEANUP([gw1],[gw2],[hv1])
9168
9169AT_CLEANUP
63d91afa 9170
b1a3a6a4
NS
9171AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9172AT_KEYWORDS([ovn-nd_ns for unknown mac])
9173AT_SKIP_IF([test $HAVE_PYTHON = no])
9174ovn_start
9175
9176ovn-nbctl ls-add sw0_ip6
9177ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9178ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9179"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9180
9181ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9182"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9183
9184ovn-nbctl lr-add lr0_ip6
847dc1c2 9185ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
9186ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9187ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9188ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
9189ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9190ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9191
9192ovn-nbctl ls-add public
9193ovn-nbctl lsp-add public ln-public
9194ovn-nbctl lsp-set-addresses ln-public unknown
9195ovn-nbctl lsp-set-type ln-public localnet
9196ovn-nbctl lsp-set-options ln-public network_name=phys
9197
9198ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
91992001:db8:1:0:200:02ff:fe01:0204/64 \
9200-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9201
9202
9203ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9204rp-ip6_public type=router options:router-port=ip6_public \
9205-- lsp-set-addresses rp-ip6_public router
9206
9207net_add n1
9208sim_add hv1
9209as hv1
9210ovs-vsctl add-br br-phys
9211ovn_attach n1 br-phys 192.168.0.2
9212
9213ovs-vsctl -- add-port br-int hv1-vif1 -- \
9214 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9215 options:tx_pcap=hv1/vif1-tx.pcap \
9216 options:rxq_pcap=hv1/vif1-rx.pcap \
9217 ofport-request=1
9218ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9219
86c9d79a
NS
9220OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9221cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9222
9223# There is only one chassis.
9224chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9225OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
b1a3a6a4
NS
9226
9227trim_zeros() {
9228 sed 's/\(00\)\{1,\}$//'
9229}
9230
9231# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9232# addresses. ovn-controller should generate an IPv6 NS request for IPv6
9233# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9234# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9235# This function sends ipv6 packet
9236test_ipv6() {
9237 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9238 dst_ip=20010db800010000020002fffe010205
9239
9240 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9241 packet=${packet}8000000000000000
9242 shift; shift; shift; shift
9243
9244 dst_mac=3333ff010205
9245 src_mac=000002010204
9246 mcast_node_ip=ff0200000000000000000001ff010205
9247 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9248 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9249 expected_packet=${expected_packet}0101${src_mac}
9250
9251 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9252 echo $expected_packet >> ipv6_ns.expected
9253}
9254
9255src_mac=506400000002
9256dst_mac=00000000af01
9257src_ip=aef0000000000000526400fffe000002
9258# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9259# should be received by the ports attached to br-phys.
9260test_ipv6 1 $src_mac $dst_mac $src_ip 2
9261
86c9d79a
NS
9262OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9263OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9264
b1a3a6a4
NS
9265$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9266trim_zeros > 1.packets
9267$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9268trim_zeros > 2.packets
9269
9270cat ipv6_ns.expected | cut -c -112 > expout
9271AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9272AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9273
9274# Skipping the ICMPv6 checksum
9275cat ipv6_ns.expected | cut -c 117- > expout
9276AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9277AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9278
9279OVN_CLEANUP([hv1])
9280
9281AT_CLEANUP
9282
63d91afa
LR
9283AT_SETUP([ovn -- options:requested-chassis for logical port])
9284ovn_start
9285
9286net_add n1
9287
9288ovn-nbctl ls-add ls0
9289ovn-nbctl lsp-add ls0 lsp0
9290
9291# create two hypervisors, each with one vif port
9292sim_add hv1
9293as hv1
9294ovs-vsctl add-br br-phys
9295ovn_attach n1 br-phys 192.168.0.11
99cc5c92
NS
9296ovs-vsctl -- add-port br-int hv1-vif0 -- \
9297set Interface hv1-vif0 ofport-request=1
63d91afa
LR
9298
9299sim_add hv2
9300as hv2
9301ovs-vsctl add-br br-phys
9302ovn_attach n1 br-phys 192.168.0.12
99cc5c92
NS
9303ovs-vsctl -- add-port br-int hv2-vif0 -- \
9304set Interface hv2-vif0 ofport-request=1
63d91afa
LR
9305
9306# Allow only chassis hv1 to bind logical port lsp0.
9307ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9308
9309# Allow some time for ovn-northd and ovn-controller to catch up.
9310ovn-nbctl --wait=hv --timeout=3 sync
9311
9312# Retrieve hv1 and hv2 chassis UUIDs from southbound database
2aa57f08
HZ
9313ovn-sbctl wait-until chassis hv1
9314ovn-sbctl wait-until chassis hv2
63d91afa
LR
9315hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9316hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9317
9318# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9319echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9320as hv2
9321ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9322
9323OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9324AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9325
99cc5c92
NS
9326# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9327AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9328AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9329
9330# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
63d91afa
LR
9331echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9332as hv1
9333ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9334
9335OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
2aa57f08 9336AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
63d91afa 9337
99cc5c92
NS
9338# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9339as hv1 ovs-ofctl dump-flows br-int
9340AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9341AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9342
9343# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
63d91afa
LR
9344# the requested chassis for lsp0 is changed from hv1 to hv2.
9345echo "verifying that lsp0 binding moves when requested-chassis is changed"
9346
9347ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9348OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
2aa57f08 9349OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
63d91afa 9350
99cc5c92
NS
9351# (6) Chassis hv2 should add flows and hv1 should not.
9352AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9353AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9354
9355AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9356AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9357
63d91afa
LR
9358OVN_CLEANUP([hv1],[hv2])
9359
9360AT_CLEANUP
bd32425f
RB
9361
9362AT_SETUP([ovn -- options:requested-chassis with hostname])
9363
9364ovn_start
9365
9366ovn-nbctl ls-add ls0
9367ovn-nbctl lsp-add ls0 lsp0
9368
9369net_add n1
9370sim_add hv1
9371as hv1
9372ovs-vsctl add-br br-phys
9373ovn_attach n1 br-phys 192.168.0.11
99cc5c92 9374ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
bd32425f 9375
362ab40a 9376ovn-sbctl wait-until chassis hv1
bd32425f
RB
9377hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9378echo "hv1_hostname=${hv1_hostname}"
9379ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9380as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9381
9382hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9383echo "hv1_uuid=${hv1_uuid}"
9384OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9385AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
99cc5c92
NS
9386AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9387AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
bd32425f
RB
9388
9389ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9390OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9391ovn-nbctl --wait=hv --timeout=3 sync
9392AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
99cc5c92
NS
9393AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9394AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
bd32425f
RB
9395
9396OVN_CLEANUP([hv1])
9397
9398AT_CLEANUP
4446661a
MM
9399
9400AT_SETUP([ovn -- IPv6 periodic RA])
9401ovn_start
9402
9403# This test sets up two hypervisors.
9404# hv1 and hv2 run ovn-controllers, and
9405# each has a VIF connected to the same
9406# logical switch in OVN. The logical
9407# switch is connected to a logical
9408# router port that is configured to send
9409# periodic router advertisements.
9410#
9411# The reason for having two ovn-controller
9412# hypervisors is to ensure that the
9413# periodic RAs being sent by each ovn-controller
9414# are kept to their local hypervisors. If the
9415# packets are not kept local, then each port
9416# will receive too many RAs.
9417
9418net_add n1
9419sim_add hv1
9420sim_add hv2
9421as hv1
9422ovs-vsctl add-br br-phys
9423ovn_attach n1 br-phys 192.168.0.2
9424as hv2
9425ovs-vsctl add-br br-phys
9426ovn_attach n1 br-phys 192.168.0.3
9427
9428ovn-nbctl lr-add ro
1ea1b0d0 9429ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
4446661a
MM
9430
9431ovn-nbctl ls-add sw
9432ovn-nbctl lsp-add sw sw-ro
9433ovn-nbctl lsp-set-type sw-ro router
9434ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9435ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9436ovn-nbctl lsp-add sw sw-p1
9437ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9438ovn-nbctl lsp-add sw sw-p2
9439ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9440
9441ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9442ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9443ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9444ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9445
86c9d79a
NS
9446for i in 1 2 ; do
9447 as hv$i
9448 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9449 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9450 options:tx_pcap=hv$i/vif1-tx.pcap \
9451 options:rxq_pcap=hv$i/vif1-rx.pcap \
4446661a
MM
9452 ofport-request=1
9453done
9454
86c9d79a
NS
9455OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9456OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
4446661a
MM
9457
9458reset_pcap_file() {
9459 local iface=$1
9460 local pcap_file=$2
9461 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9462options:rxq_pcap=dummy-rx.pcap
9463 rm -f ${pcap_file}*.pcap
9464 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9465options:rxq_pcap=${pcap_file}-rx.pcap
9466
9467}
9468
9469construct_expected_ra() {
9470 local src_mac=000000000001
9471 local dst_mac=333300000001
9472 local src_addr=fe80000000000000020000fffe000001
9473 local dst_addr=ff020000000000000000000000000001
9474
9475 local mtu=$1
9476 local ra_mo=$2
9477 local ra_prefix_la=$3
9478
9479 local slla=0101${src_mac}
9480 local mtu_opt=""
9481 if test $mtu != 0; then
9482 mtu_opt=05010000${mtu}
9483 fi
9484 shift 3
9485
9486 local prefix=""
9487 while [[ $# -gt 0 ]] ; do
9488 local size=$1
9489 local net=$2
9490 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9491 shift 2
9492 done
9493
895ceaf7 9494 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
4446661a
MM
9495 local icmp=8600XXXX${ra}
9496
9497 local ip_len=$(expr ${#icmp} / 2)
1ea1b0d0 9498 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
4446661a
MM
9499
9500 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9501 local eth=${dst_mac}${src_mac}86dd${ip}
9502 local packet=${eth}
9503 echo $packet >> expected
9504}
9505
9506ra_test() {
9507 construct_expected_ra $@
9508
9509 for i in hv1 hv2 ; do
9510 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9511
9512 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9513
9514 cat expected | cut -c -112 > expout
9515 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9516
9517 # Skip ICMPv6 checksum.
9518 cat expected | cut -c 117- > expout
9519 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9520
9521 rm -f packets
9522 as $i reset_pcap_file $i-vif1 $i/vif1
9523 done
9524
9525 rm -f expected
9526}
9527
9528# Baseline test with no MTU
9529ra_test 0 00 c0 40 aef00000000000000000000000000000
9530
9531# Now make sure an MTU option makes it
9532ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9533ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9534
9535# Now test for multiple network prefixes
9536ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9537ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9538
9539# Test a different address mode now
9540ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9541ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9542
9543# And the other address mode
9544ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9545ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9546
9547OVN_CLEANUP([hv1],[hv2])
9548AT_CLEANUP
4826add0
LB
9549
9550AT_SETUP([ovn -- ACL reject rule test])
9551AT_KEYWORDS([acl-reject])
9552AT_SKIP_IF([test $HAVE_PYTHON = no])
9553ovn_start
9554
9555# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9556#
9557# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9558# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9559# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9560# unreachable frame generated from ACL rule hit
9561#
9562# INPORT is a lport number, e.g. 11 for vif11.
9563# HV is a hypervisor number
9564# ETH_SRC and ETH_DST are each 12 hex digits.
9565# IPV4_SRC and IPV4_DST are each 8 hex digits.
9566# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9567test_ip_packet() {
9568 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9569 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9570 shift 9
9571
9572 local ip_ttl=ff
9573 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9574
9575 local reply_icmp_ttl=ff
9576 local icmp_type_code_response=0301
9577 local icmp_data=00000000
9578 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9579 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9580 echo $reply >> vif$inport.expected
9581
9582 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9583}
9584
c319fabc
LB
9585# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
9586#
9587# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
9588# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
9589# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
9590test_ipv6_packet() {
9591 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
9592 shift 7
9593
9594 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9595 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
9596
9597 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
9598 echo $reply >> vif$inport.expected
9599
9600 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9601}
9602
c20ab6aa
LB
9603# 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
9604#
9605# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
9606# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
9607# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
9608#
9609# INPORT is an lport number, e.g. 11 for vif11.
9610# HV is an hypervisor number
9611# ETH_SRC and ETH_DST are each 12 hex digits.
9612# IPV4_SRC and IPV4_DST are each 8 hex digits.
9613# TCP_SPORT and TCP_DPORT are 4 hex digits.
9614# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
9615test_tcp_syn_packet() {
9616 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9617 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
9618 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
9619 shift 12
9620
9621 local ip_ttl=ff
9622 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
9623
9624 local tcp_rst_ttl=ff
9625 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
9626 echo $reply >> vif$inport.expected
9627
9628 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9629}
9630
4826add0
LB
9631# Create hypervisors hv[123].
9632# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
9633# Add all of the vifs to a single logical switch sw0.
9634
9635net_add n1
9636ovn-nbctl ls-add sw0
9637for i in 1 2 3; do
9638 sim_add hv$i
9639 as hv$i
9640 ovs-vsctl add-br br-phys
9641 ovn_attach n1 br-phys 192.168.0.$i
9642
9643 for j in 1 2 3; do
9644 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
9645 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
9646
9647 ovs-vsctl -- add-port br-int vif$i$j -- \
9648 set interface vif$i$j \
9649 external-ids:iface-id=sw0-p$i$j \
9650 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
9651 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
9652 ofport-request=$i$j
9653 done
9654done
9655
9656OVN_POPULATE_ARP
9657# allow some time for ovn-northd and ovn-controller to catch up.
9658sleep 1
9659
9660ip_to_hex() {
9661 printf "%02x%02x%02x%02x" "$@"
9662}
9663
9664for i in 1 2 3; do
9665 : > vif${i}1.expected
9666done
9667
9668ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
9669ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
9670ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
732965bc
HZ
9671
9672# Allow some time for ovn-northd and ovn-controller to catch up.
9673ovn-nbctl --timeout=3 --wait=hv sync
4826add0
LB
9674
9675test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
9676test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
9677test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
9678
c319fabc
LB
9679test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
9680
c20ab6aa
LB
9681test_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
9682test_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
9683test_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
9684
4826add0
LB
9685for i in 1 2 3; do
9686 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
9687done
9688
9689OVN_CLEANUP([hv1], [hv2], [hv3])
9690AT_CLEANUP
689829d5
HZ
9691
9692AT_SETUP([ovn -- Port Groups])
9693AT_KEYWORDS([ovnpg])
9694AT_SKIP_IF([test $HAVE_PYTHON = no])
9695ovn_start
9696
9697# Logical network:
9698#
9699# Three logical switches ls1, ls2, ls3.
9700# One logical router lr0 connected to ls[123],
9701# with nine subnets, three per logical switch:
9702#
9703# lrp11 on ls1 for subnet 192.168.11.0/24
9704# lrp12 on ls1 for subnet 192.168.12.0/24
9705# lrp13 on ls1 for subnet 192.168.13.0/24
9706# ...
9707# lrp33 on ls3 for subnet 192.168.33.0/24
9708#
9709# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9710# digits are the subnet and the last digit distinguishes the VIF.
9711#
9712# This test will create two port groups and uses them in ACL.
9713
9714get_lsp_uuid () {
9715 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9716}
9717
9718pg1_ports=
9719pg2_ports=
9720for i in 1 2 3; do
9721 ovn-nbctl ls-add ls$i
9722 for j in 1 2 3; do
9723 for k in 1 2 3; do
9724 ovn-nbctl \
9725 -- lsp-add ls$i lp$i$j$k \
9726 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
9727 192.168.$i$j.$k"
9728 # logical ports lp[12]?1 belongs to port group pg1
9729 if test $i != 3 && test $k == 1; then
9730 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9731 fi
9732 # logical ports lp[23]?2 belongs to port group pg2
9733 if test $i != 1 && test $k == 2; then
9734 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9735 fi
9736 done
9737 done
9738done
9739
9740ovn-nbctl lr-add lr0
9741for i in 1 2 3; do
9742 for j in 1 2 3; do
9743 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9744 ovn-nbctl \
9745 -- lsp-add ls$i lrp$i$j-attachment \
9746 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9747 options:router-port=lrp$i$j \
9748 addresses='"00:00:00:00:ff:'$i$j'"'
9749 done
9750done
9751
9752ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9753ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9754
9755# create ACLs on all lswitches to drop traffic from pg2 to pg1
9756ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9757ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9758ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9759
9760# Physical network:
9761#
9762# Three hypervisors hv[123].
9763# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9764# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9765# lp?3[123] all on hv3.
9766
9767# Given the name of a logical port, prints the name of the hypervisor
9768# on which it is located.
9769vif_to_hv() {
9770 case $1 in dnl (
9771 ?11) echo 1 ;; dnl (
9772 ?12 | ?21 | ?22) echo 2 ;; dnl (
9773 ?13 | ?23 | ?3?) echo 3 ;;
9774 esac
9775}
9776
9777# Given the name of a logical port, prints the name of its logical router
9778# port, e.g. "vif_to_lrp 123" yields 12.
9779vif_to_lrp() {
9780 echo ${1%?}
9781}
9782
9783# Given the name of a logical port, prints the name of its logical
9784# switch, e.g. "vif_to_ls 123" yields 1.
9785vif_to_ls() {
9786 echo ${1%??}
9787}
9788
9789net_add n1
9790for i in 1 2 3; do
9791 sim_add hv$i
9792 as hv$i
9793 ovs-vsctl add-br br-phys
9794 ovn_attach n1 br-phys 192.168.0.$i
9795done
9796for i in 1 2 3; do
9797 for j in 1 2 3; do
9798 for k in 1 2 3; do
9799 hv=`vif_to_hv $i$j$k`
9800 as hv$hv ovs-vsctl \
9801 -- add-port br-int vif$i$j$k \
9802 -- set Interface vif$i$j$k \
9803 external-ids:iface-id=lp$i$j$k \
9804 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
9805 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
9806 ofport-request=$i$j$k
9807 done
9808 done
9809done
9810
9811# Pre-populate the hypervisors' ARP tables so that we don't lose any
9812# packets for ARP resolution (native tunneling doesn't queue packets
9813# for ARP resolution).
9814OVN_POPULATE_ARP
9815
9816# Allow some time for ovn-northd and ovn-controller to catch up.
9817# XXX This should be more systematic.
9818sleep 1
9819
9820# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9821#
9822# This shell function causes a packet to be received on INPORT. The packet's
9823# content has Ethernet destination DST and source SRC (each exactly 12 hex
9824# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
9825# more) list the VIFs on which the packet should be received. INPORT and the
9826# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9827for i in 1 2 3; do
9828 for j in 1 2 3; do
9829 for k in 1 2 3; do
9830 : > $i$j$k.expected
9831 done
9832 done
9833done
9834test_ip() {
9835 # This packet has bad checksums but logical L3 routing doesn't check.
9836 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
9837 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9838 shift; shift; shift; shift; shift
9839 hv=hv`vif_to_hv $inport`
9840 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
9841 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
9842 in_ls=`vif_to_ls $inport`
9843 in_lrp=`vif_to_lrp $inport`
9844 for outport; do
9845 out_ls=`vif_to_ls $outport`
9846 if test $in_ls = $out_ls; then
9847 # Ports on the same logical switch receive exactly the same packet.
9848 echo $packet
9849 else
9850 # Routing decrements TTL and updates source and dest MAC
9851 # (and checksum).
9852 out_lrp=`vif_to_lrp $outport`
9853 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
9854 fi >> $outport.expected
9855 done
9856}
9857
9858as hv1 ovs-vsctl --columns=name,ofport list interface
9859as hv1 ovn-sbctl list port_binding
9860as hv1 ovn-sbctl list datapath_binding
9861as hv1 ovn-sbctl list port_group
9862as hv1 ovn-sbctl list address_set
9863as hv1 ovn-sbctl dump-flows
9864as hv1 ovs-ofctl dump-flows br-int
9865
9866# Send IP packets between all pairs of source and destination ports,
9867# packets matches ACL (pg2 to pg1) should be dropped
9868ip_to_hex() {
9869 printf "%02x%02x%02x%02x" "$@"
9870}
9871for is in 1 2 3; do
9872 for js in 1 2 3; do
9873 for ks in 1 2 3; do
9874 bcast=
9875 s=$is$js$ks
9876 smac=f00000000$s
9877 sip=`ip_to_hex 192 168 $is$js $ks`
9878 for id in 1 2 3; do
9879 for jd in 1 2 3; do
9880 for kd in 1 2 3; do
9881 d=$id$jd$kd
9882 dip=`ip_to_hex 192 168 $id$jd $kd`
9883 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
9884 if test $d != $s; then unicast=$d; else unicast=; fi
9885
9886 # packets matches ACL should be dropped
9887 if test $id != 3 && test $kd == 1; then
9888 if test $is != 1 && test $ks == 2; then
9889 unicast=
9890 fi
9891 fi
9892 test_ip $s $smac $dmac $sip $dip $unicast #1
9893 done
9894 done
9895 done
9896 done
9897 done
9898done
9899
9900# Allow some time for packet forwarding.
9901# XXX This can be improved.
9902sleep 1
9903
9904# Now check the packets actually received against the ones expected.
9905for i in 1 2 3; do
9906 for j in 1 2 3; do
9907 for k in 1 2 3; do
9908 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
9909 [$i$j$k.expected])
9910 done
9911 done
9912done
9913
9914# Gracefully terminate daemons
9915OVN_CLEANUP([hv1], [hv2], [hv3])
9916AT_CLEANUP
1beb60af
HZ
9917
9918AT_SETUP([ovn -- ACLs on Port Groups])
9919AT_KEYWORDS([ovnpg_acl])
9920AT_SKIP_IF([test $HAVE_PYTHON = no])
9921ovn_start
9922
9923# Logical network:
9924#
9925# Three logical switches ls1, ls2, ls3.
9926# One logical router lr0 connected to ls[123],
9927# with nine subnets, three per logical switch:
9928#
9929# lrp11 on ls1 for subnet 192.168.11.0/24
9930# lrp12 on ls1 for subnet 192.168.12.0/24
9931# lrp13 on ls1 for subnet 192.168.13.0/24
9932# ...
9933# lrp33 on ls3 for subnet 192.168.33.0/24
9934#
9935# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9936# digits are the subnet and the last digit distinguishes the VIF.
9937#
9938# This test will create two port groups and ACLs will be applied on them.
9939
9940get_lsp_uuid () {
9941 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9942}
9943
9944pg1_ports=
9945pg2_ports=
9946for i in 1 2 3; do
9947 ovn-nbctl ls-add ls$i
9948 for j in 1 2 3; do
9949 for k in 1 2 3; do
9950 ovn-nbctl \
9951 -- lsp-add ls$i lp$i$j$k \
9952 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
9953 192.168.$i$j.$k"
9954 # logical ports lp[12]?1 belongs to port group pg1
9955 if test $i != 3 && test $k == 1; then
9956 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9957 fi
9958 # logical ports lp[23]?2 belongs to port group pg2
9959 if test $i != 1 && test $k == 2; then
9960 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9961 fi
9962 done
9963 done
9964done
9965
9966ovn-nbctl lr-add lr0
9967for i in 1 2 3; do
9968 for j in 1 2 3; do
9969 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9970 ovn-nbctl \
9971 -- lsp-add ls$i lrp$i$j-attachment \
9972 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9973 options:router-port=lrp$i$j \
9974 addresses='"00:00:00:00:ff:'$i$j'"'
9975 done
9976done
9977
d87e0897 9978ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
1beb60af
HZ
9979ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9980
9981# create ACLs on pg1 to drop traffic from pg2 to pg1
d87e0897
HZ
9982ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
9983ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
9984 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
1beb60af
HZ
9985
9986# Physical network:
9987#
9988# Three hypervisors hv[123].
9989# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9990# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9991# lp?3[123] all on hv3.
9992
9993# Given the name of a logical port, prints the name of the hypervisor
9994# on which it is located.
9995vif_to_hv() {
9996 case $1 in dnl (
9997 ?11) echo 1 ;; dnl (
9998 ?12 | ?21 | ?22) echo 2 ;; dnl (
9999 ?13 | ?23 | ?3?) echo 3 ;;
10000 esac
10001}
10002
10003# Given the name of a logical port, prints the name of its logical router
10004# port, e.g. "vif_to_lrp 123" yields 12.
10005vif_to_lrp() {
10006 echo ${1%?}
10007}
10008
10009# Given the name of a logical port, prints the name of its logical
10010# switch, e.g. "vif_to_ls 123" yields 1.
10011vif_to_ls() {
10012 echo ${1%??}
10013}
10014
10015net_add n1
10016for i in 1 2 3; do
10017 sim_add hv$i
10018 as hv$i
10019 ovs-vsctl add-br br-phys
10020 ovn_attach n1 br-phys 192.168.0.$i
10021done
10022for i in 1 2 3; do
10023 for j in 1 2 3; do
10024 for k in 1 2 3; do
10025 hv=`vif_to_hv $i$j$k`
10026 as hv$hv ovs-vsctl \
10027 -- add-port br-int vif$i$j$k \
10028 -- set Interface vif$i$j$k \
10029 external-ids:iface-id=lp$i$j$k \
10030 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10031 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10032 ofport-request=$i$j$k
10033 done
10034 done
10035done
10036
10037# Pre-populate the hypervisors' ARP tables so that we don't lose any
10038# packets for ARP resolution (native tunneling doesn't queue packets
10039# for ARP resolution).
10040OVN_POPULATE_ARP
10041
10042# Allow some time for ovn-northd and ovn-controller to catch up.
10043# XXX This should be more systematic.
10044sleep 1
10045
10046# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10047#
10048# This shell function causes a packet to be received on INPORT. The packet's
10049# content has Ethernet destination DST and source SRC (each exactly 12 hex
10050# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
10051# more) list the VIFs on which the packet should be received. INPORT and the
10052# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
10053for i in 1 2 3; do
10054 for j in 1 2 3; do
10055 for k in 1 2 3; do
10056 : > $i$j$k.expected
10057 done
10058 done
10059done
10060test_ip() {
10061 # This packet has bad checksums but logical L3 routing doesn't check.
10062 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10063 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
10064 shift; shift; shift; shift; shift
10065 hv=hv`vif_to_hv $inport`
10066 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
10067 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
10068 in_ls=`vif_to_ls $inport`
10069 in_lrp=`vif_to_lrp $inport`
10070 for outport; do
10071 out_ls=`vif_to_ls $outport`
10072 if test $in_ls = $out_ls; then
10073 # Ports on the same logical switch receive exactly the same packet.
10074 echo $packet
10075 else
10076 # Routing decrements TTL and updates source and dest MAC
10077 # (and checksum).
10078 out_lrp=`vif_to_lrp $outport`
10079 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10080 fi >> $outport.expected
10081 done
10082}
10083
10084as hv1 ovs-vsctl --columns=name,ofport list interface
10085as hv1 ovn-sbctl list port_binding
10086as hv1 ovn-sbctl list datapath_binding
10087as hv1 ovn-sbctl list port_group
10088as hv1 ovn-sbctl list address_set
10089as hv1 ovn-sbctl dump-flows
10090as hv1 ovs-ofctl dump-flows br-int
10091
10092# Send IP packets between all pairs of source and destination ports,
10093# packets matches ACL1 but not ACL2 should be dropped
10094ip_to_hex() {
10095 printf "%02x%02x%02x%02x" "$@"
10096}
10097for is in 1 2 3; do
10098 for js in 1 2 3; do
10099 for ks in 1 2 3; do
10100 bcast=
10101 s=$is$js$ks
10102 smac=f00000000$s
10103 sip=`ip_to_hex 192 168 $is$js $ks`
10104 for id in 1 2 3; do
10105 for jd in 1 2 3; do
10106 for kd in 1 2 3; do
10107 d=$id$jd$kd
10108 dip=`ip_to_hex 192 168 $id$jd $kd`
10109 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10110 if test $d != $s; then unicast=$d; else unicast=; fi
10111
10112 # packets matches ACL1 but not ACL2 should be dropped
10113 if test $id != 3 && test $kd == 1; then
10114 if test $is == 1 || test $ks != 2; then
10115 unicast=
10116 fi
10117 fi
10118 test_ip $s $smac $dmac $sip $dip $unicast #1
10119 done
10120 done
10121 done
10122 done
10123 done
10124done
10125
10126# Allow some time for packet forwarding.
10127# XXX This can be improved.
10128sleep 1
10129
10130# Now check the packets actually received against the ones expected.
10131for i in 1 2 3; do
10132 for j in 1 2 3; do
10133 for k in 1 2 3; do
10134 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10135 [$i$j$k.expected])
10136 done
10137 done
10138done
10139
10140# Gracefully terminate daemons
10141OVN_CLEANUP([hv1], [hv2], [hv3])
10142AT_CLEANUP
55b25947
NS
10143
10144AT_SETUP([ovn -- ACL conjunction])
10145ovn_start
10146
10147ovn-nbctl ls-add ls1
10148
10149ovn-nbctl lsp-add ls1 ls1-lp1 \
10150-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10151
10152ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10153
10154ovn-nbctl lsp-add ls1 ls1-lp2 \
10155-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10156
10157ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10158
10159net_add n1
10160sim_add hv1
10161
10162as hv1
10163ovs-vsctl add-br br-phys
10164ovn_attach n1 br-phys 192.168.0.1
10165ovs-vsctl -- add-port br-int hv1-vif1 -- \
10166 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
10167 options:tx_pcap=hv1/vif1-tx.pcap \
10168 options:rxq_pcap=hv1/vif1-rx.pcap \
10169 ofport-request=1
10170
10171ovs-vsctl -- add-port br-int hv1-vif2 -- \
10172 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
10173 options:tx_pcap=hv1/vif2-tx.pcap \
10174 options:rxq_pcap=hv1/vif2-rx.pcap \
10175 ofport-request=2
10176
10177ovn-nbctl create Address_Set name=set1 \
10178addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
10179ovn-nbctl create Address_Set name=set2 \
10180addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
10181ovn-nbctl acl-add ls1 to-lport 1002 \
10182'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
10183ovn-nbctl acl-add ls1 to-lport 1001 \
10184'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
10185
10186# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10187#
10188# This shell function causes an ip packet to be received on INPORT.
10189# The packet's content has Ethernet destination DST and source SRC
10190# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
10191# The OUTPORTs (zero or more) list the VIFs on which the packet should
10192# be received. INPORT and the OUTPORTs are specified as logical switch
10193# port numbers, e.g. 11 for vif11.
10194test_ip() {
10195 # This packet has bad checksums but logical L3 routing doesn't check.
10196 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10197 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
10198${dst_ip}0035111100080000
10199 shift; shift; shift; shift; shift
10200 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
10201 for outport; do
10202 echo $packet >> $outport.expected
10203 done
10204}
10205
10206ip_to_hex() {
10207 printf "%02x%02x%02x%02x" "$@"
10208}
10209
10210reset_pcap_file() {
10211 local iface=$1
10212 local pcap_file=$2
10213 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10214options:rxq_pcap=dummy-rx.pcap
10215 rm -f ${pcap_file}*.pcap
10216 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10217options:rxq_pcap=${pcap_file}-rx.pcap
10218}
10219
10220
10221sip=`ip_to_hex 10 0 0 4`
10222dip=`ip_to_hex 10 0 0 6`
10223
10224test_ip 1 f00000000001 f00000000002 $sip $dip 2
10225
10226cat 2.expected > expout
10227$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10228AT_CHECK([cat 2.packets], [0], [expout])
10229
10230# There should be total of 12 flows present with conjunction action and 2 flows
10231# with conj match. Eg.
10232# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
10233# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
10234# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
10235# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
10236# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
10237# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
10238# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
10239# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
10240# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
10241# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
10242# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
10243# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
10244# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
10245# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
10246
10247OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
10248grep conjunction | wc -l`])
10249OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
10250grep conj_id | wc -l`])
10251
10252as hv1 ovs-ofctl dump-flows br-int
10253
10254# Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
10255ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10256ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10257
10258reset_pcap_file hv1-vif2 hv1/vif2
10259
10260rm -f 2.packets
10261
10262sip=`ip_to_hex 10 0 0 4`
10263dip=`ip_to_hex 10 0 0 7`
10264
10265test_ip 1 f00000000001 f00000000002 $sip $dip
10266$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10267AT_CHECK([cat 2.packets], [0], [])
10268
10269AT_CLEANUP