]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
ovn-northd: LR respond ARP from valid subnet only.
[ovs.git] / tests / ovn.at
CommitLineData
49d7c759
BP
1# OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2#
3# This compares packets read from PCAP, in pcap format, to those read
4# from EXPECTED, which is a text file containing packets as hex
5# strings, one per line. If PCAP contains fewer packets than
6# EXPECTED, it waits up to 10 seconds for more packets to appear.
7#
8# The implementation is an m4 macro that is mostly implemented in
9# terms of a shell function. This reduces the size of the generated
10# testsuite file since the shell function is only emitted once even
11# when this macro is invoked many times.
12m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
20 ovs_wait_cond () {
abb37b6b
FF
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
49d7c759
BP
24 }
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
26
e4543cfe 27 sort $exp_text > expout
49d7c759
BP
28 }
29])
30m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
33
f295c17b 34AT_BANNER([OVN components])
10b1662b
BP
35
36AT_SETUP([ovn -- lexer])
37dnl For lines without =>, input and expected output are identical.
38dnl For lines with =>, input precedes => and expected output follows =>.
39AT_DATA([test-cases.txt], [dnl
40foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41"abc\u0020def" => "abc def"
42" => error("Input ends inside quoted string.")dnl "
43
2c5cbb15
RB
44$foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45$1 => error("`$' must be followed by a valid identifier.") 1
46
10b1662b
BP
47a/*b*/c => a c
48a//b c => a
49a/**/b => a b
50a/*/b => a error("`/*' without matching `*/'.")
51a/*/**/b => a b
52a/b => a error("`/' is only valid as part of `//' or `/*'.") b
53
540 1 12345 18446744073709551615
5518446744073709551616 => error("Decimal constants must be less than 2**64.")
569999999999999999999999 => error("Decimal constants must be less than 2**64.")
5701 => error("Decimal constants must not have leading zeros.")
58
590/0
600/1
611/0 => error("Value contains unmasked 1-bits.")
621/1
63128/384
641/3
651/ => error("Integer constant expected.")
66
671/0x123 => error("Value and mask have incompatible formats.")
68
690x1234
700x01234 => 0x1234
710x0 => 0
720x000 => 0
730xfedcba9876543210
740XFEDCBA9876543210 => 0xfedcba9876543210
750xfedcba9876543210fedcba9876543210
10b1662b
BP
760x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
770x => error("Hex digits expected following 0x.")
780X => error("Hex digits expected following 0X.")
790x0/0x0 => 0/0
800x0/0x1 => 0/0x1
810x1/0x0 => error("Value contains unmasked 1-bits.")
820xffff/0x1ffff
830x. => error("Invalid syntax in hexadecimal constant.")
84
85192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86256.1.2.3 => error("Invalid numeric constant.")
87192.168.0.0/16
88192.168.0.0/255.255.0.0 => 192.168.0.0/16
89192.168.0.0/255.255.255.0 => 192.168.0.0/24
90192.168.0.0/255.255.0.255
91192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
92192.168.0.0/32
93192.168.0.0/255.255.255.255 => 192.168.0.0/32
52c0fc39 941.2.3.4:5 => 1.2.3.4 : 5
10b1662b
BP
95
96::
97::1
98ff00::1234 => ff00::1234
992001:db8:85a3::8a2e:370:7334
1002001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
1012001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
102::ffff:192.0.2.128
103::ffff:c000:0280 => ::ffff:192.0.2.128
104::1/::1
105::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
106::1/128
107ff00::/8
108ff00::/ff00:: => ff00::/8
109
11001:23:45:67:ab:cd
11101:23:45:67:AB:CD => 01:23:45:67:ab:cd
112fe:dc:ba:98:76:54
113FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
11401:00:00:00:00:00/01:00:00:00:00:00
115ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118fe:x => error("Invalid numeric constant.")
11900:01:02:03:04:x => error("Invalid numeric constant.")
120
a20c96c6 121# Test that operators are tokenized as expected, even without white space.
52c0fc39 122(){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
10b1662b
BP
123& => error("`&' is only valid as part of `&&'.")
124| => error("`|' is only valid as part of `||'.")
56091efe 125- => error("`-' is only valid as part of `--'.")
10b1662b
BP
126
127^ => error("Invalid character `^' in input.")
128])
129AT_CAPTURE_FILE([input.txt])
130sed 's/ =>.*//' test-cases.txt > input.txt
131sed 's/.* => //' test-cases.txt > expout
132AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
133AT_CLEANUP
e0840f11 134
7700eea0
BP
135dnl The OVN expression parser needs to know what fields overlap with one
136dnl another. This test therefore verifies that all the smaller registers
137dnl are defined as terms of subfields of the larger ones.
138dnl
139dnl When we add or remove registers this test needs to be updated, of course.
140AT_SETUP([ovn -- registers])
141AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142[[reg0 = xxreg0[96..127]
143reg1 = xxreg0[64..95]
144reg2 = xxreg0[32..63]
145reg3 = xxreg0[0..31]
146reg4 = xxreg1[96..127]
147reg5 = xxreg1[64..95]
148reg6 = xxreg1[32..63]
149reg7 = xxreg1[0..31]
150reg8 = xreg4[32..63]
151reg9 = xreg4[0..31]
152xreg0 = xxreg0[64..127]
153xreg1 = xxreg0[0..63]
154xreg2 = xxreg1[64..127]
155xreg3 = xxreg1[0..63]
156xreg4 = OXM_OF_PKT_REG4
157xxreg0 = NXM_NX_XXREG0
158xxreg1 = NXM_NX_XXREG1
159]])
160AT_CLEANUP
161
2277b860
BP
162dnl Check that the OVN conntrack field definitions are correct.
163AT_SETUP([ovn -- conntrack fields])
164AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
858c2f76
GS
165[[ct.dnat = ct_state[7]
166ct.est = ct_state[1]
2277b860
BP
167ct.inv = ct_state[4]
168ct.new = ct_state[0]
169ct.rel = ct_state[2]
170ct.rpl = ct_state[3]
858c2f76 171ct.snat = ct_state[6]
2277b860
BP
172ct.trk = ct_state[5]
173ct_label = NXM_NX_CT_LABEL
b73db61d 174ct_label.blocked = ct_label[0]
2277b860
BP
175ct_mark = NXM_NX_CT_MARK
176ct_state = NXM_NX_CT_STATE
177]])
178AT_CLEANUP
179
fb8635c5 180AT_SETUP([ovn -- composition])
42d36b58
AZ
181AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
182AT_CLEANUP
183
e0840f11
BP
184AT_SETUP([ovn -- expression parser])
185dnl For lines without =>, input and expected output are identical.
186dnl For lines with =>, input precedes => and expected output follows =>.
187AT_DATA([test-cases.txt], [[
188eth.type == 0x800
189eth.type==0x800 => eth.type == 0x800
190eth.type[0..15] == 0x800 => eth.type == 0x800
191
192vlan.present
193vlan.present == 1 => vlan.present
194!(vlan.present == 0) => vlan.present
195!(vlan.present != 1) => vlan.present
196!vlan.present
197vlan.present == 0 => !vlan.present
198vlan.present != 1 => !vlan.present
199!(vlan.present == 1) => !vlan.present
200!(vlan.present != 0) => !vlan.present
201
202eth.dst[0]
203eth.dst[0] == 1 => eth.dst[0]
204eth.dst[0] != 0 => eth.dst[0]
205!(eth.dst[0] == 0) => eth.dst[0]
206!(eth.dst[0] != 1) => eth.dst[0]
207
208!eth.dst[0]
209eth.dst[0] == 0 => !eth.dst[0]
210eth.dst[0] != 1 => !eth.dst[0]
211!(eth.dst[0] == 1) => !eth.dst[0]
212!(eth.dst[0] != 0) => !eth.dst[0]
213
214vlan.tci[12..15] == 0x3
215vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
216vlan.tci[12..15] != 0x3
217vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
218
219!vlan.pcp => vlan.pcp == 0
220!(vlan.pcp) => vlan.pcp == 0
221vlan.pcp == 0x4
222vlan.pcp != 0x4
223vlan.pcp > 0x4
224vlan.pcp >= 0x4
225vlan.pcp < 0x4
226vlan.pcp <= 0x4
227!(vlan.pcp != 0x4) => vlan.pcp == 0x4
228!(vlan.pcp == 0x4) => vlan.pcp != 0x4
229!(vlan.pcp <= 0x4) => vlan.pcp > 0x4
230!(vlan.pcp < 0x4) => vlan.pcp >= 0x4
231!(vlan.pcp >= 0x4) => vlan.pcp < 0x4
232!(vlan.pcp > 0x4) => vlan.pcp <= 0x4
2330x4 == vlan.pcp => vlan.pcp == 0x4
2340x4 != vlan.pcp => vlan.pcp != 0x4
2350x4 < vlan.pcp => vlan.pcp > 0x4
2360x4 <= vlan.pcp => vlan.pcp >= 0x4
2370x4 > vlan.pcp => vlan.pcp < 0x4
2380x4 >= vlan.pcp => vlan.pcp <= 0x4
239!(0x4 != vlan.pcp) => vlan.pcp == 0x4
240!(0x4 == vlan.pcp) => vlan.pcp != 0x4
241!(0x4 >= vlan.pcp) => vlan.pcp > 0x4
242!(0x4 > vlan.pcp) => vlan.pcp >= 0x4
243!(0x4 <= vlan.pcp) => vlan.pcp < 0x4
244!(0x4 < vlan.pcp) => vlan.pcp <= 0x4
245
2461 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
2471 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2481 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
2491 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
2501 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2514 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
2524 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
2534 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
2544 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
255!(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
256!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
257!(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
258!(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
259!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
260!(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
261!(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
262!(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
263!(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
264
265vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
267
268vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
269vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
270
271vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
272vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
273vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
274
275ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
276ip6.src == ::1 => ip6.src == 0x1
277
278ip4.src == 1.2.3.4 => ip4.src == 0x1020304
279ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
280ip6.src == ::1 => ip6.src == 0x1
281
2821
2830
284!1 => 0
285!0 => 1
286
287inport == "eth0"
288!(inport != "eth0") => inport == "eth0"
289
3b7cb7e1
BP
290ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
291inport == 1 => String field inport is not compatible with integer constant.
76da94b5 292ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
e0840f11
BP
293
294ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
295eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
296vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
297
298inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
299!(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
300eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
301!(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
76da94b5 302inport = "eth0" => Syntax error at `=' expecting relational operator.
e0840f11
BP
303
304123 == 123 => Syntax error at `123' expecting field name.
305
2c5cbb15 306$name => Syntax error at `$name' expecting address set name.
3d2848ba 307@name => Syntax error at `@name' expecting port group name.
2c5cbb15 308
e0840f11
BP
309123 == xyzzy => Syntax error at `xyzzy' expecting field name.
310xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311
312inport[1] == 1 => Cannot select subfield of string field inport.
313
314eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
315eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
316eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317
318eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319
320eth.type[5..1] => Invalid bit range 5 to 1.
321
322eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323
324eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325
326eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327
328!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329
330123 => Syntax error at end of input expecting relational operator.
331
332123 x => Syntax error at `x' expecting relational operator.
333
334{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335
336eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337
338(1 x) => Syntax error at `x' expecting `)'.
339
340!0x800 != eth.type => Missing parentheses around operand of !.
341
342eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343
344eth.dst == {} => Syntax error at `}' expecting constant.
345
346eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff => Only == and != operators may be used with masked constants. Consider using subfields instead (e.g. eth.src[0..15] > 0x1111 in place of eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).
347
3b7cb7e1 348ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
e0840f11
BP
349
3501 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
8b34ccda 351
9aef3c1b 352eth.dst[40] x => Syntax error at `x' expecting end of input.
ea382567
RB
353
354ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
355eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
e0840f11
BP
356]])
357sed 's/ =>.*//' test-cases.txt > input.txt
358sed 's/.* => //' test-cases.txt > expout
359AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
360AT_CLEANUP
361
362AT_SETUP([ovn -- expression annotation])
363dnl Input precedes =>, expected output follows =>.
32157c87 364dnl Empty lines and lines starting with # are ignored.
e0840f11
BP
365AT_DATA([test-cases.txt], [[
366ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
367ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
368ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
32157c87 369ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
e0840f11
BP
370ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
371
32157c87
JS
372# Nested expressions over a single symbol should be annotated with symbol's
373# prerequisites only once, at the top level.
374tcp.dst == 1 || (tcp.dst >= 2 && tcp.dst <= 3) => (tcp.dst == 0x1 || (tcp.dst >= 0x2 && tcp.dst <= 0x3)) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
375
e0840f11
BP
376ip => eth.type == 0x800 || eth.type == 0x86dd
377ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
378ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
379ip > 0 => Only == and != operators may be used with nominal field ip.
380!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
381ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
382
383vlan.present => vlan.tci[12]
384!vlan.present => !vlan.tci[12]
385
386!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
387vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
7700eea0 388!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
e0840f11
BP
389
390ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
391!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
392ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
393
394bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
395self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
396mutual_recurse_1 != 0 => Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_1'.
397mutual_recurse_2 != 0 => Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_2'.
398]])
399sed 's/ =>.*//' test-cases.txt > input.txt
400sed 's/.* => //' test-cases.txt > expout
401AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
402AT_CLEANUP
403
9d4aecca 404AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 405AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 406 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
407])
408AT_CLEANUP
409
9d4aecca 410AT_SETUP([ovn -- 2-term expression conversion])
e0840f11 411AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
8c3caa2c 412 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
413])
414AT_CLEANUP
415
9d4aecca 416AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 417AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
8c3caa2c 418 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
419])
420AT_CLEANUP
421
9d4aecca
BP
422AT_SETUP([ovn -- 3-term numeric expression simplification])
423AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
8c3caa2c 424 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
425])
426AT_CLEANUP
427
9d4aecca
BP
428AT_SETUP([ovn -- 4-term string expression simplification])
429AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
430 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
431])
432AT_CLEANUP
433
9d4aecca
BP
434AT_SETUP([ovn -- 3-term mixed expression simplification])
435AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
8c3caa2c 436 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
437])
438AT_CLEANUP
439
97ba1d55
BP
440AT_SETUP([ovn -- simplification special cases])
441simplify() {
442 echo "$1" | ovstest test-ovn simplify-expr
443}
444AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
445])
a3d79068
BP
446AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
447])
33f15d17
BP
448AT_CHECK([simplify 'tcp.dst >= 0'], [0],
449 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
450])
451AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
452 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
453])
454AT_CHECK([simplify 'tcp.dst > 0'], [0],
455 [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
456]])
457AT_CHECK([simplify 'tcp.dst < 65535'], [0],
458 [[(!tcp.dst[0] || !tcp.dst[1] || !tcp.dst[2] || !tcp.dst[3] || !tcp.dst[4] || !tcp.dst[5] || !tcp.dst[6] || !tcp.dst[7] || !tcp.dst[8] || !tcp.dst[9] || !tcp.dst[10] || !tcp.dst[11] || !tcp.dst[12] || !tcp.dst[13] || !tcp.dst[14] || !tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
459]])
97ba1d55
BP
460AT_CLEANUP
461
ba8d3816
MS
462AT_SETUP([ovn -- is_chassis_resident simplification])
463simplify() {
464 echo "$1" | ovstest test-ovn simplify-expr
465}
466AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
467])
468AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
469])
470AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
471])
472AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
473])
474AT_CLEANUP
475
9d4aecca
BP
476AT_SETUP([ovn -- 4-term numeric expression normalization])
477AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
8c3caa2c 478 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
479])
480AT_CLEANUP
481
9d4aecca
BP
482AT_SETUP([ovn -- 4-term string expression normalization])
483AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
484 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
485])
486AT_CLEANUP
487
488AT_SETUP([ovn -- 4-term mixed expression normalization])
489AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
8c3caa2c 490 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
9d4aecca
BP
491])
492AT_CLEANUP
493
494AT_SETUP([ovn -- 5-term numeric expression normalization])
495AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
8c3caa2c 496 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
9d4aecca
BP
497])
498AT_CLEANUP
499
500AT_SETUP([ovn -- 5-term string expression normalization])
501AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
503])
504AT_CLEANUP
505
506AT_SETUP([ovn -- 5-term mixed expression normalization])
507AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
8c3caa2c 508 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
509])
510AT_CLEANUP
511
512AT_SETUP([ovn -- 4-term numeric expressions to flows])
8c3caa2c 513AT_KEYWORDS([expression])
9d4aecca 514AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
8c3caa2c 515 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
9d4aecca
BP
516])
517AT_CLEANUP
518
519AT_SETUP([ovn -- 4-term string expressions to flows])
8c3caa2c 520AT_KEYWORDS([expression])
9d4aecca
BP
521AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
522 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
523])
524AT_CLEANUP
525
526AT_SETUP([ovn -- 4-term mixed expressions to flows])
8c3caa2c 527AT_KEYWORDS([expression])
9d4aecca 528AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
8c3caa2c 529 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
530])
531AT_CLEANUP
532
533AT_SETUP([ovn -- 3-term numeric expressions to flows])
8c3caa2c 534AT_KEYWORDS([expression])
9d4aecca 535AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
8c3caa2c 536 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
537])
538AT_CLEANUP
f386a8a7
BP
539
540AT_SETUP([ovn -- converting expressions to flows -- string fields])
8c3caa2c 541AT_KEYWORDS([expression])
f386a8a7
BP
542expr_to_flow () {
543 echo "$1" | ovstest test-ovn expr-to-flows | sort
544}
cc5e28d8 545AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 546])
cc5e28d8 547AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
548])
549AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
550])
551AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
552ip,reg14=0x5
553ipv6,reg14=0x5
f386a8a7
BP
554])
555AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
556ip,reg14=0x6
557ipv6,reg14=0x6
f386a8a7
BP
558])
559AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
560])
561AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
562[reg14=0x5
563reg14=0x6
564reg14=0xfffe
f386a8a7
BP
565])
566AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
567ip,reg14=0x5
568ip,reg14=0x6
569ipv6,reg14=0x5
570ipv6,reg14=0x6
f386a8a7 571])
9d4aecca
BP
572AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
573(no flows)
574])
f386a8a7 575AT_CLEANUP
3b7cb7e1 576
2c5cbb15 577AT_SETUP([ovn -- converting expressions to flows -- address sets])
8c3caa2c 578AT_KEYWORDS([expression])
2c5cbb15
RB
579expr_to_flow () {
580 echo "$1" | ovstest test-ovn expr-to-flows | sort
581}
582AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
583ip,nw_src=10.0.0.1
584ip,nw_src=10.0.0.2
585ip,nw_src=10.0.0.3
586])
587AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
588ip,nw_src=10.0.0.1
589ip,nw_src=10.0.0.2
590ip,nw_src=10.0.0.3
591])
592AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
593ip,nw_src=1.2.3.4
594ip,nw_src=10.0.0.1
595ip,nw_src=10.0.0.2
596ip,nw_src=10.0.0.3
597])
598AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
599ip,nw_src=1.2.0.0/20
600ip,nw_src=10.0.0.1
601ip,nw_src=10.0.0.2
602ip,nw_src=10.0.0.3
603ip,nw_src=5.5.5.0/24
604])
605AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
606ipv6,ipv6_src=::1
607ipv6,ipv6_src=::2
608ipv6,ipv6_src=::3
609])
610AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
611ipv6,ipv6_src=::1
612ipv6,ipv6_src=::2
613ipv6,ipv6_src=::3
614ipv6,ipv6_src=::4
615])
616AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, 00:00:00:00:00:02, 00:00:00:00:00:03}'], [0], [dnl
617dl_src=00:00:00:00:00:01
618dl_src=00:00:00:00:00:02
619dl_src=00:00:00:00:00:03
620])
621AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
622dl_src=00:00:00:00:00:01
623dl_src=00:00:00:00:00:02
624dl_src=00:00:00:00:00:03
625])
ea382567
RB
626AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
627dl_src=00:00:00:00:00:01
628dl_src=00:00:00:00:00:02
629dl_src=00:00:00:00:00:03
630dl_src=ba:be:be:ef:de:ad
631])
f3a4e992
HZ
632AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
633(no flows)
634])
635AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
636ip,nw_src=1.2.3.4
637])
638AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
639ip,nw_src=1.2.3.4
640])
641AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
642
643])
644AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
645ip,nw_src=0.0.0.0/1.0.0.0
646ip,nw_src=128.0.0.0/1
647ip,nw_src=16.0.0.0/16.0.0.0
648ip,nw_src=2.0.0.0/2.0.0.0
649ip,nw_src=32.0.0.0/32.0.0.0
650ip,nw_src=4.0.0.0/4.0.0.0
651ip,nw_src=64.0.0.0/64.0.0.0
652ip,nw_src=8.0.0.0/8.0.0.0
653])
654AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
655ip,nw_src=0.0.0.0/1.0.0.0
656ip,nw_src=128.0.0.0/1
657ip,nw_src=16.0.0.0/16.0.0.0
658ip,nw_src=2.0.0.0/2.0.0.0
659ip,nw_src=32.0.0.0/32.0.0.0
660ip,nw_src=4.0.0.0/4.0.0.0
661ip,nw_src=64.0.0.0/64.0.0.0
662ip,nw_src=8.0.0.0/8.0.0.0
663])
2c5cbb15
RB
664AT_CLEANUP
665
3d2848ba
HZ
666AT_SETUP([ovn -- converting expressions to flows -- port groups])
667AT_KEYWORDS([expression])
668expr_to_flow () {
669 echo "$1" | ovstest test-ovn expr-to-flows | sort
670}
671AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
672reg15=0x11
673reg15=0x12
674reg15=0x13
675])
676AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
677(no flows)
678])
679AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
680reg15=0x11
681])
682AT_CLEANUP
683
55b25947
NS
684AT_SETUP([ovn -- converting expressions to flows -- conjunction])
685AT_KEYWORDS([conjunction])
686expr_to_flow () {
687 echo "$1" | ovstest test-ovn expr-to-flows | sort
688}
689
690lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
691ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
692AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
693conj_id=1,ip
694ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
695ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
696ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
697ip,nw_src=10.0.0.1: conjunction(1, 1/2)
698ip,nw_src=10.0.0.2: conjunction(1, 1/2)
699ip,nw_src=10.0.0.3: conjunction(1, 1/2)
700])
701
702lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
703AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
704ct_state=+est+trk,ct_label=0x1/0x1,ip
705ct_state=+est+trk,ct_label=0x1/0x1,ipv6
706ct_state=-est+trk,ip
707ct_state=-est+trk,ipv6
708])
709
710lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
711ip4.dst == {20.0.0.1, 20.0.0.2}"
712AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
713conj_id=1,ip
714ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
715ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
716ip,nw_src=10.0.0.1: conjunction(1, 1/2)
717ip,nw_src=10.0.0.2: conjunction(1, 1/2)
718ip,nw_src=10.0.0.3: conjunction(1, 1/2)
719])
720
721lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
722ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
723tcp.dst >= 1000 && tcp.dst <= 1010"
724
725AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
726conj_id=1,tcp
727tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
728tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
729tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
730tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
731tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
732tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
733tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
734tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
735tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
736tcp,tp_dst=1000: conjunction(1, 2/3)
737tcp,tp_dst=1001: conjunction(1, 2/3)
738tcp,tp_dst=1010: conjunction(1, 2/3)
739])
740
741lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
742((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
743tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
744|| ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
745
746AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
747conj_id=1,tcp
748ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
749ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
750ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
751ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
752ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
753ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
754tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
755tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
756tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
757tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
758tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
759tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
760tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
761tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
762tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
763tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
764tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
765tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
766tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
767tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
768tcp,tp_dst=1000: conjunction(1, 2/4)
769tcp,tp_dst=1001: conjunction(1, 2/4)
770tcp,tp_dst=2000: conjunction(1, 2/4)
771tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
772tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
773tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
774tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
775tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
776tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
777tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
778tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
779tcp,tp_src=1000: conjunction(1, 3/4)
780tcp,tp_src=1001: conjunction(1, 3/4)
781tcp,tp_src=2000: conjunction(1, 3/4)
782])
783AT_CLEANUP
784
3b7cb7e1 785AT_SETUP([ovn -- action parsing])
d5a76da4
BP
786dnl Unindented text is input (a set of OVN logical actions).
787dnl Indented text is expected output.
788AT_DATA([test-cases.txt],
789[[# drop
790drop;
791 encodes as drop
792drop; next;
793 Syntax error at `next' expecting end of input.
794next; drop;
795 Syntax error at `drop' expecting action.
5f822129
BP
796
797# output
d5a76da4
BP
798output;
799 encodes as resubmit(,64)
5f822129
BP
800
801# next
d5a76da4 802next;
00c875d0 803 encodes as resubmit(,19)
d5a76da4 804next(11);
8f5de083 805 formats as next;
00c875d0 806 encodes as resubmit(,19)
d5a76da4 807next(0);
00c875d0
MS
808 encodes as resubmit(,8)
809next(23);
d5a76da4
BP
810 encodes as resubmit(,31)
811
812next();
4c99cb18 813 Syntax error at `)' expecting "pipeline" or "table".
d5a76da4
BP
814next(10;
815 Syntax error at `;' expecting `)'.
00c875d0
MS
816next(24);
817 "next" action cannot advance beyond table 23.
5f822129 818
4c99cb18
BP
819next(table=11);
820 formats as next;
00c875d0 821 encodes as resubmit(,19)
4c99cb18
BP
822next(pipeline=ingress);
823 formats as next;
00c875d0 824 encodes as resubmit(,19)
4c99cb18
BP
825next(table=11, pipeline=ingress);
826 formats as next;
00c875d0 827 encodes as resubmit(,19)
4c99cb18
BP
828next(pipeline=ingress, table=11);
829 formats as next;
00c875d0 830 encodes as resubmit(,19)
4c99cb18
BP
831
832next(pipeline=egress);
833 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
834
835next(table=10);
836 formats as next(10);
00c875d0 837 encodes as resubmit(,18)
4c99cb18 838
5f822129 839# Loading a constant value.
d5a76da4
BP
840tcp.dst=80;
841 formats as tcp.dst = 80;
842 encodes as set_field:80->tcp_dst
843 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
844eth.dst[40] = 1;
845 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
846vlan.pcp = 2;
847 encodes as set_field:0x4000/0xe000->vlan_tci
848 has prereqs vlan.tci[12]
849vlan.tci[13..15] = 2;
850 encodes as set_field:0x4000/0xe000->vlan_tci
851inport = "";
852 encodes as set_field:0->reg14
853ip.ttl=4;
854 formats as ip.ttl = 4;
855 encodes as set_field:4->nw_ttl
856 has prereqs eth.type == 0x800 || eth.type == 0x86dd
857outport="eth0"; next; outport="LOCAL"; next;
8f5de083 858 formats as outport = "eth0"; next; outport = "LOCAL"; next;
00c875d0 859 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
d5a76da4
BP
860
861inport[1] = 1;
862 Cannot select subfield of string field inport.
863ip.proto[1] = 1;
864 Cannot select subfield of nominal field ip.proto.
865eth.dst[40] == 1;
866 Syntax error at `==' expecting `=' or `<->'.
867ip = 1;
868 Predicate symbol ip used where lvalue required.
869ip.proto = 6;
870 Field ip.proto is not modifiable.
871inport = {"a", "b"};
872 Syntax error at `{' expecting constant.
873inport = {};
874 Syntax error at `{' expecting constant.
875bad_prereq = 123;
876 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
877self_recurse = 123;
878 Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
879vlan.present = 0;
880 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
881
882# Moving one field into another.
d5a76da4
BP
883reg0=reg1;
884 formats as reg0 = reg1;
885 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
886vlan.pcp = reg0[0..2];
887 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
888 has prereqs vlan.tci[12]
889reg0[10] = vlan.pcp[1];
890 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
891 has prereqs vlan.tci[12]
892outport = inport;
893 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
894
895reg0[0] = vlan.present;
896 Predicate symbol vlan.present used where lvalue required.
897reg0 = reg1[0..10];
898 Can't assign 11-bit value to 32-bit destination.
899inport = reg0;
900 Can't assign integer field (reg0) to string field (inport).
901inport = big_string;
902 String fields inport and big_string are incompatible for assignment.
903ip.proto = reg0[0..7];
904 Field ip.proto is not modifiable.
5f822129
BP
905
906# Exchanging fields.
d5a76da4
BP
907reg0 <-> reg1;
908 encodes as push:NXM_NX_XXREG0[64..95],push:NXM_NX_XXREG0[96..127],pop:NXM_NX_XXREG0[64..95],pop:NXM_NX_XXREG0[96..127]
909vlan.pcp <-> reg0[0..2];
910 encodes as push:NXM_NX_XXREG0[96..98],push:NXM_OF_VLAN_TCI[13..15],pop:NXM_NX_XXREG0[96..98],pop:NXM_OF_VLAN_TCI[13..15]
911 has prereqs vlan.tci[12]
912reg0[10] <-> vlan.pcp[1];
913 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
914 has prereqs vlan.tci[12]
915outport <-> inport;
916 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
917
918reg0[0] <-> vlan.present;
919 Predicate symbol vlan.present used where lvalue required.
920reg0 <-> reg1[0..10];
921 Can't exchange 32-bit field with 11-bit field.
922inport <-> reg0;
923 Can't exchange string field (inport) with integer field (reg0).
924inport <-> big_string;
925 String fields inport and big_string are incompatible for exchange.
926ip.proto <-> reg0[0..7];
927 Field ip.proto is not modifiable.
928reg0[0..7] <-> ip.proto;
929 Field ip.proto is not modifiable.
5f822129
BP
930
931# TTL decrement.
d5a76da4
BP
932ip.ttl--;
933 encodes as dec_ttl
934 has prereqs ip
935ip.ttl
936 Syntax error at end of input expecting `--'.
5f822129 937
467085fd 938# load balancing.
d5a76da4 939ct_lb;
00c875d0 940 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
941 has prereqs ip
942ct_lb();
943 formats as ct_lb;
00c875d0 944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
945 has prereqs ip
946ct_lb(192.168.1.2:80, 192.168.1.3:80);
947 encodes as group:1
948 has prereqs ip
949ct_lb(192.168.1.2, 192.168.1.3, );
950 formats as ct_lb(192.168.1.2, 192.168.1.3);
951 encodes as group:2
952 has prereqs ip
9d236afa
MM
953ct_lb(fd0f::2, fd0f::3, );
954 formats as ct_lb(fd0f::2, fd0f::3);
955 encodes as group:3
956 has prereqs ip
d5a76da4
BP
957
958ct_lb(192.168.1.2:);
959 Syntax error at `)' expecting port number.
960ct_lb(192.168.1.2:123456);
961 Syntax error at `123456' expecting port number.
962ct_lb(foo);
9d236afa
MM
963 Syntax error at `foo' expecting IP address.
964ct_lb([192.168.1.2]);
965 Syntax error at `192.168.1.2' expecting IPv6 address.
d5a76da4
BP
966
967# ct_next
968ct_next;
00c875d0 969 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
d5a76da4
BP
970 has prereqs ip
971
972# ct_commit
973ct_commit;
974 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
975 has prereqs ip
976ct_commit();
977 formats as ct_commit;
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
979 has prereqs ip
980ct_commit(ct_mark=1);
981 formats as ct_commit(ct_mark=0x1);
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
983 has prereqs ip
984ct_commit(ct_mark=1/1);
985 formats as ct_commit(ct_mark=0x1/0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
987 has prereqs ip
988ct_commit(ct_label=1);
989 formats as ct_commit(ct_label=0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
991 has prereqs ip
992ct_commit(ct_label=1/1);
993 formats as ct_commit(ct_label=0x1/0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
995 has prereqs ip
996ct_commit(ct_mark=1, ct_label=2);
997 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
999 has prereqs ip
1000
1001ct_commit(ct_label=0x01020304050607080910111213141516);
1002 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1003 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1004 has prereqs ip
1005ct_commit(ct_label=0x181716151413121110090807060504030201);
1006 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1008 has prereqs ip
1009ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1010 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1011 has prereqs ip
1012ct_commit(ct_label=18446744073709551615);
1013 formats as ct_commit(ct_label=0xffffffffffffffff);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1015 has prereqs ip
1016ct_commit(ct_label=18446744073709551616);
1017 Decimal constants must be less than 2**64.
1018
1019# ct_dnat
1020ct_dnat;
00c875d0 1021 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
d5a76da4
BP
1022 has prereqs ip
1023ct_dnat(192.168.1.2);
00c875d0 1024 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
d5a76da4
BP
1025 has prereqs ip
1026
1027ct_dnat(192.168.1.2, 192.168.1.3);
1028 Syntax error at `,' expecting `)'.
1029ct_dnat(foo);
1030 Syntax error at `foo' expecting IPv4 address.
1031ct_dnat(foo, bar);
1032 Syntax error at `foo' expecting IPv4 address.
1033ct_dnat();
1034 Syntax error at `)' expecting IPv4 address.
1035
1036# ct_snat
1037ct_snat;
00c875d0 1038 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
d5a76da4
BP
1039 has prereqs ip
1040ct_snat(192.168.1.2);
00c875d0 1041 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
d5a76da4
BP
1042 has prereqs ip
1043
1044ct_snat(192.168.1.2, 192.168.1.3);
1045 Syntax error at `,' expecting `)'.
1046ct_snat(foo);
1047 Syntax error at `foo' expecting IPv4 address.
1048ct_snat(foo, bar);
1049 Syntax error at `foo' expecting IPv4 address.
1050ct_snat();
1051 Syntax error at `)' expecting IPv4 address.
de297547 1052
db0e819b
BP
1053# ct_clear
1054ct_clear;
1055 encodes as ct_clear
1056
b3bd2c33 1057# clone
8f5de083 1058clone { ip4.dst = 255.255.255.255; output; }; next;
00c875d0 1059 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
b3bd2c33
BP
1060 has prereqs eth.type == 0x800
1061
6335d074 1062# arp
8a41ad8e
BP
1063arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1064 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
d5a76da4 1065 has prereqs ip4
bac29564
BP
1066arp { };
1067 formats as arp { drop; };
1068 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1069 has prereqs ip4
6335d074 1070
0bac7164 1071# get_arp
d5a76da4
BP
1072get_arp(outport, ip4.dst);
1073 encodes as push:NXM_NX_REG0[],push:NXM_OF_IP_DST[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[]
1074 has prereqs eth.type == 0x800
1075get_arp(inport, reg0);
1076 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG0[],push:NXM_NX_XXREG0[96..127],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[],pop:NXM_NX_REG15[]
1077
1078get_arp;
1079 Syntax error at `;' expecting `('.
1080get_arp();
1081 Syntax error at `)' expecting field name.
1082get_arp(inport);
1083 Syntax error at `)' expecting `,'.
1084get_arp(inport ip4.dst);
1085 Syntax error at `ip4.dst' expecting `,'.
1086get_arp(inport, ip4.dst;
1087 Syntax error at `;' expecting `)'.
1088get_arp(inport, eth.dst);
1089 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1090get_arp(inport, outport);
1091 Cannot use string field outport where numeric field is required.
1092get_arp(reg0, ip4.dst);
1093 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
1094
1095# put_arp
d5a76da4
BP
1096put_arp(inport, arp.spa, arp.sha);
1097 encodes as push:NXM_NX_REG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ARP_SHA[],push:NXM_OF_ARP_SPA[],pop:NXM_NX_REG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.01.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_REG0[]
1098 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 1099
42814145 1100# put_dhcp_opts
d5a76da4
BP
1101reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1102 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.40.01.02.03.04.03.04.0a.00.00.01,pause)
6f016174
MM
1103reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org",wpad="https://example.org");
1104 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain = "ovn.org", wpad = "https://example.org");
1105 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67,pause)
d5a76da4
BP
1106reg0[15] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.255.0,mtu=1400,ip_forward_enable=1,default_ttl=121,dns_server={8.8.8.8,7.7.7.7},classless_static_route={30.0.0.0/24,10.0.0.4,40.0.0.0/16,10.0.0.6,0.0.0.0/0,10.0.0.1},ethernet_encap=1,router_discovery=0);
1107 formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, ethernet_encap = 1, router_discovery = 0);
1108 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00,pause)
1109
1110reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1111 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1112reg1[0] = put_dhcp_opts();
1113 put_dhcp_opts requires offerip to be specified.
1114reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1115 Syntax error at `x' expecting DHCPv4 option name.
1116reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1117 put_dhcp_opts requires offerip to be specified.
1118reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1119 Syntax error at `"hi"'.
1120reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1121 Syntax error at `xyzzy' expecting DHCPv4 option name.
1122reg1[0] = put_dhcp_opts(offerip="xyzzy");
1123 DHCPv4 option offerip requires numeric value.
1124reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1125 DHCPv4 option domain requires string value.
42814145 1126
b1a3a6a4
NS
1127# nd_ns
1128nd_ns { nd.target = xxreg0; output; };
1129 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1130 has prereqs ip6
1131
1132nd_ns { };
1133 formats as nd_ns { drop; };
1134 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1135 has prereqs ip6
1136
f8a8db39 1137# nd_na
d5a76da4
BP
1138nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1139 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1140 encodes as controller(userdata=00.00.00.03.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1141 has prereqs nd_ns
c9756229
NS
1142# nd_na_router
1143nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1144 formats as nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1145 encodes as controller(userdata=00.00.00.0c.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1146 has prereqs nd_ns
e75451fe 1147
c34a87b6 1148# get_nd
d5a76da4
BP
1149get_nd(outport, ip6.dst);
1150 encodes as push:NXM_NX_XXREG0[],push:NXM_NX_IPV6_DST[],pop:NXM_NX_XXREG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_XXREG0[]
1151 has prereqs eth.type == 0x86dd
1152get_nd(inport, xxreg0);
1153 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG15[]
1154get_nd;
1155 Syntax error at `;' expecting `('.
1156get_nd();
1157 Syntax error at `)' expecting field name.
1158get_nd(inport);
1159 Syntax error at `)' expecting `,'.
1160get_nd(inport ip6.dst);
1161 Syntax error at `ip6.dst' expecting `,'.
1162get_nd(inport, ip6.dst;
1163 Syntax error at `;' expecting `)'.
1164get_nd(inport, eth.dst);
1165 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1166get_nd(inport, outport);
1167 Cannot use string field outport where numeric field is required.
1168get_nd(xxreg0, ip6.dst);
1169 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
1170
1171# put_nd
d5a76da4
BP
1172put_nd(inport, nd.target, nd.sll);
1173 encodes as push:NXM_NX_XXREG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ND_SLL[],push:NXM_NX_ND_TARGET[],pop:NXM_NX_XXREG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.04.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_XXREG0[]
32157c87 1174 has prereqs (icmp6.type == 0x87 || icmp6.type == 0x88) && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
c34a87b6 1175
01cfdb2f 1176# put_dhcpv6_opts
d5a76da4 1177reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
a55dacac 1178 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.05.00.10.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.00.02.00.06.00.00.00.00.10.02,pause)
d5a76da4
BP
1179reg1[0] = put_dhcpv6_opts();
1180 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1181reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1182 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
a55dacac 1183 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
40df4566
ZKL
1184reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1185 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
a55dacac 1186 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.02.00.06.12.34.56.78.9a.bc.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.89.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
d5a76da4 1187reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
a55dacac 1188 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.18.00.07.6f.76.6e.2e.6f.72.67,pause)
d5a76da4
BP
1189reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1190 Syntax error at `x' expecting DHCPv6 option name.
1191reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1192 Syntax error at `"hi"'.
1193reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1194 Syntax error at `xyzzy' expecting DHCPv6 option name.
1195reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1196 DHCPv6 option ia_addr requires numeric value.
1197reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1198 DHCPv6 option domain_search requires string value.
01cfdb2f 1199
a6095f81
BS
1200# set_queue
1201set_queue(0);
1202 encodes as set_queue:0
1203set_queue(61440);
1204 encodes as set_queue:61440
1205set_queue(65535);
1206 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1207
ea991ad2
NS
1208# dns_lookup
1209reg1[0] = dns_lookup();
1210 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1211 has prereqs udp
1212reg1[0] = dns_lookup("foo");
1213 dns_lookup doesn't take any parameters
1214
66d89287
GL
1215# set_meter
1216set_meter(0);
1217 Rate 0 for set_meter is not in valid.
1218set_meter(1);
1219 encodes as meter:1
1220set_meter(100, 1000);
1221 encodes as meter:2
1222set_meter(100, 1000, );
1223 Syntax error at `,' expecting `)'.
1224set_meter(4294967295, 4294967295);
1225 encodes as meter:3
1226
977433d8
JP
1227# log
1228log(verdict=allow, severity=warning);
1229 encodes as controller(userdata=00.00.00.07.00.00.00.00.00.04)
1230log(name="test1", verdict=drop, severity=info);
1231 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31)
1232log(verdict=drop, severity=info, meter="meter1");
1233 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06,meter_id=4)
1234log(name="test1", verdict=drop, severity=info, meter="meter1");
1235 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31,meter_id=4)
1236log(verdict=drop);
1237 formats as log(verdict=drop, severity=info);
1238 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06)
1239log(verdict=bad_verdict, severity=info);
1240 Syntax error at `bad_verdict' unknown verdict.
1241log(verdict=drop, severity=bad_severity);
1242 Syntax error at `bad_severity' unknown severity.
1243log(severity=notice);
1244 Syntax error at `;' expecting verdict.
1245
52ed5fcc
NS
1246# put_nd_ra_opts
1247reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1248 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
1249 has prereqs ip6
1250reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1251 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
1252 has prereqs ip6
1253reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1254 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
1255 has prereqs ip6
1256reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1257 slla option not present
1258reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1259 prefix option can't be set when address mode is dhcpv6_stateful.
1260reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1261 prefix option can't be set when address mode is dhcpv6_stateful.
1262reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1263 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1264reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1265 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1266reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1267 Syntax error at `dhcpv6_stateless' expecting constant.
1268reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1269 Invalid value for "prefix" option
1270reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1271 Invalid value for "addr_mode" option
1272reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1273 IPv6 ND RA option mtu requires numeric value.
1274reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1275 Invalid value for "mtu" option
1276
bc3d6a63
LB
1277# icmp4
1278icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1279 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1280 has prereqs ip4
1281
1282icmp4 { };
1283 formats as icmp4 { drop; };
1284 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1285 has prereqs ip4
1286
3e7fa1e3
LB
1287# icmp6
1288icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1289 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1290 has prereqs ip6
1291
1292icmp6 { };
1293 formats as icmp6 { drop; };
1294 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1295 has prereqs ip6
1296
22b65e4d
LB
1297# tcp_reset
1298tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1299 encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1300 has prereqs tcp
1301
1302tcp_reset { };
1303 formats as tcp_reset { drop; };
1304 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1305 has prereqs tcp
1306
5f822129 1307# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
1308ip4.src = ip6.src[0..31];
1309 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1310 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1311ip4.src <-> ip6.src[0..31];
1312 encodes as push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[]
1313 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1314
1315# Miscellaneous negative tests.
1316;
1317 Syntax error at `;'.
1318xyzzy;
1319 Syntax error at `xyzzy' expecting action.
1320next; 123;
1321 Syntax error at `123'.
1322next; xyzzy;
1323 Syntax error at `xyzzy' expecting action.
1324next
9aef3c1b 1325 Syntax error at end of input expecting `;'.
3b7cb7e1 1326]])
d5a76da4
BP
1327sed '/^[[ ]]/d' test-cases.txt > input.txt
1328cp test-cases.txt expout
3b7cb7e1
BP
1329AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1330AT_CLEANUP
f295c17b
BP
1331
1332AT_BANNER([OVN end-to-end tests])
1333
9975d7be
BP
1334# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1335AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1336AT_KEYWORDS([ovnarp])
f295c17b
BP
1337AT_SKIP_IF([test $HAVE_PYTHON = no])
1338ovn_start
1339
1340# Create hypervisors hv[123].
9975d7be 1341# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1342# Add all of the vifs to a single logical switch lsw0.
1343# Turn on port security on all the vifs except vif[123]1.
1344# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1345# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1346ovn-nbctl ls-add lsw0
f295c17b
BP
1347net_add n1
1348for i in 1 2 3; do
1349 sim_add hv$i
1350 as hv$i
1351 ovs-vsctl add-br br-phys
1352 ovn_attach n1 br-phys 192.168.0.$i
1353
1354 for j in 1 2 3; do
1355 ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
31ed1192 1356 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1357 if test $j = 1; then
31ed1192 1358 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1359 else
7dc88496
NS
1360 if test $j = 3; then
1361 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1362 else
1363 ip_addrs="192.168.0.$i$j"
1364 fi
31ed1192
JP
1365 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1366 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1367 fi
1368 done
1369done
1370ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1371ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1372ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1373ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:11\",\"f0:00:00:00:00:21\",\"f0:00:00:00:00:31\"
1374ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b 1375
3d2848ba
HZ
1376get_lsp_uuid () {
1377 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1378}
1379
1380ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1381ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1382
f295c17b
BP
1383# Pre-populate the hypervisors' ARP tables so that we don't lose any
1384# packets for ARP resolution (native tunneling doesn't queue packets
1385# for ARP resolution).
74868f2c 1386OVN_POPULATE_ARP
f295c17b
BP
1387
1388# Allow some time for ovn-northd and ovn-controller to catch up.
1389# XXX This should be more systematic.
1390sleep 1
611099dc 1391
fc6f9978
HZ
1392# Make sure there is no attempt to adding duplicated flows by ovn-controller
1393AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1394AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1395AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1396
57d143eb
HZ
1397# Given the name of a logical port, prints the name of the hypervisor
1398# on which it is located.
1399vif_to_hv() {
1400 echo hv${1%?}
1401}
1402
f295c17b
BP
1403# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1404#
1405# This shell function causes a packet to be received on INPORT. The packet's
1406# content has Ethernet destination DST and source SRC (each exactly 12 hex
1407# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1408# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1409# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1410for i in 1 2 3; do
1411 for j in 1 2 3; do
1412 : > $i$j.expected
1413 done
1414done
1415test_packet() {
1416 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1417 hv=`vif_to_hv $inport`
f295c17b
BP
1418 vif=vif$inport
1419 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1420 for outport; do
e4543cfe 1421 echo $packet >> $outport.expected
f295c17b
BP
1422 done
1423}
1424
57d143eb
HZ
1425# test_arp INPORT SHA SPA TPA [REPLY_HA]
1426#
1427# Causes a packet to be received on INPORT. The packet is an ARP
1428# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1429# it should be the hardware address of the target to expect to receive in an
1430# ARP reply; otherwise no reply is expected.
1431#
31ed1192 1432# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1433# SHA and REPLY_HA are each 12 hex digits.
1434# SPA and TPA are each 8 hex digits.
1435test_arp() {
1436 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1437 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1438 hv=`vif_to_hv $inport`
1439 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1440
92f9822b 1441 if test X$reply_ha = X; then
57d143eb
HZ
1442 # Expect to receive the broadcast ARP on the other logical switch ports
1443 # if no reply is expected.
1444 local i j
1445 for i in 1 2 3; do
1446 for j in 1 2 3; do
1447 if test $i$j != $inport; then
1448 echo $request >> $i$j.expected
1449 fi
1450 done
1451 done
1452 else
1453 # Expect to receive the reply, if any.
1454 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1455 echo $reply >> $inport.expected
1456 fi
1457}
1458
1459ip_to_hex() {
1460 printf "%02x%02x%02x%02x" "$@"
1461}
1462
f295c17b
BP
1463# Send packets between all pairs of source and destination ports:
1464#
31ed1192
JP
1465# 1. Unicast packets are delivered to exactly one logical switch port
1466# (except that packets destined to their input ports are dropped).
f295c17b 1467#
31ed1192
JP
1468# 2. Broadcast and multicast are delivered to all logical switch ports
1469# except the input port.
f295c17b 1470#
ea46a4e9 1471# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1472# MAC address.
1473#
ea46a4e9 1474# 4. The switch drops all packets with a VLAN tag.
f295c17b 1475#
ea46a4e9 1476# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1477# affects behavior when port security is turned off, since otherwise port
1478# security would drop the packet anyway.)
1479#
ea46a4e9 1480# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1481# switch ports with "unknown" among their MAC addresses (and port
1482# security disabled).
f295c17b 1483#
ea46a4e9 1484# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1485#
ea46a4e9 1486# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1487#
9fcb6a18
BP
1488# 9. OVN generates responses to ARP requests for known IPs, except for
1489# requests from a port for the port's own IP.
57d143eb
HZ
1490#
1491# 10. No response to ARP requests for unknown IPs.
4acd1e87 1492
f295c17b
BP
1493for is in 1 2 3; do
1494 for js in 1 2 3; do
1495 s=$is$js
1496 bcast=
4d5c43d5
JP
1497 unknown=
1498 bacl2=
1499 bacl3=
f295c17b
BP
1500 for id in 1 2 3; do
1501 for jd in 1 2 3; do
1502 d=$id$jd
1503
1504 if test $d != $s; then unicast=$d; else unicast=; fi
1505 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1506
1507 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1508 impersonate=$d
1509 else
1510 impersonate=
1511 fi
f295c17b
BP
1512 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1513
4d5c43d5
JP
1514 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1515 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1516 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1517 # Source of 11, 21, or 31 and dest of 33 should be dropped
1518 # due to the 4th ACL that uses address_set(set1).
1519 acl4=
1520 else
1521 acl4=$d
1522 fi
3d2848ba
HZ
1523 if test $d = $s || test $d = 22 || test $d = 33; then
1524 # dest of 22 and 33 should be dropped
1525 # due to the 5th ACL that uses port_group(pg1).
1526 acl5=
1527 else
1528 acl5=$d
1529 fi
f295c17b
BP
1530 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1531 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1532 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1533 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
3d2848ba 1534 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
f295c17b
BP
1535
1536 test_packet $s f000000000$d f00000000055 810000091234 #4
1537 test_packet $s f000000000$d 0100000000$s $s$d #5
1538
4d5c43d5
JP
1539 if test $d != $s && test $jd = 1; then
1540 unknown="$unknown $d"
1541 fi
f295c17b
BP
1542 bcast="$bcast $unicast"
1543 bacl2="$bacl2 $acl2"
1544 bacl3="$bacl3 $acl3"
57d143eb 1545
db02f370 1546 sip=`ip_to_hex 192 168 0 $is$js`
57d143eb
HZ
1547 tip=`ip_to_hex 192 168 0 $id$jd`
1548 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1549 if test $d != $s; then
1550 reply_ha=f000000000$d
1551 else
1552 reply_ha=
1553 fi
1554 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1555 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1556
1557 if test $jd = 3; then
31ed1192 1558 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1559 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1560 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1561 fi
f295c17b
BP
1562 done
1563 done
1564
4d5c43d5 1565 # Broadcast and multicast.
f295c17b
BP
1566 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1567 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1568 if test $js = 1; then
f295c17b
BP
1569 bcast_impersonate=$bcast
1570 else
4d5c43d5
JP
1571 bcast_impersonate=
1572 fi
f295c17b
BP
1573 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1574
1575 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1576
1577 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1578 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1579 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1580 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1581 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1582 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1583 done
1584done
1585
7dc88496
NS
1586# set address for lp13 with invalid characters.
1587# lp13 should be configured with only 192.168.0.13.
31ed1192 1588ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1589
1590# Allow some time for ovn-northd and ovn-controller to catch up.
1591# XXX This should be more systematic.
1592sleep 1
1593
7dc88496
NS
1594sip=`ip_to_hex 192 168 0 11`
1595tip=`ip_to_hex 192 168 0 13`
1596test_arp 11 f00000000011 $sip $tip f00000000013
1597
1598tip=`ip_to_hex 192 169 0 13`
1599#arp request for 192.169.0.13 should be flooded
1600test_arp 11 f00000000011 $sip $tip
1601
91125642 1602# dump information and flows with counters
bb0c41d3
RM
1603ovn-sbctl dump-flows -- list multicast_group
1604
1605echo "------ hv1 dump ------"
1606as hv1 ovs-vsctl show
1607as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1608
1609echo "------ hv2 dump ------"
1610as hv2 ovs-vsctl show
1611as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1612
1613echo "------ hv3 dump ------"
1614as hv3 ovs-vsctl show
1615as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1616
f295c17b
BP
1617# Now check the packets actually received against the ones expected.
1618for i in 1 2 3; do
1619 for j in 1 2 3; do
49d7c759 1620 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1621 done
1622done
fcde56f5 1623
7a8f15e0 1624OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1625
f295c17b 1626AT_CLEANUP
eb6b08eb 1627
4acd1e87
BP
1628AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1629AT_SKIP_IF([test $HAVE_PYTHON = no])
1630ovn_start
1631
1632# Create a logical switch and some logical ports.
1633# Turn on port security on all lports except ls1.
1634# Make ls1 a destination for unknown MACs.
1635# Add some ACLs for Ethertypes 1234, 1235, 1236.
1636ovn-nbctl ls-add lsw0
1637ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1638for i in 1 2 3; do
1639 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1640done
1641ovn-nbctl --wait=sb sync
1642for i in 1 2 3; do
4acd1e87
BP
1643 ovn-sbctl lsp-bind lp$i hv0
1644 if test $i = 1; then
abb37b6b 1645 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1646 else
abb37b6b
FF
1647 if test $i = 3; then
1648 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1649 else
1650 ip_addrs="192.168.0.$i"
1651 fi
a8e2addc
LR
1652 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1653 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
4acd1e87
BP
1654 fi
1655done
1656ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1657ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1658ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1659ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1660ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1661
1662ovn-nbctl --wait=sb sync
1663on_exit 'kill `cat ovn-trace.pid`'
1664ovn-trace --detach --pidfile --no-chdir
1665
1666# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1667#
1668# This shell function causes a packet to be received on INPORT. The packet's
1669# content has Ethernet destination DST and source SRC (each exactly 12 hex
1670# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1671# more) list the VIFs on which the packet should be received. INPORT and the
1672# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1673test_packet() {
1674 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1675 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1676 while :; do
abb37b6b
FF
1677 case $1 in # (
1678 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1679 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1680 *) break ;;
1681 esac
4acd1e87
BP
1682 done
1683 for outport; do
abb37b6b 1684 echo "output(\"lp$outport\");"
4acd1e87
BP
1685 done > expout
1686
1687 AT_CAPTURE_FILE([trace])
1688 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1689}
1690
1691# test_arp INPORT SHA SPA TPA [REPLY_HA]
1692#
1693# Causes a packet to be received on INPORT. The packet is an ARP
1694# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1695# it should be the hardware address of the target to expect to receive in an
1696# ARP reply; otherwise no reply is expected.
1697#
1698# INPORT is an logical switch port number, e.g. 11 for vif11.
1699# SHA and REPLY_HA are each 12 hex digits.
1700# SPA and TPA are each 8 hex digits.
1701test_arp() {
1702 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1703
1704 local request="inport == \"lp$inport\"
1705 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1706 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1707 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1708
1709 if test -z "$reply_ha"; then
1710 reply=
abb37b6b
FF
1711 local i
1712 for i in 1 2 3; do
1713 if test $i != $inport; then
1714 reply="${reply}output(\"lp$i\");
4acd1e87 1715"
abb37b6b
FF
1716 fi
1717 done
4acd1e87
BP
1718 else
1719 reply="\
1720eth.dst = $sha;
1721eth.src = $reply_ha;
1722arp.op = 2;
1723arp.tha = $sha;
1724arp.sha = $reply_ha;
1725arp.tpa = $spa;
1726arp.spa = $tpa;
1727output(\"lp$inport\");
1728"
1729 fi
1730
1731 AT_CAPTURE_FILE([trace])
1732 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1733}
1734
1735# Send packets between all pairs of source and destination ports:
1736#
1737# 1. Unicast packets are delivered to exactly one logical switch port
1738# (except that packets destined to their input ports are dropped).
1739#
1740# 2. Broadcast and multicast are delivered to all logical switch ports
1741# except the input port.
1742#
1743# 3. When port security is turned on, the switch drops packets from the wrong
1744# MAC address.
1745#
1746# 4. The switch drops all packets with a VLAN tag.
1747#
1748# 5. The switch drops all packets with a multicast source address. (This only
1749# affects behavior when port security is turned off, since otherwise port
1750# security would drop the packet anyway.)
1751#
1752# 6. The switch delivers packets with an unknown destination to logical
1753# switch ports with "unknown" among their MAC addresses (and port
1754# security disabled).
1755#
1756# 7. The switch drops unicast packets that violate an ACL.
1757#
1758# 8. The switch drops multicast and broadcast packets that violate an ACL.
1759#
9fcb6a18
BP
1760# 9. OVN generates responses to ARP requests for known IPs, except for
1761# requests from a port for the port's own IP.
4acd1e87
BP
1762#
1763# 10. No response to ARP requests for unknown IPs.
1764
1765for s in 1 2 3; do
1766 bcast=
1767 unknown=
1768 bacl2=
1769 bacl3=
1770 for d in 1 2 3; do
abb37b6b
FF
1771 echo
1772 echo "lp$s -> lp$d"
1773 if test $d != $s; then unicast=$d; else unicast=; fi
1774 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1775
1776 if test $d != $s && test $s = 1; then
1777 impersonate=$d
1778 else
1779 impersonate=
1780 fi
1781 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1782
1783 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1784 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1785 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1786 # Source of 1 or 2 and dest of 3 should be dropped
1787 # due to the 4th ACL that uses address_set(set1).
1788 acl4=
1789 else
1790 acl4=$d
1791 fi
1792
1793 #7, acl1 to acl4:
1794 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1795 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1796 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1797 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1798
1799 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1800 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1801
1802 if test $d != $s && test $d = 1; then
1803 unknown="$unknown $d"
1804 fi
1805 bcast="$bcast $unicast"
1806 bacl2="$bacl2 $acl2"
1807 bacl3="$bacl3 $acl3"
1808
1809 sip=192.168.0.$s
1810 tip=192.168.0.$d
1811 tip_unknown=11.11.11.11
9fcb6a18
BP
1812 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1813 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1814 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1815
1816 if test $d = 3; then
1817 # lp3 has an additional ip 192.169.0.[123]3.
1818 tip=192.169.0.$d
9fcb6a18 1819 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1820 fi
4acd1e87
BP
1821 done
1822
1823 # Broadcast and multicast.
1824 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1825 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1826 if test $s = 1; then
abb37b6b 1827 bcast_impersonate=$bcast
4acd1e87 1828 else
abb37b6b 1829 bcast_impersonate=
4acd1e87
BP
1830 fi
1831 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1832
1833 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1834
1835 #8, acl1 to acl3:
1836 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1837 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1838 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1839
1840 #8, acl1 to acl3:
1841 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1842 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1843 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1844done
1845
1846AT_CLEANUP
1847
7277bc83
RB
1848# 2 hypervisors, 4 logical ports per HV
1849# 2 locally attached networks (one flat, one vlan tagged over same device)
1850# 2 ports per HV on each network
e90aeb57 1851AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1852AT_SKIP_IF([test $HAVE_PYTHON = no])
1853ovn_start
1854
ea46a4e9
JP
1855# In this test cases we create 3 switches, all connected to same
1856# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1857# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1858# of VIF port name indicates the hypervisor it is bound to, e.g.
1859# lp23 means VIF 3 on hv2.
1860#
ea46a4e9 1861# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1862# - ls1:
1863# - untagged
ea46a4e9 1864# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1865#
1866# - ls2:
1867# - tagged with VLAN 101
ea46a4e9 1868# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1869# - ls3:
1870# - untagged
ea46a4e9 1871# - ports: lp15, lp25
0ee7f7f1 1872#
ea46a4e9 1873# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1874# physical network.
1875
1876for i in 1 2 3; do
ea46a4e9
JP
1877 ls_name=ls$i
1878 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1879 ln_port_name=ln$i
1880 if test $i -eq 2; then
ea46a4e9 1881 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1882 else
ea46a4e9 1883 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1884 fi
31ed1192
JP
1885 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1886 ovn-nbctl lsp-set-type $ln_port_name localnet
1887 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1888done
d79fc5f4 1889
69b72264
BP
1890# lsp_to_ls LSP
1891#
1892# Prints the name of the logical switch that contains LSP.
1893lsp_to_ls () {
1894 case $1 in dnl (
5a0e4aec
BP
1895 lp?[[12]]) echo ls1 ;; dnl (
1896 lp?[[34]]) echo ls2 ;; dnl (
1897 lp?5) echo ls3 ;; dnl (
1898 *) AT_FAIL_IF([:]) ;;
69b72264
BP
1899 esac
1900}
1901
d79fc5f4
RB
1902net_add n1
1903for i in 1 2; do
1904 sim_add hv$i
1905 as hv$i
1906 ovs-vsctl add-br br-phys
1907 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1908 ovn_attach n1 br-phys 192.168.0.$i
1909
0ee7f7f1 1910 for j in 1 2 3 4 5; do
d79fc5f4
RB
1911 ovs-vsctl add-port br-int vif$i$j -- \
1912 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1913 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1914 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1915 ofport-request=$i$j
1916
31ed1192 1917 lsp_name=lp$i$j
5a0e4aec 1918 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 1919
ea46a4e9 1920 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1921 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1922 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1923
31ed1192 1924 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1925 done
1926done
69b72264
BP
1927ovn-nbctl --wait=sb sync
1928ovn-sbctl dump-flows
d79fc5f4 1929
74868f2c 1930OVN_POPULATE_ARP
d79fc5f4
RB
1931
1932# XXX This is now the 3rd copy of these functions in this file ...
1933
1934# Given the name of a logical port, prints the name of the hypervisor
1935# on which it is located.
1936vif_to_hv() {
1937 echo hv${1%?}
1938}
1939#
69b72264 1940# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
1941#
1942# This shell function causes a packet to be received on INPORT. The packet's
1943# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
1944# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1945# logical switch port numbers, e.g. 11 for vif11.
1946#
1947# EOUT is the end-to-end output port, that is, where the packet will end up
1948# after possibly bouncing through one or more localnet ports. LOUT is the
1949# logical output port, which might be a localnet port, as seen by ovn-trace
1950# (which doesn't know what localnet ports are connected to and therefore can't
1951# figure out the end-to-end answer).
d79fc5f4 1952for i in 1 2; do
0ee7f7f1 1953 for j in 1 2 3 4 5; do
d79fc5f4
RB
1954 : > $i$j.expected
1955 done
1956done
1957test_packet() {
69b72264
BP
1958 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1959 echo "$@"
1960
1961 # First try tracing the packet.
1962 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1963 if test $lout != drop; then
1964 echo "output(\"$lout\");"
1965 fi > expout
1966 AT_CAPTURE_FILE([trace])
1967 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1968
1969 # Then actually send a packet, for an end-to-end test.
1970 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
1971 hv=`vif_to_hv $inport`
1972 vif=vif$inport
1973 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
1974 if test $eout != drop; then
1975 echo $packet >> ${eout#lp}.expected
1976 fi
d79fc5f4
RB
1977}
1978
7277bc83
RB
1979# lp11 and lp21 are on the same network (phys, untagged)
1980# and on different hypervisors
69b72264
BP
1981test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1982test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 1983
7277bc83
RB
1984# lp11 and lp12 are on the same network (phys, untagged)
1985# and on the same hypervisor
69b72264
BP
1986test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1987test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
1988
1989# lp13 and lp23 are on the same network (phys, VLAN 101)
1990# and on different hypervisors
69b72264
BP
1991test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1992test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
1993
1994# lp13 and lp14 are on the same network (phys, VLAN 101)
1995# and on the same hypervisor
69b72264
BP
1996test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1997test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 1998
0ee7f7f1 1999# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 2000# same hypervisor, and on different switches
69b72264
BP
2001test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2002test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
2003
2004# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 2005# different hypervisors, and on different switches
69b72264
BP
2006test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2007test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 2008
d79fc5f4 2009# Ports that should not be able to communicate
69b72264
BP
2010test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2011test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2012test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2013test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2014test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2015test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2016test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2017test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 2018
d79fc5f4
RB
2019# Dump a bunch of info helpful for debugging if there's a failure.
2020
2021echo "------ OVN dump ------"
2022ovn-nbctl show
2023ovn-sbctl show
2024
2025echo "------ hv1 dump ------"
2026as hv1 ovs-vsctl show
2027as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2028
2029echo "------ hv2 dump ------"
2030as hv2 ovs-vsctl show
2031as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2032
2033# Now check the packets actually received against the ones expected.
2034for i in 1 2; do
0ee7f7f1 2035 for j in 1 2 3 4 5; do
49d7c759 2036 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
2037 done
2038done
2039
7a8f15e0 2040OVN_CLEANUP([hv1],[hv2])
d9c8c57c 2041
d79fc5f4
RB
2042AT_CLEANUP
2043
91125642
FF
2044AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2045AT_KEYWORDS([vtep])
eb6b08eb
JP
2046AT_SKIP_IF([test $HAVE_PYTHON = no])
2047ovn_start
2048
2049# Configure the Northbound database
ea46a4e9 2050ovn-nbctl ls-add lsw0
eb6b08eb 2051
31ed1192
JP
2052ovn-nbctl lsp-add lsw0 lp1
2053ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 2054
31ed1192
JP
2055ovn-nbctl lsp-add lsw0 lp2
2056ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 2057
31ed1192
JP
2058ovn-nbctl lsp-add lsw0 lp-vtep
2059ovn-nbctl lsp-set-type lp-vtep vtep
2060ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2061ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 2062
77adbb62
DB
2063# lpr, lr and lrp1 are used for the ARP request handling test only.
2064ovn-nbctl lsp-add lsw0 lpr
2065ovn-nbctl lr-add lr
2066ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2067ovn-nbctl set Logical_Switch_Port lpr type=router \
2068 options:router-port=lrp1 \
2069 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2070
2071
eb6b08eb
JP
2072net_add n1 # Network to connect hv1, hv2, and vtep
2073net_add n2 # Network to connect vtep and hv3
2074
2075# Create hypervisor hv1 connected to n1
2076sim_add hv1
2077as hv1
2078ovs-vsctl add-br br-phys
2079ovn_attach n1 br-phys 192.168.0.1
2080ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
2081
2082# Create hypervisor hv2 connected to n1
2083sim_add hv2
2084as hv2
2085ovs-vsctl add-br br-phys
2086ovn_attach n1 br-phys 192.168.0.2
2087ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
2088
2089
2090# Start the vtep emulator with a leg in both networks
2091sim_add vtep
2092as vtep
2093
2094ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2095ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2096
2097ovs-vsctl add-br br-phys
2098net_attach n1 br-phys
2099
2100mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2101arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2102ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2103ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2104
2105ovs-vsctl add-br br-vtep
2106net_attach n2 br-vtep
2107
2108vtep-ctl add-ps br-vtep
2109vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2110vtep-ctl add-ls lsw0
2111
2112start_daemon ovs-vtep br-vtep
2113start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2114
8cdc4312 2115OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 2116
475f0a2c
DB
2117OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2118 grep -- source`"])
2119# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
2120sleep 1
2121
2122# Add hv3 on the other side of the vtep
2123sim_add hv3
2124as hv3
2125ovs-vsctl add-br br-phys
2126net_attach n2 br-phys
2127
2128ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
2129
2130# Pre-populate the hypervisors' ARP tables so that we don't lose any
2131# packets for ARP resolution (native tunneling doesn't queue packets
2132# for ARP resolution).
74868f2c 2133OVN_POPULATE_ARP
eb6b08eb
JP
2134
2135# Allow some time for ovn-northd and ovn-controller to catch up.
2136# XXX This should be more systematic.
2137sleep 1
6977df72 2138
eb6b08eb
JP
2139# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2140#
2141# This shell function causes a packet to be received on INPORT. The packet's
2142# content has Ethernet destination DST and source SRC (each exactly 12 hex
2143# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2144# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2145# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
2146for i in 1 2 3; do
2147 : > $i.expected
2148done
2149test_packet() {
2150 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2151 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2152 hv=hv$inport
2153 vif=vif$inport
2154 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2155 for outport; do
e4543cfe 2156 echo $packet >> $outport.expected
eb6b08eb
JP
2157 done
2158}
2159
2160# Send packets between all pairs of source and destination ports:
2161#
31ed1192
JP
2162# 1. Unicast packets are delivered to exactly one logical switch port
2163# (except that packets destined to their input ports are dropped).
eb6b08eb 2164#
31ed1192
JP
2165# 2. Broadcast and multicast are delivered to all logical switch ports
2166# except the input port.
eb6b08eb 2167#
ea46a4e9 2168# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
2169# switch ports with "unknown" among their MAC addresses (and port
2170# security disabled).
eb6b08eb
JP
2171for s in 1 2 3; do
2172 bcast=
2173 unknown=
2174 for d in 1 2 3; do
2175 if test $d != $s; then unicast=$d; else unicast=; fi
2176 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2177
2178 # The vtep (vif3) is the only one configured for "unknown"
2179 if test $d != $s && test $d = 3; then
2180 unknown="$unknown $d"
2181 fi
2182 bcast="$bcast $unicast"
2183 done
2184
2185 # Broadcast and multicast.
46ed1382
DB
2186 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2187 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
2188
2189 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2190done
2191
77adbb62
DB
2192# ARP request should not be responded to by logical switch router
2193# type arp responder on HV1 and HV2 and should reach directly to
2194# vif1 and vif2
2195ip_to_hex() {
2196 printf "%02x%02x%02x%02x" "$@"
2197}
2198sha=f00000000003
2199spa=`ip_to_hex 192 168 1 2`
2200tpa=`ip_to_hex 192 168 1 1`
2201request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2202as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2203echo $request >> 1.expected
2204echo $request >> 2.expected
2205
bb0c41d3
RM
2206# dump information with counters
2207echo "------ OVN dump ------"
2208ovn-nbctl show
2209ovn-sbctl show
2210
77adbb62
DB
2211echo "---------SB dump-----"
2212ovn-sbctl list datapath_binding
2213echo "---------------------"
2214ovn-sbctl list port_binding
2215echo "---------------------"
2216ovn-sbctl dump-flows
2217
bb0c41d3
RM
2218echo "------ hv1 dump ------"
2219as hv1 ovs-vsctl show
6195e2e7 2220as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2221as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2222
2223echo "------ hv2 dump ------"
2224as hv2 ovs-vsctl show
6195e2e7 2225as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2226as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2227
2228echo "------ hv3 dump ------"
2229as hv3 ovs-vsctl show
6754e92d
FF
2230# note: hv3 has no logical port bind, thus it should not have br-int
2231AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2232[ovs-ofctl: br-int is not a bridge or a socket
2233])
bb0c41d3 2234
eb6b08eb
JP
2235# Now check the packets actually received against the ones expected.
2236for i in 1 2 3; do
49d7c759 2237 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 2238done
fcde56f5
LR
2239
2240# Gracefully terminate daemons
7a8f15e0
LR
2241OVN_CLEANUP([hv1],[hv2],[vtep])
2242OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 2243
eb6b08eb 2244AT_CLEANUP
9975d7be 2245
184bc3ca
RB
2246# Similar test to "hardware GW"
2247AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2248AT_SKIP_IF([test $HAVE_PYTHON = no])
2249ovn_start
2250
2251# Configure the Northbound database
2252ovn-nbctl ls-add lsw0
2253
2254ovn-nbctl lsp-add lsw0 lp1
2255ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2256
2257ovn-nbctl lsp-add lsw0 lp2
2258ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2259
2260ovn-nbctl lsp-add lsw0 lp-gw
2261ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 2262ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
2263ovn-nbctl lsp-set-addresses lp-gw unknown
2264
2265net_add n1 # Network to connect hv1, hv2, and gw
2266net_add n2 # Network to connect gw and hv3
2267
2268# Create hypervisor hv1 connected to n1
2269sim_add hv1
2270as hv1
2271ovs-vsctl add-br br-phys
2272ovn_attach n1 br-phys 192.168.0.1
2273ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
2274
2275# Create hypervisor hv2 connected to n1
2276sim_add hv2
2277as hv2
2278ovs-vsctl add-br br-phys
2279ovn_attach n1 br-phys 192.168.0.2
2280ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
2281
2282# Create hypervisor hv_gw connected to n1 and n2
2283# connect br-phys bridge to n1; connect hv-gw bridge to n2
2284sim_add hv_gw
2285as hv_gw
2286ovs-vsctl add-br br-phys
2287ovn_attach n1 br-phys 192.168.0.3
2288ovs-vsctl add-br br-phys2
2289net_attach n2 br-phys2
2290ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2291
184bc3ca
RB
2292# Add hv3 on the other side of the GW
2293sim_add hv3
2294as hv3
2295ovs-vsctl add-br br-phys
2296net_attach n2 br-phys
2297ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
2298
2299
2300# Pre-populate the hypervisors' ARP tables so that we don't lose any
2301# packets for ARP resolution (native tunneling doesn't queue packets
2302# for ARP resolution).
74868f2c 2303OVN_POPULATE_ARP
184bc3ca
RB
2304
2305# Allow some time for ovn-northd and ovn-controller to catch up.
2306# XXX This should be more systematic.
2307sleep 1
2308
2309# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2310#
2311# This shell function causes a packet to be received on INPORT. The packet's
2312# content has Ethernet destination DST and source SRC (each exactly 12 hex
2313# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2314# more) list the VIFs on which the packet should be received. INPORT and the
2315# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
2316for i in 1 2 3; do
2317 : > $i.expected
2318done
2319test_packet() {
2320 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2321 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2322 hv=hv$inport
2323 vif=vif$inport
2324 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2325 for outport; do
e4543cfe 2326 echo $packet >> $outport.expected
184bc3ca
RB
2327 done
2328}
2329
2330# Send packets between all pairs of source and destination ports:
2331#
2332# 1. Unicast packets are delivered to exactly one lport (except that packets
2333# destined to their input ports are dropped).
2334#
2335# 2. Broadcast and multicast are delivered to all lports except the input port.
2336#
2337# 3. The lswitch delivers packets with an unknown destination to lports with
2338# "unknown" among their MAC addresses (and port security disabled).
2339for s in 1 2 3 ; do
2340 bcast=
2341 unknown=
2342 for d in 1 2 3 ; do
2343 if test $d != $s; then unicast=$d; else unicast=; fi
2344 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2345
2346 # The vtep (vif3) is the only one configured for "unknown"
2347 if test $d != $s && test $d = 3; then
2348 unknown="$unknown $d"
2349 fi
2350 bcast="$bcast $unicast"
2351 done
2352
2353 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2354 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2355 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2356done
2357
184bc3ca
RB
2358echo "------ ovn-nbctl show ------"
2359ovn-nbctl show
2360echo "------ ovn-sbctl show ------"
2361ovn-sbctl show
2362
2363echo "------ hv1 ------"
2364as hv1 ovs-vsctl show
2365echo "------ hv1 br-int ------"
2366as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2367echo "------ hv1 br-phys ------"
2368as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2369
2370echo "------ hv2 ------"
2371as hv2 ovs-vsctl show
2372echo "------ hv2 br-int ------"
2373as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2374echo "------ hv2 br-phys ------"
2375as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2376
2377echo "------ hv_gw ------"
2378as hv_gw ovs-vsctl show
2379echo "------ hv_gw br-phys ------"
2380as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2381echo "------ hv_gw br-phys2 ------"
2382as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2383
2384echo "------ hv3 ------"
2385as hv3 ovs-vsctl show
2386echo "------ hv3 br-phys ------"
2387as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2388
2389# Now check the packets actually received against the ones expected.
2390for i in 1 2 3; do
49d7c759 2391 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2392done
2393AT_CLEANUP
2394
9975d7be
BP
2395# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2396AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2397AT_SKIP_IF([test $HAVE_PYTHON = no])
2398ovn_start
2399
2400# Logical network:
2401#
2402# Three logical switches ls1, ls2, ls3.
86e98048
BP
2403# One logical router lr0 connected to ls[123],
2404# with nine subnets, three per logical switch:
2405#
2406# lrp11 on ls1 for subnet 192.168.11.0/24
2407# lrp12 on ls1 for subnet 192.168.12.0/24
2408# lrp13 on ls1 for subnet 192.168.13.0/24
2409# ...
2410# lrp33 on ls3 for subnet 192.168.33.0/24
2411#
2412# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2413# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2414for i in 1 2 3; do
ea46a4e9 2415 ovn-nbctl ls-add ls$i
9975d7be 2416 for j in 1 2 3; do
86e98048 2417 for k in 1 2 3; do
31ed1192
JP
2418 # Add "unknown" to MAC addresses for lp?11, so packets for
2419 # MAC-IP bindings discovered via ARP later have somewhere to go.
2420 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2421
2422 ovn-nbctl \
2423 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
2424 -- lsp-set-addresses lp$i$j$k \
2425 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
86e98048
BP
2426 done
2427 done
2428done
2429
fa2a27b2 2430ovn-nbctl lr-add lr0
86e98048
BP
2431for i in 1 2 3; do
2432 for j in 1 2 3; do
bf44c2cd 2433 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2434 ovn-nbctl \
31ed1192 2435 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2436 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2437 options:router-port=lrp$i$j \
86e98048 2438 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2439 done
2440done
2441
80f408f4 2442ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2443 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2444
9975d7be
BP
2445# Physical network:
2446#
2447# Three hypervisors hv[123].
86e98048
BP
2448# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2449# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2450# lp?3[123] all on hv3.
2451
9975d7be
BP
2452
2453# Given the name of a logical port, prints the name of the hypervisor
2454# on which it is located.
2455vif_to_hv() {
2456 case $1 in dnl (
86e98048
BP
2457 ?11) echo 1 ;; dnl (
2458 ?12 | ?21 | ?22) echo 2 ;; dnl (
2459 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2460 esac
2461}
2462
86e98048
BP
2463# Given the name of a logical port, prints the name of its logical router
2464# port, e.g. "vif_to_lrp 123" yields 12.
2465vif_to_lrp() {
2466 echo ${1%?}
2467}
2468
2469# Given the name of a logical port, prints the name of its logical
2470# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2471vif_to_ls() {
86e98048 2472 echo ${1%??}
e3393e3f
BP
2473}
2474
9975d7be
BP
2475net_add n1
2476for i in 1 2 3; do
2477 sim_add hv$i
2478 as hv$i
2479 ovs-vsctl add-br br-phys
2480 ovn_attach n1 br-phys 192.168.0.$i
2481done
2482for i in 1 2 3; do
2483 for j in 1 2 3; do
86e98048 2484 for k in 1 2 3; do
269ecccc
JP
2485 hv=`vif_to_hv $i$j$k`
2486 as hv$hv ovs-vsctl \
2487 -- add-port br-int vif$i$j$k \
2488 -- set Interface vif$i$j$k \
2489 external-ids:iface-id=lp$i$j$k \
2490 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2491 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2492 ofport-request=$i$j$k
86e98048 2493 done
9975d7be
BP
2494 done
2495done
2496
2497# Pre-populate the hypervisors' ARP tables so that we don't lose any
2498# packets for ARP resolution (native tunneling doesn't queue packets
2499# for ARP resolution).
74868f2c 2500OVN_POPULATE_ARP
9975d7be
BP
2501
2502# Allow some time for ovn-northd and ovn-controller to catch up.
2503# XXX This should be more systematic.
2504sleep 1
2505
e3393e3f 2506# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2507#
2508# This shell function causes a packet to be received on INPORT. The packet's
2509# content has Ethernet destination DST and source SRC (each exactly 12 hex
2510# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2511# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2512# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2513for i in 1 2 3; do
2514 for j in 1 2 3; do
86e98048
BP
2515 for k in 1 2 3; do
2516 : > $i$j$k.expected
269ecccc 2517 done
9975d7be
BP
2518 done
2519done
e3393e3f 2520test_ip() {
9975d7be
BP
2521 # This packet has bad checksums but logical L3 routing doesn't check.
2522 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2523 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2524 shift; shift; shift; shift; shift
2525 hv=hv`vif_to_hv $inport`
2526 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2527 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2528 in_ls=`vif_to_ls $inport`
2529 in_lrp=`vif_to_lrp $inport`
9975d7be 2530 for outport; do
269ecccc 2531 out_ls=`vif_to_ls $outport`
86e98048 2532 if test $in_ls = $out_ls; then
9975d7be
BP
2533 # Ports on the same logical switch receive exactly the same packet.
2534 echo $packet
2535 else
2536 # Routing decrements TTL and updates source and dest MAC
2537 # (and checksum).
269ecccc 2538 out_lrp=`vif_to_lrp $outport`
86e98048 2539 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2540 fi >> $outport.expected
9975d7be
BP
2541 done
2542}
2543
e3393e3f 2544as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2545as hv1 ovn-sbctl list port_binding
2546as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2547as hv1 ovn-sbctl dump-flows
2548as hv1 ovs-ofctl dump-flows br-int
2549
e3393e3f 2550# Send IP packets between all pairs of source and destination ports:
9975d7be 2551#
31ed1192
JP
2552# 1. Unicast IP packets are delivered to exactly one logical switch port
2553# (except that packets destined to their input ports are dropped).
9975d7be 2554#
31ed1192
JP
2555# 2. Broadcast IP packets are delivered to all logical switch ports
2556# except the input port.
86e98048
BP
2557ip_to_hex() {
2558 printf "%02x%02x%02x%02x" "$@"
2559}
9975d7be 2560for is in 1 2 3; do
269ecccc
JP
2561 for js in 1 2 3; do
2562 for ks in 1 2 3; do
2563 bcast=
2564 s=$is$js$ks
2565 smac=f00000000$s
2566 sip=`ip_to_hex 192 168 $is$js $ks`
2567 for id in 1 2 3; do
2568 for jd in 1 2 3; do
2569 for kd in 1 2 3; do
2570 d=$id$jd$kd
2571 dip=`ip_to_hex 192 168 $id$jd $kd`
2572 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2573 if test $d != $s; then unicast=$d; else unicast=; fi
2574
2575 test_ip $s $smac $dmac $sip $dip $unicast #1
2576
2577 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2578 done
2579 done
9975d7be 2580 done
269ecccc
JP
2581 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2582 done
2583 done
e3393e3f
BP
2584done
2585
0bac7164
BP
2586# 3. Send an IP packet from every logical port to every other subnet,
2587# to an IP address that does not have a static IP-MAC binding.
2588# This should generate a broadcast ARP request for the destination
2589# IP address in the destination subnet.
2590for is in 1 2 3; do
269ecccc
JP
2591 for js in 1 2 3; do
2592 for ks in 1 2 3; do
2593 s=$is$js$ks
2594 smac=f00000000$s
2595 sip=`ip_to_hex 192 168 $is$js $ks`
2596 for id in 1 2 3; do
2597 for jd in 1 2 3; do
2598 if test $is$js = $id$jd; then
2599 continue
2600 fi
2601
2602 # Send the packet.
2603 dmac=00000000ff$is$js
2604 # Calculate a 4th octet for the destination that is
2605 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2606 # that have static MAC bindings, and fits in the range
2607 # 0-255.
2608 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2609 dip=`ip_to_hex 192 168 $id$jd $o4`
2610 test_ip $s $smac $dmac $sip $dip
2611
2612 # Every LP on the destination subnet's lswitch should
2613 # receive the ARP request.
2614 lrmac=00000000ff$id$jd
2615 lrip=`ip_to_hex 192 168 $id$jd 254`
2616 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2617 for jd2 in 1 2 3; do
2618 for kd in 1 2 3; do
e4543cfe 2619 echo $arp >> $id$jd2$kd.expected
0bac7164 2620 done
269ecccc 2621 done
0bac7164 2622 done
269ecccc 2623 done
0bac7164 2624 done
269ecccc 2625 done
0bac7164
BP
2626done
2627
e3393e3f
BP
2628# test_arp INPORT SHA SPA TPA [REPLY_HA]
2629#
2630# Causes a packet to be received on INPORT. The packet is an ARP
2631# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2632# it should be the hardware address of the target to expect to receive in an
2633# ARP reply; otherwise no reply is expected.
2634#
31ed1192 2635# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2636# SHA and REPLY_HA are each 12 hex digits.
2637# SPA and TPA are each 8 hex digits.
2638test_arp() {
2639 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2640 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2641 hv=hv`vif_to_hv $inport`
2642 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2d9b49dd 2643 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
e3393e3f 2644
57d143eb 2645 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2646 # IP address is not configured to the switch patch port.
e3393e3f 2647 local i=`vif_to_ls $inport`
86e98048 2648 local j k
e3393e3f 2649 for j in 1 2 3; do
86e98048 2650 for k in 1 2 3; do
ea46a4e9 2651 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2652 # so no ARP flooding expected for it.
2653 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2654 echo $request >> $i$j$k.expected
2655 fi
2656 done
e3393e3f
BP
2657 done
2658
2659 # Expect to receive the reply, if any.
2660 if test X$reply_ha != X; then
86e98048
BP
2661 lrp=`vif_to_lrp $inport`
2662 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2663 echo $reply >> $inport.expected
2664 fi
2665}
2666
2667# Test router replies to ARP requests from all source ports:
2668#
0bac7164 2669# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2670#
0bac7164 2671# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2672# in its subnet.
2673#
054008ad 2674# 6. No reply to query for IP address other than router IP.
e3393e3f 2675#
054008ad 2676# 7. No reply to query from another subnet.
e3393e3f 2677for i in 1 2 3; do
269ecccc
JP
2678 for j in 1 2 3; do
2679 for k in 1 2 3; do
2680 smac=f00000000$i$j$k # Source MAC
2681 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2682 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2683 rmac=00000000ff$i$j # Router MAC
2684 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
054008ad
HZ
2685 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2686
2687 test_arp $i$j$k $smac $sip $rip $rmac #4
2688 test_arp $i$j$k $smac $otherip $rip $rmac #5
2689 test_arp $i$j$k $smac $sip $otherip #6
2690
2691 # When rip is 192.168.33.254, ARP request from externalip won't be
2692 # filtered, because 192.168.33.254 is configured to switch peer port
2693 # for lrp33.
2694 lrp33_rsp=
2695 if test $i = 3 && test $j = 3; then
2696 lrp33_rsp=$rmac
2697 fi
2698 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2699
0bac7164 2700 done
269ecccc 2701 done
0bac7164
BP
2702done
2703
2704# Allow some time for packet forwarding.
2705# XXX This can be improved.
2706sleep 1
2707
2708# 8. Generate an ARP reply for each of the IP addresses ARPed for
2709# earlier as #3.
2710#
2711# Here, the $s is the VIF that originated the ARP request and $d is
2712# the VIF that sends the ARP reply, which is somewhat backward but
2713# it means that $s and $d are the same as #3.
2714: > mac_bindings.expected
2715for is in 1 2 3; do
269ecccc
JP
2716 for js in 1 2 3; do
2717 for ks in 1 2 3; do
2718 s=$is$js$ks
2719 for id in 1 2 3; do
2720 for jd in 1 2 3; do
2721 if test $is$js = $id$jd; then
2722 continue
2723 fi
2724
2725 kd=1
2726 d=$id$jd$kd
2727
2728 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2729 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2730 host_mac=8000000000$o4
2731
2732 lrmac=00000000ff$id$jd
2733 lrip=`ip_to_hex 192 168 $id$jd 254`
2734
2735 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2736
2737 echo
2738 echo
2739 echo
2740 hv=hv`vif_to_hv $d`
2741 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2742 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2743 #as $hv ovs-ofctl dump-flows br-int table=19
2744
2745 host_ip_pretty=192.168.$id$jd.$o4
2746 host_mac_pretty=80:00:00:00:00:$o4
2747 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2748 done
269ecccc 2749 done
9975d7be 2750 done
269ecccc 2751 done
9975d7be 2752done
0bac7164 2753
9975d7be
BP
2754# Allow some time for packet forwarding.
2755# XXX This can be improved.
2756sleep 1
2757
0bac7164
BP
2758# 9. Send an IP packet from every logical port to every other subnet. These
2759# are the same packets already sent as #3, but now the destinations' IP-MAC
2760# bindings have been discovered via ARP, so instead of provoking an ARP
2761# request, these packets now get routed to their destinations (which don't
2762# have static MAC bindings, so they go to the port we've designated as
2763# accepting "unknown" MACs.)
2764for is in 1 2 3; do
269ecccc
JP
2765 for js in 1 2 3; do
2766 for ks in 1 2 3; do
2767 s=$is$js$ks
2768 smac=f00000000$s
2769 sip=`ip_to_hex 192 168 $is$js $ks`
2770 for id in 1 2 3; do
2771 for jd in 1 2 3; do
2772 if test $is$js = $id$jd; then
2773 continue
2774 fi
2775
2776 # Send the packet.
2777 dmac=00000000ff$is$js
2778 # Calculate a 4th octet for the destination that is
2779 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2780 # that have static MAC bindings, and fits in the range
2781 # 0-255.
2782 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2783 dip=`ip_to_hex 192 168 $id$jd $o4`
2784 test_ip $s $smac $dmac $sip $dip
2785
2786 # Expect the packet egress.
2787 host_mac=8000000000$o4
2788 outport=${id}11
2789 out_lrp=$id$jd
e4543cfe 2790 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2791 done
269ecccc 2792 done
0bac7164 2793 done
269ecccc 2794 done
0bac7164
BP
2795done
2796
0bac7164
BP
2797ovn-sbctl -f csv -d bare --no-heading \
2798 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2799
9975d7be
BP
2800# Now check the packets actually received against the ones expected.
2801for i in 1 2 3; do
2802 for j in 1 2 3; do
86e98048 2803 for k in 1 2 3; do
abb37b6b
FF
2804 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2805 [$i$j$k.expected])
86e98048 2806 done
9975d7be
BP
2807 done
2808done
fcde56f5 2809
0bac7164
BP
2810# Check the MAC bindings against those expected.
2811AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2812])
2813
fcde56f5 2814# Gracefully terminate daemons
7a8f15e0 2815OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2816
9975d7be 2817AT_CLEANUP
685f4dfe
NS
2818
2819# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2820AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
2821AT_SKIP_IF([test $HAVE_PYTHON = no])
2822ovn_start
2823
2824# Create hypervisors hv[123].
2825# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2826# Add all of the vifs to a single logical switch lsw0.
2827# Turn off port security on vifs vif[123]1
2828# Turn on l2 port security on vifs vif[123]2
2829# Turn of l2 and l3 port security on vifs vif[123]3
2830# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 2831ovn-nbctl ls-add lsw0
685f4dfe
NS
2832net_add n1
2833for i in 1 2 3; do
2834 sim_add hv$i
2835 as hv$i
2836 ovs-vsctl add-br br-phys
2837 ovn_attach n1 br-phys 192.168.0.$i
2838
2839 for j in 1 2 3; do
2840 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 2841 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 2842 if test $j = 1; then
31ed1192 2843 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 2844 elif test $j = 2; then
31ed1192
JP
2845 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2846 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
2847 else
2848 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
2849 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2850 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
2851 fi
2852 done
2853done
2854
685f4dfe
NS
2855# Pre-populate the hypervisors' ARP tables so that we don't lose any
2856# packets for ARP resolution (native tunneling doesn't queue packets
2857# for ARP resolution).
74868f2c 2858OVN_POPULATE_ARP
685f4dfe
NS
2859
2860# Allow some time for ovn-northd and ovn-controller to catch up.
2861# XXX This should be more systematic.
2862sleep 1
685f4dfe
NS
2863
2864# Given the name of a logical port, prints the name of the hypervisor
2865# on which it is located.
2866vif_to_hv() {
2867 echo hv${1%?}
2868}
2869
685f4dfe
NS
2870for i in 1 2 3; do
2871 for j in 1 2 3; do
2872 : > $i$j.expected
2873 done
2874done
2875
2876# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2877#
2878# This shell function causes an ip packet to be received on INPORT.
2879# The packet's content has Ethernet destination DST and source SRC
2880# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2881# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2882# be received. INPORT and the OUTPORTs are specified as logical switch
2883# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2884test_ip() {
2885 # This packet has bad checksums but logical L3 routing doesn't check.
2886 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 2887 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
2888 shift; shift; shift; shift; shift
2889 hv=`vif_to_hv $inport`
2890 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2891 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2892 for outport; do
e4543cfe 2893 echo $packet >> $outport.expected
685f4dfe
NS
2894 done
2895}
2896
2897# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2898#
2899# Causes a packet to be received on INPORT. The packet is an ARP
2900# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2901# it should be the hardware address of the target to expect to receive in an
2902# ARP reply; otherwise no reply is expected.
2903#
31ed1192 2904# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2905# SHA and REPLY_HA are each 12 hex digits.
2906# SPA and TPA are each 8 hex digits.
2907test_arp() {
2908 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2909 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2910 hv=`vif_to_hv $inport`
2911 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2912 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2913 if test $drop != 1; then
e137131a 2914 if test X$reply_ha = X; then
685f4dfe
NS
2915 # Expect to receive the broadcast ARP on the other logical switch ports
2916 # if no reply is expected.
2917 local i j
2918 for i in 1 2 3; do
2919 for j in 1 2 3; do
2920 if test $i$j != $inport; then
2921 echo $request >> $i$j.expected
2922 fi
2923 done
2924 done
2925 else
2926 # Expect to receive the reply, if any.
2927 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2928 echo $reply >> $inport.expected
2929 fi
2930 fi
2931}
2932
2933# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2934# This function is similar to test_ip() except that it sends
2935# ipv6 packet
2936test_ipv6() {
2937 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2938 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2939 shift; shift; shift; shift; shift
2940 hv=`vif_to_hv $inport`
2941 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2942 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2943 for outport; do
e4543cfe 2944 echo $packet >> $outport.expected
685f4dfe
NS
2945 done
2946}
2947
9e687b23
DL
2948# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2949# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2950# of the test packet
2951test_icmpv6() {
2952 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2953 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2954 shift; shift; shift; shift; shift; shift
2955 hv=`vif_to_hv $inport`
2956 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2957 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2958 for outport; do
e4543cfe 2959 echo $packet >> $outport.expected
9e687b23
DL
2960 done
2961}
2962
685f4dfe
NS
2963ip_to_hex() {
2964 printf "%02x%02x%02x%02x" "$@"
2965}
2966
2967# no port security
2968sip=`ip_to_hex 192 168 0 12`
2969tip=`ip_to_hex 192 168 0 13`
2970# the arp packet should be allowed even if lp[123]1 is
2971# not configured with mac f00000000023 and ip 192.168.0.12
2972for i in 1 2 3; do
2973 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2974 for j in 1 2 3; do
2975 if test $i != $j; then
2976 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2977 fi
2978 done
2979done
2980
2981# l2 port security
2982sip=`ip_to_hex 192 168 0 12`
2983tip=`ip_to_hex 192 168 0 13`
2984
2985# arp packet should be allowed since lp22 is configured with
2986# mac f00000000022
2987test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2988
2989# arp packet should not be allowed since lp32 is not configured with
2990# mac f00000000021
2991test_arp 32 f00000000021 f00000000021 $sip $tip 1
2992
2993# arp packet with sha set to f00000000021 should not be allowed
2994# for lp12
2995test_arp 12 f00000000012 f00000000021 $sip $tip 1
2996
2997# ip packets should be allowed and received since lp[123]2 do not
2998# have l3 port security
2999sip=`ip_to_hex 192 168 0 55`
3000tip=`ip_to_hex 192 168 0 66`
3001for i in 1 2 3; do
3002 for j in 1 2 3; do
3003 if test $i != $j; then
3004 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3005 fi
3006 done
3007done
3008
3009# ipv6 packets should be received by lp[123]2
3010# lp[123]1 can send ipv6 traffic as there is no port security
3011sip=fe800000000000000000000000000000
3012tip=ff020000000000000000000000000000
3013
3014for i in 1 2 3; do
3015 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3016done
3017
3018
3019# l2 and l3 port security
3020sip=`ip_to_hex 192 168 0 13`
3021tip=`ip_to_hex 192 168 0 22`
3022# arp packet should be allowed since lp13 is configured with
3023# f00000000013 and 192.168.0.13
3024test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3025
3026# the arp packet should be dropped because lp23 is not configured
3027# with mac f00000000022
3028sip=`ip_to_hex 192 168 0 13`
3029tip=`ip_to_hex 192 168 0 22`
3030test_arp 23 f00000000022 f00000000022 $sip $tip 1
3031
3032# the arp packet should be dropped because lp33 is not configured
3033# with ip 192.168.0.55
3034spa=`ip_to_hex 192 168 0 55`
3035tpa=`ip_to_hex 192 168 0 22`
3036test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3037
3038# ip packets should not be received by lp[123]3 since
3039# l3 port security is enabled
3040sip=`ip_to_hex 192 168 0 55`
3041tip=`ip_to_hex 192 168 0 66`
3042for i in 1 2 3; do
3043 for j in 1 2 3; do
3044 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3045 done
3046done
3047
3048# ipv6 packets should be dropped for lp[123]3 since
3049# it is configured with only ipv4 address
3050sip=fe800000000000000000000000000000
3051tip=ff020000000000000000000000000000
3052
3053for i in 1 2 3; do
3054 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3055done
3056
3057# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3058# lp[123]1 can send ipv6 traffic as there is no port security
3059for i in 1 2 3; do
3060 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3061done
3062
3063# lp13 has extra port security with mac f0000000113 and ipv6 addr
3064# fe80::ea2a:eaff:fe28:0012
3065
3066# ipv4 packet should be dropped for lp13 with mac f0000000113
3067sip=`ip_to_hex 192 168 0 13`
3068tip=`ip_to_hex 192 168 0 23`
3069test_ip 13 f00000000113 f00000000023 $sip $tip
3070
6d53e8a9
BP
3071# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3072# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
3073# lp11 can send ipv6 traffic as there is no port security
3074sip=ee800000000000000000000000000000
3075for i in 1 2 3; do
6d53e8a9
BP
3076 tip=fe80000000000000ea2aeafffe2800${i}3
3077 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
3078done
3079
3080
3081# ipv6 packet should not be received by lp33 with mac f0000000333
3082# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3083# configured with fe80::ea2a:eaff:fe28:0033
3084# lp11 can send ipv6 traffic as there is no port security
3085
3086sip=ee800000000000000000000000000000
3087tip=fe80000000000000ea2aeafffe280023
3088test_ipv6 11 f00000000011 f00000000333 $sip $tip
3089
6d53e8a9
BP
3090# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3091# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
3092# and should be dropped for any other ip6.src
3093# lp21 can receive ipv6 traffic as there is no port security
3094
3095tip=ee800000000000000000000000000000
3096for i in 1 2 3; do
3097 sip=fe80000000000000ea2aeafffe2800${i}3
3098 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3099
9e687b23 3100 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 3101 sip=00000000000000000000000000000000
9e687b23
DL
3102 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3103 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3104 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3105 # Traffic to non-multicast traffic should be dropped
3106 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3107 # Traffic of other ICMPv6 types should be dropped
3108 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
3109
3110 # should be dropped
3111 sip=ae80000000000000ea2aeafffe2800aa
3112 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3113done
3114
31ed1192
JP
3115# configure lsp13 to send and received IPv4 packets with an address range
3116ovn-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 3117
8ff5a966
NS
3118sleep 2
3119
7d9d86ad
NS
3120sip=`ip_to_hex 10 0 0 13`
3121tip=`ip_to_hex 192 168 0 22`
31ed1192 3122# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
3123test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3124
3125sip=`ip_to_hex 10 0 0 14`
3126tip=`ip_to_hex 192 168 0 23`
31ed1192 3127# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
3128# with dst ip 192.168.0.23 should be allowed
3129test_ip 13 f00000000013 f00000000023 $sip $tip 23
3130
3131sip=`ip_to_hex 192 168 0 33`
3132tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
3133# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3134# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
3135test_ip 33 f00000000033 f00000000013 $sip $tip 13
3136
3137sip=`ip_to_hex 192 168 0 33`
3138tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
3139# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3140# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
3141test_ip 33 f00000000033 f00000000013 $sip $tip 13
3142
3143sip=`ip_to_hex 192 168 0 33`
3144tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
3145# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3146# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
3147test_ip 33 f00000000033 f00000000013 $sip $tip
3148
3149sip=`ip_to_hex 192 168 0 33`
3150tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
3151# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3152# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
3153test_ip 33 f00000000033 f00000000013 $sip $tip 13
3154
3155sip=`ip_to_hex 192 168 0 33`
3156tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
3157# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3158# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
3159test_ip 33 f00000000033 f00000000013 $sip $tip
3160
3161sip=`ip_to_hex 192 168 0 33`
3162tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
3163# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3164# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 3165test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 3166
bb0c41d3
RM
3167#dump information including flow counters
3168ovn-nbctl show
3169ovn-sbctl dump-flows -- list multicast_group
3170
3171echo "------ hv1 dump ------"
3172as hv1 ovs-vsctl show
6195e2e7 3173as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3174as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3175
3176echo "------ hv2 dump ------"
3177as hv2 ovs-vsctl show
6195e2e7 3178as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3179as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3180
3181echo "------ hv3 dump ------"
3182as hv3 ovs-vsctl show
6195e2e7 3183as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3184as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3185
685f4dfe
NS
3186# Now check the packets actually received against the ones expected.
3187for i in 1 2 3; do
3188 for j in 1 2 3; do
49d7c759 3189 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
3190 done
3191done
3192
7a8f15e0 3193OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 3194
685f4dfe 3195AT_CLEANUP
509afdc3
GS
3196
3197AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
3198AT_SKIP_IF([test $HAVE_PYTHON = no])
3199ovn_start
3200
3201# Logical network:
3202# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3203# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3204# R2 has ls2 (172.16.1.0/24) connected to it.
3205
3c1ae70a
JP
3206ls1_lp1_mac="f0:00:00:01:02:03"
3207rp_ls1_mac="00:00:00:01:02:03"
3208rp_ls2_mac="00:00:00:01:02:04"
3209ls2_lp1_mac="f0:00:00:01:02:04"
3210
3211ls1_lp1_ip="192.168.1.2"
3212ls2_lp1_ip="172.16.1.2"
3213
fa2a27b2
JP
3214ovn-nbctl lr-add R1
3215ovn-nbctl lr-add R2
509afdc3 3216
ea46a4e9
JP
3217ovn-nbctl ls-add ls1
3218ovn-nbctl ls-add ls2
509afdc3
GS
3219
3220# Connect ls1 to R1
3c1ae70a 3221ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
509afdc3 3222
31ed1192 3223ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3c1ae70a 3224 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
509afdc3
GS
3225
3226# Connect ls2 to R2
3c1ae70a 3227ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
509afdc3 3228
31ed1192 3229ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3c1ae70a 3230 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
509afdc3
GS
3231
3232# Connect R1 to R2
4685e523
JP
3233ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3234ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 3235
6d9ecfa9
JP
3236ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3237ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
3238
3239# Create logical port ls1-lp1 in ls1
31ed1192 3240ovn-nbctl lsp-add ls1 ls1-lp1 \
3c1ae70a 3241-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
509afdc3
GS
3242
3243# Create logical port ls2-lp1 in ls2
31ed1192 3244ovn-nbctl lsp-add ls2 ls2-lp1 \
3c1ae70a 3245-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
509afdc3
GS
3246
3247# Create two hypervisor and create OVS ports corresponding to logical ports.
3248net_add n1
3249
3250sim_add hv1
3251as hv1
3252ovs-vsctl add-br br-phys
3253ovn_attach n1 br-phys 192.168.0.1
3254ovs-vsctl -- add-port br-int hv1-vif1 -- \
3255 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3256 options:tx_pcap=hv1/vif1-tx.pcap \
3257 options:rxq_pcap=hv1/vif1-rx.pcap \
3258 ofport-request=1
3259
3260sim_add hv2
3261as hv2
3262ovs-vsctl add-br br-phys
3263ovn_attach n1 br-phys 192.168.0.2
3264ovs-vsctl -- add-port br-int hv2-vif1 -- \
3265 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3266 options:tx_pcap=hv2/vif1-tx.pcap \
3267 options:rxq_pcap=hv2/vif1-rx.pcap \
3268 ofport-request=1
3269
3270
3271# Pre-populate the hypervisors' ARP tables so that we don't lose any
3272# packets for ARP resolution (native tunneling doesn't queue packets
3273# for ARP resolution).
74868f2c 3274OVN_POPULATE_ARP
509afdc3
GS
3275
3276# Allow some time for ovn-northd and ovn-controller to catch up.
3277# XXX This should be more systematic.
3278sleep 1
3279
509afdc3 3280# Packet to send.
3c1ae70a
JP
3281packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3282 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3283 udp && udp.src==53 && udp.dst==4369"
3284as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
509afdc3
GS
3285
3286
3287echo "---------NB dump-----"
3288ovn-nbctl show
3289echo "---------------------"
3290ovn-nbctl list logical_router
3291echo "---------------------"
3292ovn-nbctl list logical_router_port
3293echo "---------------------"
3294
3295echo "---------SB dump-----"
3296ovn-sbctl list datapath_binding
3297echo "---------------------"
3298ovn-sbctl list port_binding
3299echo "---------------------"
3300
3301echo "------ hv1 dump ----------"
8dab1022 3302as hv1 ovs-ofctl show br-int
509afdc3
GS
3303as hv1 ovs-ofctl dump-flows br-int
3304echo "------ hv2 dump ----------"
8dab1022 3305as hv2 ovs-ofctl show br-int
509afdc3
GS
3306as hv2 ovs-ofctl dump-flows br-int
3307
3308# Packet to Expect
3c1ae70a
JP
3309# The TTL should be decremented by 2.
3310packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3311 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3312 udp && udp.src==53 && udp.dst==4369"
3313echo $packet | ovstest test-ovn expr-to-packets > expected
509afdc3 3314
49d7c759 3315OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 3316
7ebfcd3d
NS
3317AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3318grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3319])
3320
3321# Disable the ls2-lp1 port.
3322ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3323
3324AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3325grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3326])
3327
3328# Generate the packet destined for ls2-lp1 and it should not be delivered.
3329# Packet to send.
3330packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3331 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3332 udp && udp.src==53 && udp.dst==4369"
3333
3334as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3335# The 2nd packet sent shound not be received.
3336OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3337
7a8f15e0 3338OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
3339
3340AT_CLEANUP
5412db30
J
3341
3342
4685e523
JP
3343AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3344AT_KEYWORDS([router-admin-state])
3345AT_SKIP_IF([test $HAVE_PYTHON = no])
3346ovn_start
3347
3348# Logical network:
3349# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3350# and 172.16.1.0/24) connected to it.
3351
3352ovn-nbctl lr-add R1
3353
3354ovn-nbctl ls-add ls1
3355
3356# Connect ls1 to R1
bf44c2cd 3357ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
3358ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3359 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3360
3361# Create logical port ls1-lp1 in ls1
3362ovn-nbctl lsp-add ls1 ls1-lp1 \
3363 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3364
3365# Create logical port ls1-lp2 in ls1
3366ovn-nbctl lsp-add ls1 ls1-lp2 \
3367 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3368
3369# Create one hypervisor and create OVS ports corresponding to logical ports.
3370net_add n1
3371
3372sim_add hv1
3373as hv1
3374ovs-vsctl add-br br-phys
3375ovn_attach n1 br-phys 192.168.0.1
3376ovs-vsctl -- add-port br-int vif1 -- \
3377 set interface vif1 external-ids:iface-id=ls1-lp1 \
3378 options:tx_pcap=hv1/vif1-tx.pcap \
3379 options:rxq_pcap=hv1/vif1-rx.pcap \
3380 ofport-request=1
3381
3382ovs-vsctl -- add-port br-int vif2 -- \
3383 set interface vif2 external-ids:iface-id=ls1-lp2 \
3384 options:tx_pcap=hv1/vif2-tx.pcap \
3385 options:rxq_pcap=hv1/vif2-rx.pcap \
3386 ofport-request=1
3387
3388
3389# Allow some time for ovn-northd and ovn-controller to catch up.
3390# XXX This should be more systematic.
3391sleep 1
3392
3393# Send ip packets between the two ports.
3394ip_to_hex() {
3395 printf "%02x%02x%02x%02x" "$@"
3396}
4685e523
JP
3397
3398# Packet to send.
3399src_mac="f00000010203"
3400dst_mac="000000010203"
3401src_ip=`ip_to_hex 192 168 1 2`
3402dst_ip=`ip_to_hex 172 16 1 2`
3403packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3404as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3405
3406
3407echo "---------NB dump-----"
3408ovn-nbctl show
3409echo "---------------------"
3410ovn-nbctl list logical_router
3411echo "---------------------"
3412ovn-nbctl list logical_router_port
3413echo "---------------------"
3414
3415echo "---------SB dump-----"
3416ovn-sbctl list datapath_binding
3417echo "---------------------"
3418ovn-sbctl list logical_flow
3419echo "---------------------"
3420
3421echo "------ hv1 dump ----------"
3422as hv1 ovs-ofctl dump-flows br-int
3423
3424
3425#Disable router R1
3426ovn-nbctl set Logical_Router R1 enabled=false
3427
3b8cd0ea
BP
3428# Allow some time for ovn-northd and ovn-controller to catch up.
3429# XXX This should be more systematic.
3430sleep 1
3431
4685e523
JP
3432echo "---------SB dump-----"
3433ovn-sbctl list datapath_binding
3434echo "---------------------"
3435ovn-sbctl list logical_flow
3436echo "---------------------"
3437
3438echo "------ hv1 dump ----------"
3439as hv1 ovs-ofctl dump-flows br-int
3440
3441as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3442
3443# Packet to Expect
3444expect_src_mac="000000010203"
3445expect_dst_mac="f00000010204"
49d7c759 3446echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3447
49d7c759 3448OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
3449
3450
3451as hv1
3452OVS_APP_EXIT_AND_WAIT([ovn-controller])
3453OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3454OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3455
3456as ovn-sb
3457OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3458
3459as ovn-nb
3460OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3461
3462as northd
3463OVS_APP_EXIT_AND_WAIT([ovn-northd])
3464
3465as main
3466OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3467OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3468
3469AT_CLEANUP
3470
3471
3472AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3473AT_KEYWORDS([router-admin-state])
3474AT_SKIP_IF([test $HAVE_PYTHON = no])
3475ovn_start
3476
3477# Logical network:
3478# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3479# and has switch ls2 (172.16.1.0/24) connected to it.
3480
fa2a27b2 3481ovn-nbctl lr-add R1
5412db30 3482
ea46a4e9
JP
3483ovn-nbctl ls-add ls1
3484ovn-nbctl ls-add ls2
5412db30
J
3485
3486# Connect ls1 to R1
bf44c2cd 3487ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3488ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3489 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3490
3491# Connect ls2 to R1
bf44c2cd 3492ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3493ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3494 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3495
3496# Create logical port ls1-lp1 in ls1
31ed1192
JP
3497ovn-nbctl lsp-add ls1 ls1-lp1 \
3498-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3499
3500# Create logical port ls2-lp1 in ls2
31ed1192
JP
3501ovn-nbctl lsp-add ls2 ls2-lp1 \
3502-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3503
3504# Create one hypervisor and create OVS ports corresponding to logical ports.
3505net_add n1
3506
3507sim_add hv1
3508as hv1
3509ovs-vsctl add-br br-phys
3510ovn_attach n1 br-phys 192.168.0.1
3511ovs-vsctl -- add-port br-int vif1 -- \
3512 set interface vif1 external-ids:iface-id=ls1-lp1 \
3513 options:tx_pcap=hv1/vif1-tx.pcap \
3514 options:rxq_pcap=hv1/vif1-rx.pcap \
3515 ofport-request=1
3516
3517ovs-vsctl -- add-port br-int vif2 -- \
3518 set interface vif2 external-ids:iface-id=ls2-lp1 \
3519 options:tx_pcap=hv1/vif2-tx.pcap \
3520 options:rxq_pcap=hv1/vif2-rx.pcap \
3521 ofport-request=1
3522
3523
3524# Allow some time for ovn-northd and ovn-controller to catch up.
3525# XXX This should be more systematic.
3526sleep 1
3527
3528# Send ip packets between the two ports.
3529ip_to_hex() {
3530 printf "%02x%02x%02x%02x" "$@"
3531}
5412db30
J
3532
3533# Packet to send.
3534src_mac="f00000010203"
3535dst_mac="000000010203"
3536src_ip=`ip_to_hex 192 168 1 2`
3537dst_ip=`ip_to_hex 172 16 1 2`
3538packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3539as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3540
3541
3542echo "---------NB dump-----"
3543ovn-nbctl show
3544echo "---------------------"
3545ovn-nbctl list logical_router
3546echo "---------------------"
3547ovn-nbctl list logical_router_port
3548echo "---------------------"
3549
3550echo "---------SB dump-----"
3551ovn-sbctl list datapath_binding
3552echo "---------------------"
3553ovn-sbctl list logical_flow
3554echo "---------------------"
3555
3556echo "------ hv1 dump ----------"
3557as hv1 ovs-ofctl dump-flows br-int
3558
5412db30
J
3559#Disable router R1
3560ovn-nbctl set Logical_Router R1 enabled=false
3561
3562echo "---------SB dump-----"
3563ovn-sbctl list datapath_binding
3564echo "---------------------"
3565ovn-sbctl list logical_flow
3566echo "---------------------"
3567
3568echo "------ hv1 dump ----------"
3569as hv1 ovs-ofctl dump-flows br-int
3570
a1361a6e
LR
3571# Allow some time for the disabling of logical router R1 to propagate.
3572# XXX This should be more systematic.
3573sleep 1
3574
5412db30
J
3575as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3576
3577# Packet to Expect
3578expect_src_mac="000000010204"
3579expect_dst_mac="f00000010204"
49d7c759 3580echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3581
49d7c759 3582OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3583
7a8f15e0 3584OVN_CLEANUP([hv1])
5412db30
J
3585
3586AT_CLEANUP
3587
28dc3fe9 3588AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3589AT_SKIP_IF([test $HAVE_PYTHON = no])
3590ovn_start
3591
3592# Logical network:
3593# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3594# network. R1 has switchess foo (192.168.1.0/24)
3595# connected to it.
3596# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3597
fa2a27b2
JP
3598ovn-nbctl lr-add R1
3599ovn-nbctl lr-add R2
28dc3fe9 3600
ea46a4e9
JP
3601ovn-nbctl ls-add foo
3602ovn-nbctl ls-add alice
3603ovn-nbctl ls-add bob
28dc3fe9
SR
3604
3605# Connect foo to R1
bf44c2cd 3606ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3607ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3608 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3609
3610# Connect alice to R2
bf44c2cd 3611ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3612ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3613 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3614
3615# Connect bob to R2
bf44c2cd 3616ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3617ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3618 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3619
3620# Connect R1 to R2
4685e523
JP
3621ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3622ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3623
3624#install static routes
e48ccf3c
JP
3625ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3626ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3627ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3628
3629# Create logical port foo1 in foo
31ed1192
JP
3630ovn-nbctl lsp-add foo foo1 \
3631-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3632
3633# Create logical port alice1 in alice
31ed1192
JP
3634ovn-nbctl lsp-add alice alice1 \
3635-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3636
3637# Create logical port bob1 in bob
31ed1192
JP
3638ovn-nbctl lsp-add bob bob1 \
3639-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3640
3641# Create two hypervisor and create OVS ports corresponding to logical ports.
3642net_add n1
3643
3644sim_add hv1
3645as hv1
3646ovs-vsctl add-br br-phys
3647ovn_attach n1 br-phys 192.168.0.1
3648ovs-vsctl -- add-port br-int hv1-vif1 -- \
3649 set interface hv1-vif1 external-ids:iface-id=foo1 \
3650 options:tx_pcap=hv1/vif1-tx.pcap \
3651 options:rxq_pcap=hv1/vif1-rx.pcap \
3652 ofport-request=1
3653
3654ovs-vsctl -- add-port br-int hv1-vif2 -- \
3655 set interface hv1-vif2 external-ids:iface-id=alice1 \
3656 options:tx_pcap=hv1/vif2-tx.pcap \
3657 options:rxq_pcap=hv1/vif2-rx.pcap \
3658 ofport-request=2
3659
3660sim_add hv2
3661as hv2
3662ovs-vsctl add-br br-phys
3663ovn_attach n1 br-phys 192.168.0.2
3664ovs-vsctl -- add-port br-int hv2-vif1 -- \
3665 set interface hv2-vif1 external-ids:iface-id=bob1 \
3666 options:tx_pcap=hv2/vif1-tx.pcap \
3667 options:rxq_pcap=hv2/vif1-rx.pcap \
3668 ofport-request=1
3669
3670
3671# Pre-populate the hypervisors' ARP tables so that we don't lose any
3672# packets for ARP resolution (native tunneling doesn't queue packets
3673# for ARP resolution).
74868f2c 3674OVN_POPULATE_ARP
28dc3fe9
SR
3675
3676# Allow some time for ovn-northd and ovn-controller to catch up.
3677# XXX This should be more systematic.
3678sleep 1
3679
3680ip_to_hex() {
3681 printf "%02x%02x%02x%02x" "$@"
3682}
28dc3fe9
SR
3683
3684# Send ip packets between foo1 and alice1
3685src_mac="f00000010203"
3686dst_mac="000000010203"
3687src_ip=`ip_to_hex 192 168 1 2`
3688dst_ip=`ip_to_hex 172 16 1 2`
3689packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3690as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3691
3692# Send ip packets between foo1 and bob1
3693src_mac="f00000010203"
3694dst_mac="000000010203"
3695src_ip=`ip_to_hex 192 168 1 2`
3696dst_ip=`ip_to_hex 172 16 2 2`
3697packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3698as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3699
3700echo "---------NB dump-----"
3701ovn-nbctl show
3702echo "---------------------"
3703ovn-nbctl list logical_router
3704echo "---------------------"
3705ovn-nbctl list logical_router_port
3706echo "---------------------"
3707
3708echo "---------SB dump-----"
3709ovn-sbctl list datapath_binding
3710echo "---------------------"
3711ovn-sbctl list port_binding
3712echo "---------------------"
3713
3714echo "------ hv1 dump ----------"
3715as hv1 ovs-ofctl dump-flows br-int
3716echo "------ hv2 dump ----------"
3717as hv2 ovs-ofctl dump-flows br-int
3718
3719# Packet to Expect at bob1
3720src_mac="000000010205"
3721dst_mac="f00000010205"
3722src_ip=`ip_to_hex 192 168 1 2`
3723dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3724echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3725
49d7c759 3726OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3727
3728# Packet to Expect at alice1
3729src_mac="000000010204"
3730dst_mac="f00000010204"
3731src_ip=`ip_to_hex 192 168 1 2`
3732dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3733echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3734
49d7c759 3735OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3736
7a8f15e0 3737OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3738
3739AT_CLEANUP
5412db30 3740
0ee8aaf6 3741AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3742AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3743ovn_start
ea46a4e9 3744ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3745net_add n1
3746sim_add hv
3747as hv
3748ovs-vsctl \
3749 -- add-br br-phys \
3750 -- add-br br-eth0
3751
3752ovn_attach n1 br-phys 192.168.0.1
3753
3754AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3755AT_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])
3756
3757# Create a vif.
31ed1192
JP
3758AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3759AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3760AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3761
3762# Create a localnet port.
31ed1192
JP
3763AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3764AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3765AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3766AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3767
3768AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3769
3770# Wait for packet to be received.
49d7c759
BP
3771echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3772OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6 3773
5b57e12a
GL
3774# Check GARP packet when restart openflow connection.
3775as hv
3776OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3777
3778OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3779
3780as hv
3781start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3782
3783# Wait for packet to be received.
3784echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3785OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3786
0ee8aaf6
RR
3787# Delete the localnet ports.
3788AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3789AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3790
7a8f15e0 3791OVN_CLEANUP([hv])
0ee8aaf6
RR
3792
3793AT_CLEANUP
75cf9d2b
GS
3794
3795AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
3796AT_SKIP_IF([test $HAVE_PYTHON = no])
3797ovn_start
3798
3799# Logical network:
3800# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3801# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3802# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3803# connected to it.
3804
fa2a27b2
JP
3805ovn-nbctl lr-add R1
3806ovn-nbctl lr-add R2
3807ovn-nbctl lr-add R3
75cf9d2b 3808
ea46a4e9
JP
3809ovn-nbctl ls-add foo
3810ovn-nbctl ls-add alice
3811ovn-nbctl ls-add bob
3812ovn-nbctl ls-add join
75cf9d2b
GS
3813
3814# Connect foo to R1
31114af7 3815ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3816ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3817 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
3818
3819# Connect alice to R2
31114af7 3820ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3821ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3822 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
3823
3824# Connect bob to R3
31114af7 3825ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 3826ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 3827 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
3828
3829# Connect R1 to join
31114af7 3830ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3831ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3832 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
3833
3834# Connect R2 to join
31114af7 3835ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3836ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3837 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
3838
3839# Connect R3 to join
31114af7 3840ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 3841ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 3842 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
3843
3844#install static routes
e48ccf3c
JP
3845ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3846ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 3847
e48ccf3c
JP
3848ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3849ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 3850
e48ccf3c
JP
3851ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3852ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
3853
3854# Create logical port foo1 in foo
31ed1192
JP
3855ovn-nbctl lsp-add foo foo1 \
3856-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
3857
3858# Create logical port alice1 in alice
31ed1192
JP
3859ovn-nbctl lsp-add alice alice1 \
3860-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
3861
3862# Create logical port bob1 in bob
31ed1192
JP
3863ovn-nbctl lsp-add bob bob1 \
3864-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
3865
3866# Create two hypervisor and create OVS ports corresponding to logical ports.
3867net_add n1
3868
3869sim_add hv1
3870as hv1
3871ovs-vsctl add-br br-phys
3872ovn_attach n1 br-phys 192.168.0.1
3873ovs-vsctl -- add-port br-int hv1-vif1 -- \
3874 set interface hv1-vif1 external-ids:iface-id=foo1 \
3875 options:tx_pcap=hv1/vif1-tx.pcap \
3876 options:rxq_pcap=hv1/vif1-rx.pcap \
3877 ofport-request=1
3878
3879ovs-vsctl -- add-port br-int hv1-vif2 -- \
3880 set interface hv1-vif2 external-ids:iface-id=alice1 \
3881 options:tx_pcap=hv1/vif2-tx.pcap \
3882 options:rxq_pcap=hv1/vif2-rx.pcap \
3883 ofport-request=2
3884
3885sim_add hv2
3886as hv2
3887ovs-vsctl add-br br-phys
3888ovn_attach n1 br-phys 192.168.0.2
3889ovs-vsctl -- add-port br-int hv2-vif1 -- \
3890 set interface hv2-vif1 external-ids:iface-id=bob1 \
3891 options:tx_pcap=hv2/vif1-tx.pcap \
3892 options:rxq_pcap=hv2/vif1-rx.pcap \
3893 ofport-request=1
3894
3895
3896# Pre-populate the hypervisors' ARP tables so that we don't lose any
3897# packets for ARP resolution (native tunneling doesn't queue packets
3898# for ARP resolution).
74868f2c 3899OVN_POPULATE_ARP
75cf9d2b
GS
3900
3901# Allow some time for ovn-northd and ovn-controller to catch up.
3902# XXX This should be more systematic.
3903sleep 1
3904
3905ip_to_hex() {
3906 printf "%02x%02x%02x%02x" "$@"
3907}
75cf9d2b
GS
3908
3909# Send ip packets between foo1 and alice1
3910src_mac="f00000010203"
3911dst_mac="000001010203"
3912src_ip=`ip_to_hex 192 168 1 2`
3913dst_ip=`ip_to_hex 172 16 1 2`
3914packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3915as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3916as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3917
3918# Send ip packets between foo1 and bob1
3919src_mac="f00000010203"
3920dst_mac="000001010203"
3921src_ip=`ip_to_hex 192 168 1 2`
3922dst_ip=`ip_to_hex 10 32 1 2`
3923packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3924as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3925
3926echo "---------NB dump-----"
3927ovn-nbctl show
3928echo "---------------------"
3929ovn-nbctl list logical_router
3930echo "---------------------"
3931ovn-nbctl list logical_router_port
3932echo "---------------------"
3933
3934echo "---------SB dump-----"
3935ovn-sbctl list datapath_binding
3936echo "---------------------"
3937ovn-sbctl list port_binding
3938echo "---------------------"
3939ovn-sbctl dump-flows
3940echo "---------------------"
3941
3942echo "------ hv1 dump ----------"
3943as hv1 ovs-ofctl show br-int
3944as hv1 ovs-ofctl dump-flows br-int
3945echo "------ hv2 dump ----------"
3946as hv2 ovs-ofctl show br-int
3947as hv2 ovs-ofctl dump-flows br-int
3948echo "----------------------------"
3949
3950# Packet to Expect at bob1
3951src_mac="000003010203"
3952dst_mac="f00000010205"
3953src_ip=`ip_to_hex 192 168 1 2`
3954dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 3955echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3956
49d7c759 3957OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
3958
3959# Packet to Expect at alice1
3960src_mac="000002010203"
3961dst_mac="f00000010204"
3962src_ip=`ip_to_hex 192 168 1 2`
3963dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3964echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3965
49d7c759 3966OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 3967
7a8f15e0 3968OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
3969
3970AT_CLEANUP
c1645003 3971
281977f7 3972AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
3973AT_SKIP_IF([test $HAVE_PYTHON = no])
3974ovn_start
3975
3976ovn-nbctl ls-add ls1
3977
3978ovn-nbctl lsp-add ls1 ls1-lp1 \
3979-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3980
3981ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3982
3983ovn-nbctl lsp-add ls1 ls1-lp2 \
3984-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3985
3986ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3987
3988ovn-nbctl ls-add ls2
3989ovn-nbctl lsp-add ls2 ls2-lp1 \
3990-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3991ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3992ovn-nbctl lsp-add ls2 ls2-lp2 \
3993-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3994ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3995
9060fc9a 3996d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
281977f7 3997options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
9060fc9a 3998\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
281977f7 3999
9060fc9a
MM
4000ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4001ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4002
4003d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
281977f7 4004options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
9060fc9a
MM
4005\"lease_time\"=\"3600\"")"
4006
4007ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
281977f7
NS
4008
4009net_add n1
4010sim_add hv1
4011
4012as hv1
4013ovs-vsctl add-br br-phys
4014ovn_attach n1 br-phys 192.168.0.1
4015ovs-vsctl -- add-port br-int hv1-vif1 -- \
4016 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4017 options:tx_pcap=hv1/vif1-tx.pcap \
4018 options:rxq_pcap=hv1/vif1-rx.pcap \
4019 ofport-request=1
4020
4021ovs-vsctl -- add-port br-int hv1-vif2 -- \
4022 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4023 options:tx_pcap=hv1/vif2-tx.pcap \
4024 options:rxq_pcap=hv1/vif2-rx.pcap \
4025 ofport-request=2
4026
4027ovs-vsctl -- add-port br-int hv1-vif3 -- \
4028 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4029 options:tx_pcap=hv1/vif3-tx.pcap \
4030 options:rxq_pcap=hv1/vif3-rx.pcap \
4031 ofport-request=3
4032
4033ovs-vsctl -- add-port br-int hv1-vif4 -- \
4034 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4035 options:tx_pcap=hv1/vif4-tx.pcap \
4036 options:rxq_pcap=hv1/vif4-rx.pcap \
4037 ofport-request=4
4038
74868f2c 4039OVN_POPULATE_ARP
281977f7
NS
4040
4041sleep 2
4042
4043as hv1 ovs-vsctl show
4044
281977f7
NS
4045# This shell function sends a DHCP request packet
4046# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
4047test_dhcp() {
213615b3
NS
4048 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
4049 shift; shift; shift; shift; shift;
4050 if test $use_ip != 0; then
4051 src_ip=$1
4052 dst_ip=$2
4053 shift; shift;
4054 else
4055 src_ip=`ip_to_hex 0 0 0 0`
4056 dst_ip=`ip_to_hex 255 255 255 255`
4057 fi
4058 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
281977f7 4059 # udp header and dhcp header
ab187e7e
BP
4060 request=${request}0044004300fc0000
4061 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 4062 # client hardware padding
ab187e7e 4063 request=${request}00000000000000000000
281977f7 4064 # server hostname
ab187e7e
BP
4065 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4066 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4067 # boot file name
ab187e7e
BP
4068 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4069 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4070 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4071 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4072 # dhcp magic cookie
ab187e7e 4073 request=${request}63825363
281977f7 4074 # dhcp message type
ab187e7e 4075 request=${request}3501${dhcp_type}ff
281977f7
NS
4076
4077 if test $offer_ip != 0; then
213615b3 4078 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
281977f7
NS
4079 # total IP length will be the IP length of the request packet
4080 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4081 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4082 udp_len=`expr $ip_len - 20`
04d60f6e
YT
4083 ip_len=$(printf "%x" $ip_len)
4084 udp_len=$(printf "%x" $udp_len)
281977f7
NS
4085 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4086 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4087 # udp header and dhcp header.
4088 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 4089 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 4090 # your ip address
ab187e7e 4091 reply=${reply}${offer_ip}
281977f7 4092 # next server ip address, relay agent ip address, client mac address
ab187e7e 4093 reply=${reply}0000000000000000${src_mac}
281977f7 4094 # client hardware padding
ab187e7e 4095 reply=${reply}00000000000000000000
281977f7 4096 # server hostname
ab187e7e
BP
4097 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4098 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4099 # boot file name
ab187e7e
BP
4100 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4101 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4102 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4103 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4104 # dhcp magic cookie
ab187e7e 4105 reply=${reply}63825363
281977f7
NS
4106 # dhcp message type
4107 local dhcp_reply_type=02
4108 if test $dhcp_type = 03; then
4109 dhcp_reply_type=05
4110 fi
ab187e7e 4111 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
4112 echo $reply >> $inport.expected
4113 else
281977f7 4114 for outport; do
e4543cfe 4115 echo $request >> $outport.expected
281977f7
NS
4116 done
4117 fi
4118 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4119}
4120
4121reset_pcap_file() {
4122 local iface=$1
4123 local pcap_file=$2
4124 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4125options:rxq_pcap=dummy-rx.pcap
4126 rm -f ${pcap_file}*.pcap
4127 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4128options:rxq_pcap=${pcap_file}-rx.pcap
4129}
4130
4131ip_to_hex() {
4132 printf "%02x%02x%02x%02x" "$@"
4133}
4134
4135AT_CAPTURE_FILE([ofctl_monitor0.log])
4136as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4137--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4138
4139echo "---------NB dump-----"
4140ovn-nbctl show
4141echo "---------------------"
4142echo "---------SB dump-----"
4143ovn-sbctl list datapath_binding
4144echo "---------------------"
4145ovn-sbctl list logical_flow
4146echo "---------------------"
4147
4148echo "---------------------"
4149ovn-sbctl dump-flows
4150echo "---------------------"
4151
4152echo "------ hv1 dump ----------"
4153as hv1 ovs-ofctl dump-flows br-int
4154
4155# Send DHCPDISCOVER.
4156offer_ip=`ip_to_hex 10 0 0 4`
4157server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4158expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4159test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4160
4161# NXT_RESUMEs should be 1.
4162OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4163
4164$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4165cat 1.expected | cut -c -48 > expout
4166AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4167# Skipping the IPv4 checksum.
4168cat 1.expected | cut -c 53- > expout
4169AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4170
4171# ovs-ofctl also resumes the packets and this causes other ports to receive
4172# the DHCP request packet. So reset the pcap files so that its easier to test.
4173reset_pcap_file hv1-vif1 hv1/vif1
4174reset_pcap_file hv1-vif2 hv1/vif2
4175rm -f 1.expected
4176rm -f 2.expected
4177
4178# Send DHCPREQUEST.
4179offer_ip=`ip_to_hex 10 0 0 6`
4180server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4181expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4182test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4183
4184# NXT_RESUMEs should be 2.
4185OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4186
4187$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4188cat 2.expected | cut -c -48 > expout
4189AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4190# Skipping the IPv4 checksum.
4191cat 2.expected | cut -c 53- > expout
4192AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4193
4194reset_pcap_file hv1-vif1 hv1/vif1
4195reset_pcap_file hv1-vif2 hv1/vif2
4196rm -f 1.expected
4197rm -f 2.expected
4198
4199# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4200# but should be resumed without the reply.
4201# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4202# one from ovn-controller and the other from "ovs-ofctl resume."
4203offer_ip=0
213615b3 4204test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
281977f7
NS
4205
4206# NXT_RESUMEs should be 3.
4207OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4208
4209# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 4210OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
4211
4212reset_pcap_file hv1-vif1 hv1/vif1
4213reset_pcap_file hv1-vif2 hv1/vif2
4214rm -f 1.expected
4215rm -f 2.expected
4216
4217# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4218# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4219
213615b3 4220test_dhcp 3 f00000000003 01 0 4 0
281977f7
NS
4221
4222# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4223# this lport.
213615b3 4224test_dhcp 4 f00000000004 01 0 3 0
281977f7
NS
4225
4226# NXT_RESUMEs should be 3.
4227OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4228
49d7c759
BP
4229OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4230OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 4231
213615b3
NS
4232# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4233offer_ip=`ip_to_hex 10 0 0 6`
4234server_ip=`ip_to_hex 10 0 0 1`
4235expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4236src_ip=$offer_ip
4237dst_ip=$server_ip
4238test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4239
4240# NXT_RESUMEs should be 4.
4241OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4242
4243$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4244cat 2.expected | cut -c -48 > expout
4245AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4246# Skipping the IPv4 checksum.
4247cat 2.expected | cut -c 53- > expout
4248AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4249
4250reset_pcap_file hv1-vif1 hv1/vif1
4251reset_pcap_file hv1-vif2 hv1/vif2
4252rm -f 1.expected
4253rm -f 2.expected
4254
4255# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4256offer_ip=`ip_to_hex 10 0 0 6`
4257server_ip=`ip_to_hex 10 0 0 1`
4258expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4259src_ip=$offer_ip
4260dst_ip=`ip_to_hex 255 255 255 255`
4261test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4262
4263# NXT_RESUMEs should be 5.
4264OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4265
4266$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4267cat 2.expected | cut -c -48 > expout
4268AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4269# Skipping the IPv4 checksum.
4270cat 2.expected | cut -c 53- > expout
4271AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4272
4273reset_pcap_file hv1-vif1 hv1/vif1
4274reset_pcap_file hv1-vif2 hv1/vif2
4275rm -f 1.expected
4276rm -f 2.expected
4277
4278# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4279# The packet should not be received by ovn-controller.
4280src_ip=`ip_to_hex 10 0 0 6`
4281dst_ip=`ip_to_hex 10 0 0 4`
4282test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4283
4284# NXT_RESUMEs should be 5.
4285OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4286
4287# vif1-tx.pcap should have received the DHCPv4 request packet
4288OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4289
281977f7 4290as hv1
33ac3c83
NS
4291OVS_APP_EXIT_AND_WAIT([ovn-controller])
4292OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4293OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4294
4295as ovn-sb
4296OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4297
4298as ovn-nb
4299OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4300
4301as northd
4302OVS_APP_EXIT_AND_WAIT([ovn-northd])
4303
4304as main
4305OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4306OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4307
4308AT_CLEANUP
4309
40df4566 4310AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
4311AT_SKIP_IF([test $HAVE_PYTHON = no])
4312ovn_start
4313
4314ovn-nbctl ls-add ls1
4315ovn-nbctl lsp-add ls1 ls1-lp1 \
4316-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4317
4318ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4319
4320ovn-nbctl lsp-add ls1 ls1-lp2 \
4321-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4322
4323ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4324
40df4566
ZKL
4325ovn-nbctl lsp-add ls1 ls1-lp3 \
4326-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4327
4328ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4329
9060fc9a
MM
4330d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4331options="\"server_id\"=\"00:00:00:10:00:01\"")"
4332
4333ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4334ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4335
4336d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4337options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
33ac3c83 4338
9060fc9a 4339ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
40df4566 4340
33ac3c83
NS
4341ovn-nbctl ls-add ls2
4342ovn-nbctl lsp-add ls2 ls2-lp1 \
4343-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4344ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4345ovn-nbctl lsp-add ls2 ls2-lp2 \
4346-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4347ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4348
4349net_add n1
4350sim_add hv1
4351
4352as hv1
4353ovs-vsctl add-br br-phys
4354ovn_attach n1 br-phys 192.168.0.1
4355ovs-vsctl -- add-port br-int hv1-vif1 -- \
4356 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4357 options:tx_pcap=hv1/vif1-tx.pcap \
4358 options:rxq_pcap=hv1/vif1-rx.pcap \
4359 ofport-request=1
4360
4361ovs-vsctl -- add-port br-int hv1-vif2 -- \
4362 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4363 options:tx_pcap=hv1/vif2-tx.pcap \
4364 options:rxq_pcap=hv1/vif2-rx.pcap \
4365 ofport-request=2
4366
4367ovs-vsctl -- add-port br-int hv1-vif3 -- \
4368 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4369 options:tx_pcap=hv1/vif3-tx.pcap \
4370 options:rxq_pcap=hv1/vif3-rx.pcap \
4371 ofport-request=3
4372
4373ovs-vsctl -- add-port br-int hv1-vif4 -- \
4374 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4375 options:tx_pcap=hv1/vif4-tx.pcap \
4376 options:rxq_pcap=hv1/vif4-rx.pcap \
4377 ofport-request=4
4378
40df4566
ZKL
4379ovs-vsctl -- add-port br-int hv1-vif5 -- \
4380 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4381 options:tx_pcap=hv1/vif5-tx.pcap \
4382 options:rxq_pcap=hv1/vif5-rx.pcap \
4383 ofport-request=5
4384
74868f2c 4385OVN_POPULATE_ARP
33ac3c83
NS
4386
4387sleep 2
4388
4389trim_zeros() {
4390 sed 's/\(00\)\{1,\}$//'
4391}
4392
4393# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4394# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4395# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4396# packet should be received twice (one from ovn-controller and the other
4397# from the "ovs-ofctl monitor br-int resume"
4398test_dhcpv6() {
4399 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4400 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4401 # dst ip ff02::1:2
ab187e7e 4402 request=${request}ff020000000000000000000000010002
33ac3c83 4403 # udp header and dhcpv6 header
ab187e7e 4404 request=${request}02220223002affff${msg_code}010203
33ac3c83 4405 # Client identifier
ab187e7e 4406 request=${request}0001000a00030001${src_mac}
33ac3c83 4407 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 4408 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
4409 shift; shift; shift; shift; shift;
4410 if test $offer_ip != 0; then
4411 local server_mac=000000100001
4412 local server_lla=fe80000000000000020000fffe100001
4413 local reply_code=07
4414 if test $msg_code = 01; then
4415 reply_code=02
4416 fi
40df4566
ZKL
4417 local msg_len=54
4418 if test $offer_ip = 1; then
4419 msg_len=28
4420 fi
4421 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4422 # udp header and dhcpv6 header
ab187e7e 4423 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4424 # Client identifier
ab187e7e 4425 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4426 # IA-NA
40df4566 4427 if test $offer_ip != 1; then
ab187e7e 4428 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4429 fi
33ac3c83 4430 # Server identifier
ab187e7e 4431 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4432 echo $reply | trim_zeros >> $inport.expected
4433 else
4434 for outport; do
4435 echo $request | trim_zeros >> $outport.expected
4436 done
4437 fi
4438
4439 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4440}
4441
4442reset_pcap_file() {
4443 local iface=$1
4444 local pcap_file=$2
4445 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4446options:rxq_pcap=dummy-rx.pcap
4447 rm -f ${pcap_file}*.pcap
4448 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4449options:rxq_pcap=${pcap_file}-rx.pcap
4450}
4451
4452AT_CAPTURE_FILE([ofctl_monitor0.log])
4453as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4454--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4455
4456echo "---------NB dump-----"
4457ovn-nbctl show
4458echo "---------------------"
4459echo "---------SB dump-----"
4460ovn-sbctl list datapath_binding
4461echo "---------------------"
4462ovn-sbctl list logical_flow
4463echo "---------------------"
4464
4465echo "---------------------"
4466ovn-sbctl dump-flows
4467echo "---------------------"
4468
4469echo "------ hv1 dump ----------"
4470as hv1 ovs-ofctl dump-flows br-int
4471
4472src_mac=f00000000001
4473src_lla=fe80000000000000f20000fffe000001
4474offer_ip=ae700000000000000000000000000004
4475test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4476
4477# NXT_RESUMEs should be 1.
4478OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4479
4480$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4481# cat 1.expected | trim_zeros > expout
4482cat 1.expected | cut -c -120 > expout
4483AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4484# Skipping the UDP checksum
4485cat 1.expected | cut -c 125- > expout
4486AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4487
4488rm 1.expected
4489
4490# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4491# without any modifications and the packet should be received by ls1-lp1.
4492# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4493# resume and the other from ovs-ofctl monitor resume.
4494
4495reset_pcap_file hv1-vif1 hv1/vif1
4496reset_pcap_file hv1-vif2 hv1/vif2
4497
4498src_mac=f00000000002
4499src_lla=fe80000000000000f20000fffe000002
4500offer_ip=ae700000000000000000000000000005
4501# Set invalid msg_type
4502
4503test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4504
4505# NXT_RESUMEs should be 2.
4506OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4507
4508# vif2-tx.pcap should not have received the DHCPv6 reply packet
4509rm 2.packets
4510$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4511AT_CHECK([cat 2.packets], [0], [])
4512
4513# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4514$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4515cat 1.expected > expout
4516AT_CHECK([cat 1.packets], [0], [expout])
4517
4518# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4519# There should be no DHCPv6 reply from ovn-controller and the request packet
4520# should be received by ls2-lp2.
4521
4522src_mac=f00000000003
4523src_lla=fe80000000000000f20000fffe000003
4524test_dhcpv6 3 $src_mac $src_lla 01 0 4
4525
4526# NXT_RESUMEs should be 2 only.
4527OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4528
4529# vif3-tx.pcap should not have received the DHCPv6 reply packet
4530$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4531AT_CHECK([cat 3.packets], [0], [])
4532
4533# vif4-tx.pcap should have received the DHCPv6 request packet
4534$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4535cat 4.expected > expout
4536AT_CHECK([cat 4.packets], [0], [expout])
4537
40df4566
ZKL
4538# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4539# The DHCPv6 reply should doesn't contian offer_ip.
4540src_mac=f00000000022
4541src_lla=fe80000000000000f20000fffe000022
4542reset_pcap_file hv1-vif5 hv1/vif5
4543test_dhcpv6 5 $src_mac $src_lla 01 1 5
4544
4545# NXT_RESUMEs should be 3.
4546OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4547
4548$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4549# Skipping the UDP checksum
4550cat 5.expected | cut -c 1-120,125- > expout
4551AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4552
33ac3c83 4553as hv1
281977f7
NS
4554OVS_APP_EXIT_AND_WAIT([ovn-controller])
4555OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4556OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4557
4558as ovn-sb
4559OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4560
4561as ovn-nb
4562OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4563
4564as northd
4565OVS_APP_EXIT_AND_WAIT([ovn-northd])
4566
4567as main
4568OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4569OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4570
4571AT_CLEANUP
4572
c1645003 4573AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4574AT_SKIP_IF([test $HAVE_PYTHON = no])
4575ovn_start
4576
4577# Logical network:
4578# Two LRs - R1 and R2 that are connected to each other via LS "join"
4579# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4580# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4581# R2 is a gateway router.
4582
4583
4584
4585# Create two hypervisor and create OVS ports corresponding to logical ports.
4586net_add n1
4587
4588sim_add hv1
4589as hv1
4590ovs-vsctl add-br br-phys
4591ovn_attach n1 br-phys 192.168.0.1
4592ovs-vsctl -- add-port br-int hv1-vif1 -- \
4593 set interface hv1-vif1 external-ids:iface-id=foo1 \
4594 options:tx_pcap=hv1/vif1-tx.pcap \
4595 options:rxq_pcap=hv1/vif1-rx.pcap \
4596 ofport-request=1
4597
4598
4599sim_add hv2
4600as hv2
4601ovs-vsctl add-br br-phys
4602ovn_attach n1 br-phys 192.168.0.2
4603ovs-vsctl -- add-port br-int hv2-vif1 -- \
4604 set interface hv2-vif1 external-ids:iface-id=alice1 \
4605 options:tx_pcap=hv2/vif1-tx.pcap \
4606 options:rxq_pcap=hv2/vif1-rx.pcap \
4607 ofport-request=1
4608
4609# Pre-populate the hypervisors' ARP tables so that we don't lose any
4610# packets for ARP resolution (native tunneling doesn't queue packets
4611# for ARP resolution).
74868f2c 4612OVN_POPULATE_ARP
c1645003
GS
4613
4614ovn-nbctl create Logical_Router name=R1
4615ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4616
ea46a4e9
JP
4617ovn-nbctl ls-add foo
4618ovn-nbctl ls-add alice
4619ovn-nbctl ls-add join
c1645003
GS
4620
4621# Connect foo to R1
31114af7 4622ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4623ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4624 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4625
4626# Connect alice to R2
31114af7 4627ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4628ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4629 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4630
4631# Connect R1 to join
31114af7 4632ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4633ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4634 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4635
4636# Connect R2 to join
31114af7 4637ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4638ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4639 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4640
4641
4642#install static routes
4643ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4644ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4645R1 static_routes @lrt
4646
4647ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4648ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4649R2 static_routes @lrt
4650
4651# Create logical port foo1 in foo
31ed1192
JP
4652ovn-nbctl lsp-add foo foo1 \
4653-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4654
4655# Create logical port alice1 in alice
31ed1192
JP
4656ovn-nbctl lsp-add alice alice1 \
4657-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4658
4659
4660# Allow some time for ovn-northd and ovn-controller to catch up.
4661# XXX This should be more systematic.
4662sleep 2
4663
4664ip_to_hex() {
4665 printf "%02x%02x%02x%02x" "$@"
4666}
c1645003
GS
4667
4668# Send ip packets between foo1 and alice1
4669src_mac="f00000010203"
4670dst_mac="000001010203"
4671src_ip=`ip_to_hex 192 168 1 2`
4672dst_ip=`ip_to_hex 172 16 1 2`
4673packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4674
4675echo "---------NB dump-----"
4676ovn-nbctl show
4677echo "---------------------"
4678ovn-nbctl list logical_router
4679echo "---------------------"
4680ovn-nbctl list logical_router_port
4681echo "---------------------"
4682
4683echo "---------SB dump-----"
4684ovn-sbctl list datapath_binding
4685echo "---------------------"
4686ovn-sbctl list port_binding
4687echo "---------------------"
4688ovn-sbctl dump-flows
4689echo "---------------------"
4690ovn-sbctl list chassis
4691ovn-sbctl list encap
4692echo "---------------------"
4693
c1645003
GS
4694# Packet to Expect at alice1
4695src_mac="000002010203"
4696dst_mac="f00000010204"
4697src_ip=`ip_to_hex 192 168 1 2`
4698dst_ip=`ip_to_hex 172 16 1 2`
4699expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4700
4701
4702as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4703as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4704
ab39371d
RM
4705echo "------ hv1 dump after packet 1 ----------"
4706as hv1 ovs-ofctl show br-int
4707as hv1 ovs-ofctl dump-flows br-int
4708echo "------ hv2 dump after packet 1 ----------"
4709as hv2 ovs-ofctl show br-int
4710as hv2 ovs-ofctl dump-flows br-int
4711echo "----------------------------"
4712
49d7c759
BP
4713echo $expected > expected
4714OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4715
34114cf8
GS
4716# Delete the router and re-create it. Things should work as before.
4717ovn-nbctl lr-del R2
4718ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4719# Connect alice to R2
4720ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4721# Connect R2 to join
4722ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4723
4724ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4725ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4726R2 static_routes @lrt
4727
4728# Wait for ovn-controller to catch up.
4729sleep 1
4730
4731# Send the packet again.
4732as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4733
4734echo "------ hv1 dump after packet 2 ----------"
4735as hv1 ovs-ofctl show br-int
4736as hv1 ovs-ofctl dump-flows br-int
4737echo "------ hv2 dump after packet 2 ----------"
4738as hv2 ovs-ofctl show br-int
4739as hv2 ovs-ofctl dump-flows br-int
4740echo "----------------------------"
4741
49d7c759
BP
4742echo $expected >> expected
4743OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4744
7a8f15e0 4745OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4746
4747AT_CLEANUP
bb3c4568
FF
4748
4749AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4750AT_KEYWORDS([router-icmp-reply])
4751AT_SKIP_IF([test $HAVE_PYTHON = no])
4752ovn_start
4753
4754# Logical network:
4755# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4756# and has switch ls2 (172.16.1.0/24) connected to it.
4757
fa2a27b2 4758ovn-nbctl lr-add R1
bb3c4568 4759
ea46a4e9
JP
4760ovn-nbctl ls-add ls1
4761ovn-nbctl ls-add ls2
bb3c4568
FF
4762
4763# Connect ls1 to R1
31114af7 4764ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4765ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4766 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4767
4768# Connect ls2 to R1
31114af7 4769ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4770ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4771 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4772
4773# Create logical port ls1-lp1 in ls1
31ed1192
JP
4774ovn-nbctl lsp-add ls1 ls1-lp1 \
4775-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4776
4777# Create logical port ls2-lp1 in ls2
31ed1192
JP
4778ovn-nbctl lsp-add ls2 ls2-lp1 \
4779-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4780
4781# Create one hypervisor and create OVS ports corresponding to logical ports.
4782net_add n1
4783
4784sim_add hv1
4785as hv1
4786ovs-vsctl add-br br-phys
4787ovn_attach n1 br-phys 192.168.0.1
4788ovs-vsctl -- add-port br-int vif1 -- \
4789 set interface vif1 external-ids:iface-id=ls1-lp1 \
4790 options:tx_pcap=hv1/vif1-tx.pcap \
4791 options:rxq_pcap=hv1/vif1-rx.pcap \
4792 ofport-request=1
4793
4794ovs-vsctl -- add-port br-int vif2 -- \
4795 set interface vif2 external-ids:iface-id=ls2-lp1 \
4796 options:tx_pcap=hv1/vif2-tx.pcap \
4797 options:rxq_pcap=hv1/vif2-rx.pcap \
4798 ofport-request=1
4799
4800
4801# Allow some time for ovn-northd and ovn-controller to catch up.
4802# XXX This should be more systematic.
4803sleep 1
4804
4805
4806ip_to_hex() {
4807 printf "%02x%02x%02x%02x" "$@"
4808}
bb3c4568
FF
4809for i in 1 2; do
4810 : > vif$i.expected
4811done
4812# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4813#
4814# Causes a packet to be received on INPORT. The packet is an ICMPv4
4815# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4816# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4817# provided, then it should be the ip and icmp checksums of the packet
4818# responded; otherwise, no reply is expected.
4819# In the absence of an ip checksum calculation helpers, this relies
4820# on the caller to provide the checksums for the ip and icmp headers.
4821# XXX This should be more systematic.
4822#
4823# INPORT is an lport number, e.g. 11 for vif11.
4824# ETH_SRC and ETH_DST are each 12 hex digits.
4825# IPV4_SRC and IPV4_DST are each 8 hex digits.
4826# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4827# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4828test_ipv4_icmp_request() {
4829 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4830 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4831 shift; shift; shift; shift; shift; shift; shift
4832 shift; shift
4833
4834 # Use ttl to exercise section 4.2.2.9 of RFC1812
4835 local ip_ttl=01
4836 local icmp_id=5fbf
4837 local icmp_seq=0001
4838 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4839 local icmp_type_code_request=0800
4840 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4841 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4842
4843 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4844 if test X$exp_icmp_chksum != X; then
4845 # Expect to receive the reply, if any. In same port where packet was sent.
4846 # Note: src and dst fields are expected to be reversed.
4847 local icmp_type_code_response=0000
4848 local reply_icmp_ttl=fe
4849 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4850 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4851 echo $reply >> vif$inport.expected
4852 fi
4853}
4854
4855# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4856rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4857rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4858l1_ip=$(ip_to_hex 192 168 1 2)
4859l2_ip=$(ip_to_hex 172 16 1 2)
4860
4861# Ping router ip address that is on same subnet as the logical port
4862test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4863test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4864
4865# Ping router ip address that is on the other side of the logical ports
4866test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4867test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4868
4869echo "---------NB dump-----"
4870ovn-nbctl show
4871echo "---------------------"
4872ovn-nbctl list logical_router
4873echo "---------------------"
4874ovn-nbctl list logical_router_port
4875echo "---------------------"
4876
4877echo "---------SB dump-----"
4878ovn-sbctl list datapath_binding
4879echo "---------------------"
4880ovn-sbctl list logical_flow
4881echo "---------------------"
4882
4883echo "------ hv1 dump ----------"
4884as hv1 ovs-ofctl dump-flows br-int
4885
4886# Now check the packets actually received against the ones expected.
4887for inport in 1 2; do
49d7c759 4888 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4889done
4890
7a8f15e0 4891OVN_CLEANUP([hv1])
bb3c4568
FF
4892
4893AT_CLEANUP
94f79fcb
RB
4894
4895# 1 hypervisor, 1 port
4896# make sure that the port state is properly set to up and back down
4897# when created and deleted.
4898AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
4899ovn_start
4900
4901ovn-nbctl ls-add ls1
4902ovn-nbctl lsp-add ls1 lp1
4903ovn-nbctl lsp-set-addresses lp1 unknown
4904
4905net_add n1
4906sim_add hv1
4907as hv1 ovs-vsctl add-br br-phys
4908as hv1 ovn_attach n1 br-phys 192.168.0.1
4909
4910as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4911OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4912
4913as hv1 ovs-vsctl del-port br-int vif1
4914OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4915
7a8f15e0 4916OVN_CLEANUP([hv1])
94f79fcb 4917
94f79fcb 4918AT_CLEANUP
e75451fe 4919
ccc6e1db
FF
4920# 1 hypervisor, 1 port
4921# make sure that the OF rules created to support a datapath are added/cleared
4922# when logical switch is created and removed.
4923AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 4924AT_KEYWORDS([cleanup])
ccc6e1db
FF
4925ovn_start
4926
4927net_add n1
4928sim_add hv1
4929as hv1 ovs-vsctl add-br br-phys
4930as hv1 ovn_attach n1 br-phys 192.168.0.1
4931
4932# This shell function checks if OF rules in br-int have clauses
4933# related to OVN datapaths. The caller determines if it should find
4934# a match in the output, or not.
4935#
4936# EXPECT_DATAPATH param determines whether flows that refer to
4937# datapath to should be present or not. 0 means
4938# they should not be.
4939# STAGE_INFO param is a simple string to help identify the stage
4940# in the test when this function was invoked.
4941test_datapath_in_of_rules() {
4942 local expect_datapath=$1 stage_info=$2
4943 echo "------ ovn-nbctl show ${stage_info} ------"
4944 ovn-nbctl show
4945 echo "------ ovn-sbctl show ${stage_info} ------"
4946 ovn-sbctl show
4947 echo "------ OF rules ${stage_info} ------"
4948 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4949 # if there is a datapath mentioned in the output, check for the
4950 # magic keyword that represents one, based on the exit status of
4951 # a quiet grep
4952 if test $expect_datapath != 0; then
4618b102 4953 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 4954 else
4618b102 4955 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
4956 fi
4957}
4958
4959test_datapath_in_of_rules 0 "before ls+port create"
4960
4961ovn-nbctl ls-add ls1
4962ovn-nbctl lsp-add ls1 lp1
4963ovn-nbctl lsp-set-addresses lp1 unknown
4964
4965as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4966OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4967
4968test_datapath_in_of_rules 1 "after port is bound"
4969
4970as hv1 ovs-vsctl del-port br-int vif1
4971OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4972
4973ovn-nbctl lsp-set-addresses lp1
4974ovn-nbctl lsp-del lp1
4975ovn-nbctl ls-del ls1
4976
4977# wait for earlier changes to take effect
4978AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4979
4980# ensure OF rules are no longer present. There used to be a bug here.
4981test_datapath_in_of_rules 0 "after lport+ls removal"
4982
4983OVN_CLEANUP([hv1])
4984
4985AT_CLEANUP
4986
f8a8db39 4987AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
4988AT_SKIP_IF([test $HAVE_PYTHON = no])
4989ovn_start
4990
4991#TODO: since patch port for IPv6 logical router port is not ready not,
4992# so we are not going to test vifs on different lswitches cases. Try
4993# to update for that once relevant stuff implemented.
4994
4995# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4996# with. NS packet we test, from one VIF for another VIF, will be replied
4997# by local ovn-controller, but not by target VIF.
4998
4999# Create hypervisors and logical switch lsw0.
5000ovn-nbctl ls-add lsw0
5001net_add n1
5002sim_add hv1
5003as hv1
5004ovs-vsctl add-br br-phys
5005ovn_attach n1 br-phys 192.168.0.2
5006
5007# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5008ovs-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
5009ovn-nbctl lsp-add lsw0 lp1
5010ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5011ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5012
5013# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5014ovs-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
5015ovn-nbctl lsp-add lsw0 lp2
5016ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5017ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5018
5019# Add ACL rule for ICMPv6 on lsw0
5020ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5021ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5022ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5023
5024# Allow some time for ovn-northd and ovn-controller to catch up.
5025# XXX This should be more systematic.
5026sleep 1
5027
5028# Given the name of a logical port, prints the name of the hypervisor
5029# on which it is located.
5030vif_to_hv() {
5031 echo hv1${1%?}
5032}
e75451fe
ZKL
5033for i in 1 2; do
5034 : > $i.expected
5035done
5036
5037# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5038# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5039# vif2 will not receive NS packet, since ovn-controller will reply for it.
5040ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5041na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5042
5043as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 5044echo $na_packet >> 1.expected
e75451fe 5045
e75451fe
ZKL
5046echo "------ hv1 dump ------"
5047as hv1 ovs-vsctl show
5048as hv1 ovs-ofctl -O OpenFlow13 show br-int
5049as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5050
5051for i in 1 2; do
49d7c759 5052 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
5053done
5054
7a8f15e0 5055OVN_CLEANUP([hv1])
e75451fe
ZKL
5056
5057AT_CLEANUP
7417d147
RM
5058
5059AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
5060ovn_start
5061
5062net_add n1
5063
5064sim_add hv1
5065as hv1
5066ovs-vsctl add-br br-phys
5067ovn_attach n1 br-phys 192.168.0.1
5068
5069row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5070ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5071ovn-nbctl destroy Address_Set $row
5072
5073sleep 1
5074
5075# A bug previously existed in the address set support code
5076# that caused ovn-controller to crash after an address set
5077# was updated and then removed. This test case ensures
5078# that ovn-controller is at least still running after
5079# creating, updating, and deleting an address set.
5080AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5081
5082OVN_CLEANUP([hv1])
5083
5084AT_CLEANUP
8639f9be
ND
5085
5086AT_SETUP([ovn -- ipam])
8639f9be
ND
5087AT_SKIP_IF([test $HAVE_PYTHON = no])
5088ovn_start
5089
5090# Add a port to a switch that does not have a subnet set, then set the
5091# subnet which should result in an address being allocated for the port.
5092ovn-nbctl ls-add sw0
5093ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 5094ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
5095AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5096 ["0a:00:00:00:00:01 192.168.1.2"
5097])
5098
5099# Add 9 more ports to sw0, addresses should all be unique.
5100for n in `seq 1 9`; do
11547f85 5101 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5102done
5103AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5104 ["0a:00:00:00:00:02 192.168.1.3"
5105])
5106AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5107 ["0a:00:00:00:00:03 192.168.1.4"
5108])
5109AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5110 ["0a:00:00:00:00:04 192.168.1.5"
5111])
5112AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5113 ["0a:00:00:00:00:05 192.168.1.6"
5114])
5115AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5116 ["0a:00:00:00:00:06 192.168.1.7"
5117])
5118AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5119 ["0a:00:00:00:00:07 192.168.1.8"
5120])
5121AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5122 ["0a:00:00:00:00:08 192.168.1.9"
5123])
5124AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5125 ["0a:00:00:00:00:09 192.168.1.10"
5126])
5127AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5128 ["0a:00:00:00:00:0a 192.168.1.11"
5129])
5130
5131# Trying similar tests with a second switch. MAC addresses should be unique
5132# across both switches but IP's only need to be unique within the same switch.
5133ovn-nbctl ls-add sw1
5134ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 5135ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
5136AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
5137 ["0a:00:00:00:00:0b 192.168.1.2"
5138])
5139
5140for n in `seq 11 19`; do
11547f85 5141 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5142done
5143AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5144 ["0a:00:00:00:00:0c 192.168.1.3"
5145])
5146AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5147 ["0a:00:00:00:00:0d 192.168.1.4"
5148])
5149AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5150 ["0a:00:00:00:00:0e 192.168.1.5"
5151])
5152AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5153 ["0a:00:00:00:00:0f 192.168.1.6"
5154])
5155AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5156 ["0a:00:00:00:00:10 192.168.1.7"
5157])
5158AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5159 ["0a:00:00:00:00:11 192.168.1.8"
5160])
5161AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5162 ["0a:00:00:00:00:12 192.168.1.9"
5163])
5164AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5165 ["0a:00:00:00:00:13 192.168.1.10"
5166])
5167AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5168 ["0a:00:00:00:00:14 192.168.1.11"
5169])
5170
5171# Change a port's address to test for multiple ip's for a single address entry
5172# and addresses set by the user.
451624fe 5173ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.2 192.168.1.12 192.168.1.14"
11547f85 5174ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
5175AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5176 ["0a:00:00:00:00:16 192.168.1.13"
5177])
5178
5179# Test for logical router port address management.
5180ovn-nbctl create Logical_Router name=R1
5181ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5182network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5183-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5184-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 5185ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
5186AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5187 ["0a:00:00:00:00:18 192.168.1.15"
5188])
5189
5190# Test for address reuse after logical port is deleted.
5191ovn-nbctl lsp-del p0
11547f85 5192ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
5193AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5194 ["0a:00:00:00:00:19 192.168.1.2"
5195])
5196
5197# Test for multiple addresses to one logical port.
5198ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5199"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 5200ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
5201AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5202 ["0a:00:00:00:00:1c 192.168.1.16"
5203])
5204
5205# Test for exhausting subnet address space.
5206ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 5207ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
5208AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5209 ["0a:00:00:00:00:1d 172.16.1.2"
5210])
5211
11547f85 5212ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 5213AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
7cc0741e 5214 ["0a:00:00:00:00:1e"
8639f9be
ND
5215])
5216
5217# Test that address management does not add duplicate MAC for lsp/lrp peers.
5218ovn-nbctl create Logical_Router name=R2
5219ovn-nbctl ls-add sw3
5220ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
7cc0741e 5221"0a:00:00:00:00:1f"
8639f9be
ND
5222ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5223network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5224-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5225-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 5226ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
5227AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5228 ["0a:00:00:00:00:20 192.168.1.17"
5229])
5230
6374d518
LR
5231# Test static MAC address with dynamically allocated IP
5232ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5233"fe:dc:ba:98:76:54 dynamic"
5234AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5235 ["fe:dc:ba:98:76:54 192.168.1.18"
5236])
5237
6c4f7a8a
NS
5238# Update the static MAC address with dynamically allocated IP and check
5239# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5240ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
6c4f7a8a
NS
5241
5242AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5243 ["fe:dc:ba:98:76:55 192.168.1.18"
5244])
5245
5246ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5247AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
451624fe 5248 ["0a:00:00:00:00:21 192.168.1.18"
6c4f7a8a
NS
5249])
5250
5251ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5252AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5253 ["fe:dc:ba:98:76:56 192.168.1.18"
5254])
5255
161ea2c8
NS
5256
5257# Test the exclude_ips from the IPAM list
5258ovn-nbctl --wait=sb set logical_switch sw0 \
5259other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5260
5261ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5262"dynamic"
5263# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5264AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
451624fe 5265 ["0a:00:00:00:00:22 192.168.1.20"
161ea2c8
NS
5266])
5267
5268ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5269"dynamic"
5270# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5271AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
451624fe 5272 ["0a:00:00:00:00:23 192.168.1.22"
161ea2c8
NS
5273])
5274
5275ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5276"dynamic"
5277# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5278AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
451624fe 5279 ["0a:00:00:00:00:24 192.168.1.51"
161ea2c8
NS
5280])
5281
5282# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5283ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5284ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5285"dynamic"
5286AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
451624fe 5287 ["0a:00:00:00:00:25 192.168.1.19"
161ea2c8
NS
5288])
5289
5290# Set invalid data in exclude_ips list. It should be ignored.
5291ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5292ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5293"dynamic"
5294# 192.168.1.21 should be assigned as that's the next free one.
5295AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
451624fe 5296 ["0a:00:00:00:00:26 192.168.1.21"
161ea2c8
NS
5297])
5298
5299# Clear the dynamic addresses assignment request.
5300ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5301AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5302 [[[]]
5303])
5304
7cc0741e
NS
5305# Set IPv6 prefix
5306ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5307ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5308"dynamic"
5309
5310# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5311# - aef0::800:ff:fe00:26 (EUI64)
5312AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
451624fe 5313 ["0a:00:00:00:00:27 192.168.1.21 aef0::800:ff:fe00:27"
7cc0741e
NS
5314])
5315
5316ovn-nbctl --wait=sb ls-add sw4
451624fe
MM
5317ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
5318-- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
7cc0741e
NS
5319ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5320"dynamic"
5321
5322AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
451624fe 5323 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
7cc0741e
NS
5324])
5325
5326ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5327"f0:00:00:00:10:12 dynamic"
5328
5329AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5330 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5331])
5332
451624fe
MM
5333# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5334# p40 should not have an IPv4 address since the pool is exhausted
7cc0741e
NS
5335ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5336"dynamic"
7cc0741e 5337AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
451624fe
MM
5338 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5339])
5340
5341# Test dynamic changes on switch ports.
5342#
5343ovn-nbctl --wait=sb ls-add sw5
5344ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
5345"dynamic"
5346# p41 will start with nothing
5347AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
7cc0741e
NS
5348 [[[]]
5349])
5350
451624fe
MM
5351# Set a subnet. Now p41 should have an ipv4 address, too
5352ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5353AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5354 ["0a:00:00:00:00:2a 192.168.1.2"
5355])
7cc0741e 5356
451624fe
MM
5357# Clear the other_config. The IPv4 address should be gone
5358ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5359AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5360 [[[]]
7cc0741e
NS
5361])
5362
451624fe
MM
5363# Set an IPv6 prefix. Now p41 should have an IPv6 address.
5364ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
7cc0741e 5365AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
451624fe
MM
5366 ["0a:00:00:00:00:2b aef0::800:ff:fe00:2b"
5367])
5368
5369# Change the MAC address to a static one. The IPv6 address should update.
5370ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
5371AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5372 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
5373])
5374
5375# Change the IPv6 prefix. The IPv6 address should update.
5376ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
5377AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5378 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
5379])
5380
5381# Clear the other_config. The IPv6 address should be gone
5382ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5383AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5384 [[[]]
5385])
5386
5387# Set the subnet again. Now p41 should get the IPv4 address again.
5388ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5389AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5390 ["f0:00:00:00:10:2b 192.168.1.2"
5391])
5392
5393# Add another port with a conflicting static IPv4 address. p41 should update.
5394ovn-nbctl --wait=sb lsp-add sw5 p42 -- lsp-set-addresses p42 \
5395"f0:00:00:00:10:2c 192.168.1.2"
5396AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5397 ["f0:00:00:00:10:2b 192.168.1.3"
5398])
5399
5400# Add an excluded IP address that conflicts with p41. p41 should update.
5401ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
5402exclude_ips="192.168.1.3"
5403AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5404 ["f0:00:00:00:10:2b 192.168.1.4"
7cc0741e
NS
5405])
5406
8639f9be
ND
5407as ovn-sb
5408OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5409
5410as ovn-nb
5411OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5412
5413as northd
5414OVS_APP_EXIT_AND_WAIT([ovn-northd])
5415
5416AT_CLEANUP
5417
5418AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5419AT_SKIP_IF([test $HAVE_PYTHON = no])
5420ovn_start
5421
5422ovn-nbctl lr-add R1
5423
5424# Test for a ping using dynamically allocated addresses.
5425ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5426ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5427
5428# Connect foo to R1
5429ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5430ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5431 options:router-port=foo \
5432 -- lsp-set-addresses rp-foo router
8639f9be
ND
5433
5434# Connect alice to R1
5435ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5436ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5437 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5438
5439# Create logical port foo1 in foo
fd3b31e9 5440ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5441-- lsp-set-addresses foo1 "dynamic"
8bc2c143 5442AT_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
5443
5444# Create logical port alice1 in alice
fd3b31e9 5445ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5446-- lsp-set-addresses alice1 "dynamic"
8bc2c143 5447AT_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
5448
5449# Create logical port foo2 in foo
fd3b31e9 5450ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5451-- lsp-set-addresses foo2 "dynamic"
8bc2c143 5452AT_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
5453
5454# Create a hypervisor and create OVS ports corresponding to logical ports.
5455net_add n1
5456
5457sim_add hv1
5458as hv1
5459ovs-vsctl add-br br-phys
5460ovn_attach n1 br-phys 192.168.0.1
5461ovs-vsctl -- add-port br-int hv1-vif1 -- \
5462 set interface hv1-vif1 external-ids:iface-id=foo1 \
5463 options:tx_pcap=hv1/vif1-tx.pcap \
5464 options:rxq_pcap=hv1/vif1-rx.pcap \
5465 ofport-request=1
5466
5467ovs-vsctl -- add-port br-int hv1-vif2 -- \
5468 set interface hv1-vif2 external-ids:iface-id=foo2 \
5469 options:tx_pcap=hv1/vif2-tx.pcap \
5470 options:rxq_pcap=hv1/vif2-rx.pcap \
5471 ofport-request=2
5472
5473ovs-vsctl -- add-port br-int hv1-vif3 -- \
5474 set interface hv1-vif3 external-ids:iface-id=alice1 \
5475 options:tx_pcap=hv1/vif3-tx.pcap \
5476 options:rxq_pcap=hv1/vif3-rx.pcap \
5477 ofport-request=3
5478
5479# Allow some time for ovn-northd and ovn-controller to catch up.
5480# XXX This should be more systematic.
5481sleep 1
5482
5483ip_to_hex() {
5484 printf "%02x%02x%02x%02x" "$@"
5485}
8639f9be
ND
5486
5487# Send ip packets between foo1 and foo2
5488src_mac="0a0000000001"
5489dst_mac="0a0000000003"
5490src_ip=`ip_to_hex 192 168 1 2`
5491dst_ip=`ip_to_hex 192 168 1 3`
5492packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5493as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5494
5495# Send ip packets between foo1 and alice1
5496src_mac="0a0000000001"
5497dst_mac="000000010203"
5498src_ip=`ip_to_hex 192 168 1 2`
5499dst_ip=`ip_to_hex 192 168 2 2`
5500packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5501as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5502
5503echo "---------NB dump-----"
5504ovn-nbctl show
5505echo "---------------------"
5506ovn-nbctl list logical_router
5507echo "---------------------"
5508ovn-nbctl list logical_router_port
5509echo "---------------------"
5510
5511echo "---------SB dump-----"
5512ovn-sbctl list datapath_binding
5513echo "---------------------"
5514ovn-sbctl list port_binding
5515echo "---------------------"
5516
5517echo "------ hv1 dump ----------"
5518as hv1 ovs-ofctl dump-flows br-int
5519
5520# Packet to Expect at foo2
5521src_mac="0a0000000001"
5522dst_mac="0a0000000003"
5523src_ip=`ip_to_hex 192 168 1 2`
5524dst_ip=`ip_to_hex 192 168 1 3`
5525expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5526
e4543cfe
DDP
5527$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5528echo $expected > expout
8639f9be
ND
5529AT_CHECK([cat received1.packets], [0], [expout])
5530
5531# Packet to Expect at alice1
5532src_mac="000000010204"
5533dst_mac="0a0000000002"
5534src_ip=`ip_to_hex 192 168 1 2`
5535dst_ip=`ip_to_hex 192 168 2 2`
5536expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5537
e4543cfe
DDP
5538$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5539echo $expected > expout
8639f9be
ND
5540AT_CHECK([cat received2.packets], [0], [expout])
5541
5542OVN_CLEANUP([hv1])
5543
5544AT_CLEANUP
f5792c3f
NS
5545
5546AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5547AT_KEYWORDS([vswitchd])
f5792c3f
NS
5548AT_SKIP_IF([test $HAVE_PYTHON = no])
5549ovn_start
5550
5551ovn-nbctl ls-add ls1
5552
5553ovn-nbctl lsp-add ls1 ls1-lp1 \
5554-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5555
5556ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5557
5558net_add n1
5559sim_add hv1
5560
5561as hv1
5562ovs-vsctl add-br br-phys
5563ovn_attach n1 br-phys 192.168.0.1
5564ovs-vsctl -- add-port br-int hv1-vif1 -- \
5565 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5566 options:tx_pcap=hv1/vif1-tx.pcap \
5567 options:rxq_pcap=hv1/vif1-rx.pcap \
5568 ofport-request=1
5569
74868f2c 5570OVN_POPULATE_ARP
f5792c3f
NS
5571sleep 2
5572
5573as hv1 ovs-vsctl show
5574
5575echo "---------------------"
5576ovn-sbctl dump-flows
5577echo "---------------------"
5578
5579echo "------ hv1 dump ----------"
5580as hv1 ovs-ofctl dump-flows br-int
5581total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5582
5583echo "Total flows before vswitchd restart = " $total_flows
5584
5585# Code taken from ovs-save utility
5586save_flows () {
5587 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5588 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5589 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5590 echo "EOF" >> restore_flows.sh
5591}
5592
5593restart_vswitchd () {
5594 restore_flows=$1
5595
5596 if test $restore_flows = true; then
5597 save_flows
5598 fi
5599
5600 as hv1
5601 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5602
5603 if test $restore_flows = true; then
5604 as hv1
5605 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5606 fi
5607
5608 as hv1
5609 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5610 ovs-ofctl dump-flows br-int
5611
5612 if test $restore_flows = true; then
5613 sh ./restore_flows.sh
5614 echo "Flows after restore"
5615 as hv1
5616 ovs-ofctl dump-flows br-int
5617 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5618 flow-restore-wait="true"
5619 fi
5620}
5621
5622# Save the flows, restart vswitchd and restore the flows
5623restart_vswitchd true
5624OVS_WAIT_UNTIL([
5625 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5626 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5627 test "${total_flows}" = "${total_flows_after_restart}"
5628])
5629
5630# Restart vswitchd without restoring
5631restart_vswitchd false
5632OVS_WAIT_UNTIL([
5633 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5634 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5635 test "${total_flows}" = "${total_flows_after_restart}"
5636])
5637
5638OVN_CLEANUP([hv1])
5639AT_CLEANUP
47021598
CSV
5640
5641AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5642AT_SKIP_IF([test $HAVE_PYTHON = no])
5643ovn_start
5644
5645# Topology: Two LSs - ls1 and ls2 are connected via router r0
5646
5647# Create logical switches
5648ovn-nbctl ls-add ls1
5649ovn-nbctl ls-add ls2
5650
5651# Create router
5652ovn-nbctl create Logical_Router name=lr0
5653
5654# Add router ls1p1 port to gateway router
5655ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5656ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5657 type=router options:router-port=lrp-ls1lp1 \
5658 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5659
5660# Add router ls2p2 port to gateway router
5661ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5662ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5663 type=router options:router-port=lrp-ls2lp1 \
5664 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5665
5666# Set default gateway (nexthop) to 192.168.1.254
5667ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5668
5669# Create logical port ls1lp2 in ls1
5670ovn-nbctl lsp-add ls1 ls1lp2 \
5671-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5672
5673# Create logical port ls2lp2 in ls2
5674ovn-nbctl lsp-add ls2 ls2lp2 \
5675-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5676
5677net_add n1
5678sim_add hv1
5679as hv1
5680ovs-vsctl add-br br-phys
5681ovn_attach n1 br-phys 192.168.0.1
5682ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5683 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5684 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5685 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5686 ofport-request=1
5687ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5688 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5689 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5690 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5691 ofport-request=2
5692
5693# Allow some time for ovn-northd and ovn-controller to catch up.
5694# XXX This should be more systematic.
5695sleep 1
5696
5697echo "---------NB dump-----"
5698ovn-nbctl show
5699echo "---------------------"
5700ovn-nbctl list logical_router
5701echo "---------------------"
5702ovn-nbctl list logical_router_port
5703echo "---------------------"
5704
5705echo "---------SB dump-----"
5706ovn-sbctl list datapath_binding
5707echo "---------------------"
5708ovn-sbctl list port_binding
5709echo "---------------------"
5710ovn-sbctl dump-flows
5711echo "---------------------"
5712ovn-sbctl list chassis
5713ovn-sbctl list encap
5714echo "---------------------"
5715
5716echo "------Flows dump-----"
5717as hv1
5718ovs-ofctl dump-flows
5719echo "---------------------"
5720
5721ip_to_hex() {
5722 printf "%02x%02x%02x%02x" "$@"
5723}
5724
5725src_mac="f00000000003"
5726dst_mac="f00000000001"
5727src_ip=`ip_to_hex 192 168 0 2`
5728dst_ip=`ip_to_hex 8 8 8 8`
5729packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5730
5731# Send IP packet destined to 8.8.8.8 from lsp1lp2
5732as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5733
5734trim_zeros() {
5735 sed 's/\(00\)\{1,\}$//'
5736}
5737
5738# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5739# not 8.8.8.8
5740
5741$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5742expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5743echo $expected > expout
5744AT_CHECK([cat packets], [0], [expout])
5745cat packets
5746
5747OVN_CLEANUP([hv1])
5748
5749AT_CLEANUP
8439c2eb
CSV
5750
5751AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5752AT_SKIP_IF([test $HAVE_PYTHON = no])
5753ovn_start
5754# Create logical switch
5755ovn-nbctl ls-add ls0
5756# Create gateway router
5757ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5758# Add router port to gateway router
5759ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5760ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5761 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
5762# Add nat-address option
5763ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5764
5765net_add n1
5766sim_add hv1
5767as hv1
5768ovs-vsctl \
5769 -- add-br br-phys \
5770 -- add-br br-eth0
5771
5772ovn_attach n1 br-phys 192.168.0.1
5773
5774AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5775AT_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])
5776
5777# Create a localnet port.
5778AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5779AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5780AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5781AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5782
5783
5784# Wait for packet to be received.
5785OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5786trim_zeros() {
5787 sed 's/\(00\)\{1,\}$//'
5788}
5789$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5790expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5791echo $expected > expout
5792AT_CHECK([sort packets], [0], [expout])
5793cat packets
5794
5795OVN_CLEANUP([hv1])
5796
5797AT_CLEANUP
6e31816f 5798
e914fb54
MS
5799AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5800AT_SKIP_IF([test $HAVE_PYTHON = no])
5801ovn_start
5802# Create logical switch
5803ovn-nbctl ls-add ls0
5804# Create gateway router
5805ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5806# Add router port to gateway router
5807ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5808ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5809 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
5810# Add nat-address option
5811ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5812# Add NAT rules
5813AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5814AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5815# Add load balancers
5816AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5817AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5818AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5819AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5820
5821net_add n1
5822sim_add hv1
5823as hv1
5824ovs-vsctl \
5825 -- add-br br-phys \
5826 -- add-br br-eth0
5827
5828ovn_attach n1 br-phys 192.168.0.1
5829
5830AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5831AT_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])
5832
5833# Create a localnet port.
5834AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5835AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5836AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5837AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5838
5839
5840# Wait for packet to be received.
5841OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5842trim_zeros() {
5843 sed 's/\(00\)\{1,\}$//'
5844}
5845$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5846expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5847echo $expected > expout
5848expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5849echo $expected >> expout
5850expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5851echo $expected >> expout
5852AT_CHECK([sort packets], [0], [expout])
5853cat packets
5854
5855OVN_CLEANUP([hv1])
5856
5857AT_CLEANUP
5858
6e31816f 5859AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
5860ovn_start
5861net_add n1
5862sim_add hv1
5863as hv1
5864ovs-vsctl -- add-br br-phys
5865ovn_attach n1 br-phys 192.168.0.1
5866# Create logical switch ls0
5867ovn-nbctl ls-add ls0
5868# Create ports lp0, lp1 in ls0
5869ovn-nbctl lsp-add ls0 lp0
5870ovn-nbctl lsp-add ls0 lp1
5871ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5872ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5873dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5874ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5875ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5876ovn-sbctl find MAC_Binding
093aa761 5877# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5878ovn-nbctl lsp-del lp0
5879ovn-sbctl find MAC_Binding
093aa761
BP
5880OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5881# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5882ovn-nbctl ls-del ls0
5883ovn-sbctl find MAC_Binding
093aa761 5884OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
5885
5886OVN_CLEANUP([hv1])
5887
5888AT_CLEANUP
926c34fd
RM
5889
5890AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
5891AT_SKIP_IF([test $HAVE_PYTHON = no])
5892ovn_start
5893
5894# Logical network:
5895# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5896# connected to a router R1.
5897# foo has foo1 to act as a client.
5898# bar has bar1, bar2, bar3 to act as servers.
5899
5900net_add n1
5901
5902sim_add hv1
5903as hv1
5904ovs-vsctl add-br br-phys
5905ovn_attach n1 br-phys 192.168.0.1
5906for i in foo1 bar1 bar2 bar3; do
5907 ovs-vsctl -- add-port br-int $i -- \
5908 set interface $i external-ids:iface-id=$i \
5909 options:tx_pcap=hv1/$i-tx.pcap \
5910 options:rxq_pcap=hv1/$i-rx.pcap
5911done
5912
5913ovn-nbctl create Logical_Router name=R1
5914ovn-nbctl ls-add foo
5915ovn-nbctl ls-add bar
5916
5917# Connect foo to R1
5918ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5919ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5920 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5921
5922# Connect bar to R1
5923ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5924ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5925 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5926
5927# Create logical port foo1 in foo
5928ovn-nbctl lsp-add foo foo1 \
5929-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5930
5931# Create logical port bar1, bar2 and bar3 in bar
5932for i in `seq 1 3`; do
5933 ip=`expr $i + 1`
5934 ovn-nbctl lsp-add bar bar$i \
5935 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5936done
5937
5938OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5939
5940OVN_CLEANUP([hv1])
5941
5942AT_CLEANUP
b511690b
GS
5943
5944AT_SETUP([ovn -- tag allocation])
b511690b
GS
5945ovn_start
5946
5947AT_CHECK([ovn-nbctl ls-add ls0])
5948AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5949AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5950AT_CHECK([ovn-nbctl ls-add ls1])
5951
5952dnl When a tag is provided, no allocation is done
5953AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5954AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5955])
5956dnl The same 'tag' gets created in southbound database.
5957AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5958logical_port="c0"], [0], [3
5959])
5960
5961dnl Allocate tags and see it getting created in both NB and SB
5962AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5963AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5964])
5965AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5966logical_port="c1"], [0], [1
5967])
5968
5969AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5970AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5971])
5972AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5973logical_port="c2"], [0], [2
5974])
5975AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5976AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5977])
5978AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5979logical_port="c3"], [0], [4
5980])
5981
5982dnl A different parent.
5983AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5984AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5985])
5986AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5987logical_port="c4"], [0], [1
5988])
5989
5990AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5991AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5992])
5993AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5994logical_port="c5"], [0], [2
5995])
5996
5997dnl Delete a logical port and create a new one.
5998AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5999AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6000AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6001])
6002AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6003logical_port="c6"], [0], [1
6004])
6005
6006dnl Restart northd to see that the same allocation remains.
6007as northd
6008OVS_APP_EXIT_AND_WAIT([ovn-northd])
6009start_daemon ovn-northd \
6010 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6011 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6012
6013dnl Create a switch to make sure that ovn-northd has run through the main loop.
6014AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6015AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6016])
6017AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6018])
6019AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6020])
6021AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6022])
6023AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6024])
6025AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6026])
6027
6028dnl Create a switch port with a tag that has already been allocated.
6029dnl It should go through fine with a duplicate tag.
6030AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6031AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6032])
6033AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6034logical_port="c7"], [0], [2
6035])
6036AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6037])
6038
6039AT_CHECK([ovn-nbctl ls-add ls2])
6040dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
6041dnl gets copied to 'tag'
6042AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
6043AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
6044])
6045dnl The same 'tag' gets created in southbound database.
6046AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6047logical_port="local0"], [0], [25
6048])
6049dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
6050AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
6051AT_CHECK([ovn-nbctl lsp-get-tag local1])
6052dnl change the tag_request.
6053AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
6054AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
6055])
6056
6057AT_CLEANUP
57afd0c0
RR
6058
6059AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
6060ovn_start
6061ovn-nbctl ls-add lsw0
6062net_add n1
6063for i in 1 2; do
6064 sim_add hv$i
6065 as hv$i
6066 ovs-vsctl add-br br-phys
6067 ovn_attach n1 br-phys 192.168.0.$i
6068 ovs-vsctl add-br br-eth0
6069 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6070done
6071
6072# Create a localnet port.
6073AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
6074AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6075AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6076AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6077
6078
6079# Create 3 vifs.
6080AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6081AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6082AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6083AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
6084AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
6085AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6086AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6087AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6088AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6089
6090# Bind the localvif1 to hv1.
6091as hv1
6092AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6093
6094# On hv1, check that there are no flows outputting bcast to tunnel
6095OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6096
1ea9b847 6097# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 6098as hv2
1ea9b847 6099OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
6100
6101# Now bind vif2 on hv2.
6102AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6103
6104# At this point, the broadcast flow on vif2 should be deleted.
6105# because, there is now a localnet vif bound (table=32 programming logic)
6106OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6107
6108# Verify that the local net patch port exists on hv2.
6109OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6110
6111# Now bind vif3 on hv2.
6112AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6113
6114# Verify that the local net patch port still exists on hv2
6115OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6116
6117# Delete localvif2
6118AT_CHECK([ovn-nbctl lsp-del localvif2])
6119
6120# Verify that the local net patch port still exists on hv2,
6121# because, localvif3 is still bound.
6122OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6123
57afd0c0 6124OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
6125
6126AT_CLEANUP
6127
d383eed5
JP
6128
6129AT_SETUP([ovn -- ACL logging])
6130AT_KEYWORDS([ovn])
6131ovn_start
6132
6133net_add n1
6134
6135sim_add hv
6136as hv
6137ovs-vsctl add-br br-phys
6138ovn_attach n1 br-phys 192.168.0.1
6139for i in lp1 lp2; do
6140 ovs-vsctl -- add-port br-int $i -- \
6141 set interface $i external-ids:iface-id=$i \
6142 options:tx_pcap=hv/$i-tx.pcap \
6143 options:rxq_pcap=hv/$i-rx.pcap
6144done
6145
6146lp1_mac="f0:00:00:00:00:01"
6147lp1_ip="192.168.1.2"
6148
6149lp2_mac="f0:00:00:00:00:02"
6150lp2_ip="192.168.1.3"
6151
6152ovn-nbctl ls-add lsw0
6153ovn-nbctl --wait=sb lsp-add lsw0 lp1
6154ovn-nbctl --wait=sb lsp-add lsw0 lp2
6155ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6156ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6157ovn-nbctl --wait=sb sync
6158
6159ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6160ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6161
6162ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6163ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6164
6165ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6166ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6167
6168ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6169ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6170
6171ovn-sbctl dump-flows
6172
6173
6174# Send packet that should be dropped without logging.
6175packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6176 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6177 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6178as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6179
6180# Send packet that should be dropped with logging.
6181packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6182 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6183 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6184as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6185
6186# Send packet that should be allowed without logging.
6187packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6188 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6189 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6190as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6191
6192# Send packet that should be allowed with logging.
6193packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6194 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6195 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6196as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6197
6198# Send packet that should allow related flows without logging.
6199packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6200 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6201 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6202as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6203
6204# Send packet that should allow related flows with logging.
6205packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6206 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6207 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6208as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6209
df48cfc7 6210# Send packet that should be rejected without logging.
d383eed5
JP
6211packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6212 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6213 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6214as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6215
df48cfc7 6216# Send packet that should be rejected with logging.
d383eed5
JP
6217packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6218 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6219 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6220as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6221
c1f272f9
NS
6222OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6223
d383eed5
JP
6224AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6225name="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
6226name="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
6227name="<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
6228name="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
6229])
6230
6231OVN_CLEANUP([hv])
6232AT_CLEANUP
6233
6234
23749245
JP
6235AT_SETUP([ovn -- ACL rate-limited logging])
6236AT_KEYWORDS([ovn])
6237ovn_start
6238
6239net_add n1
6240
6241sim_add hv
6242as hv
6243ovs-vsctl add-br br-phys
6244ovn_attach n1 br-phys 192.168.0.1
6245for i in lp1 lp2; do
6246 ovs-vsctl -- add-port br-int $i -- \
6247 set interface $i external-ids:iface-id=$i \
6248 options:tx_pcap=hv/$i-tx.pcap \
6249 options:rxq_pcap=hv/$i-rx.pcap
6250done
6251
6252lp1_mac="f0:00:00:00:00:01"
6253lp1_ip="192.168.1.2"
6254
6255lp2_mac="f0:00:00:00:00:02"
6256lp2_ip="192.168.1.3"
6257
6258ovn-nbctl ls-add lsw0
6259ovn-nbctl --wait=sb lsp-add lsw0 lp1
6260ovn-nbctl --wait=sb lsp-add lsw0 lp2
6261ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6262ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6263ovn-nbctl --wait=sb sync
6264
6265
6266# Add an ACL that rate-limits logs at 10 per second.
6267ovn-nbctl meter-add http-rl1 drop 10 pktps
6268ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6269
6270# Add an ACL that rate-limits logs at 5 per second.
6271ovn-nbctl meter-add http-rl2 drop 5 pktps
6272ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
6273
6274# Add an ACL that doesn't rate-limit logs.
6275ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
6276
6277
6278# For each ACL, send 100 packets.
6279for i in `seq 1 100`; do
6280 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=80)'
6281
6282 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=81)'
6283
6284 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=82)'
6285done
6286
6287# Print some information that may help debugging.
6288as hv ovs-appctl -t ovn-controller meter-table-list
6289as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
6290
6291# The userspace meter implementation doesn't precisely enforce counts,
6292# so we just check that exactly 100 "http-acl3" actions were logged and
6293# that there were more "http-acl1" actions than "http-acl2" ones.
6294OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
6295
6296n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
6297n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
6298n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
6299
6300AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
6301AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
6302
6303
6304OVN_CLEANUP([hv])
6305AT_CLEANUP
6306
6307
66d89287 6308AT_SETUP([ovn -- DSCP marking and meter check])
1a03fc7d
BS
6309AT_KEYWORDS([ovn])
6310ovn_start
6311
6312ovn-nbctl ls-add lsw0
6313ovn-nbctl --wait=sb lsp-add lsw0 lp1
6314ovn-nbctl --wait=sb lsp-add lsw0 lp2
e50ed58a 6315ovn-nbctl --wait=sb lsp-add lsw0 lp3
1a03fc7d
BS
6316ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6317ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
e50ed58a 6318ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
1a03fc7d
BS
6319ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6320ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6321ovn-nbctl --wait=sb sync
6322net_add n1
6323sim_add hv
6324as hv
6325ovs-vsctl add-br br-phys
6326ovn_attach n1 br-phys 192.168.0.1
6327ovs-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
6328ovs-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
6329
6330AT_CAPTURE_FILE([trace])
6331ovn_trace () {
6332 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6333}
6334
6335# Extracts nw_tos from the final flow from ofproto/trace output and prints
6336# it on stdout. Prints "none" if no nw_tos was included.
6337get_final_nw_tos() {
6338 if flow=$(grep '^Final flow:' stdout); then :; else
6339 # The output didn't have a final flow.
6340 return 99
6341 fi
6342
6343 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6344 case $tos in
6345 '') echo none ;;
5a0e4aec 6346 *) echo $tos ;;
1a03fc7d
BS
6347 esac
6348}
6349
6350# check_tos TOS
6351#
6352# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6353check_tos() {
6354 # First check with ovn-trace for logical flows.
6355 echo "checking for tos $1"
6356 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6357 echo 'output("lp2");') > expout
6358 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])
6359
6360 # Then re-check with ofproto/trace for a physical packet.
6361 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])
6362 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6363])
6364}
6365
6366# check at L2
6367AT_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");
6368])
6369AT_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])
6370AT_CHECK([get_final_nw_tos], [0], [none
6371])
6372
6373# check at L3 without dscp marking
6374check_tos 0
6375
6376# Mark DSCP with a valid value
e50ed58a 6377qos_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
6378AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6379])
1a03fc7d
BS
6380check_tos 48
6381
66d89287
GL
6382# check at hv without qos meter
6383AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6384])
6385
6386# Update the meter rate
6387ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6388
6389# check at hv with a qos meter table
6390AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6391])
6392AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6393])
6394
1a03fc7d
BS
6395# Update the DSCP marking
6396ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6397check_tos 63
6398
66d89287
GL
6399# Update the meter rate
6400ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6401
6402# check at hv with a qos meter table
6403AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6404])
6405AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6406])
6407
1a03fc7d
BS
6408ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6409check_tos 63
6410
6411# Disable DSCP marking
5ee33cbd
GL
6412ovn-nbctl --wait=hv qos-del lsw0
6413AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6414])
1a03fc7d
BS
6415check_tos 0
6416
66d89287
GL
6417# check at hv without qos meter
6418AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6419])
6420
e50ed58a
GL
6421# check meter with chassis not resident
6422ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6423AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6424])
6425
6426# check no meter table
6427AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6428])
6429AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6430])
6431
1a03fc7d 6432OVN_CLEANUP([hv])
57afd0c0 6433AT_CLEANUP
7fff4eb7
LR
6434
6435AT_SETUP([ovn -- read-only sb db:ptcp access])
6436AT_SKIP_IF([test $HAVE_PYTHON = no])
6437
6438: > .$1.db.~lock~
6439ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6440
6441# Add read-only remote to sb ovsdb-server
6442AT_CHECK(
6443 [ovsdb-tool transact ovn-sb.db \
6444 ['["OVN_Southbound",
6445 {"op": "insert",
6446 "table": "SB_Global",
6447 "row": {
6448 "connections": ["set", [["named-uuid", "xyz"]]]}},
6449 {"op": "insert",
6450 "table": "Connection",
6451 "uuid-name": "xyz",
6452 "row": {"target": "ptcp:0:127.0.0.1",
6453 "read_only": true}}]']], [0], [ignore], [ignore])
6454
6455start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6456
6457PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6458
6459# read-only accesses should succeed
6460AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6461AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6462
6463# write access should fail
6464AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6465[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6466])
6467
6468OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6469AT_CLEANUP
6470
6471AT_SETUP([ovn -- read-only sb db:pssl access])
6472AT_SKIP_IF([test $HAVE_PYTHON = no])
6473AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6474PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6475AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6476\\]"])
6477
6478: > .$1.db.~lock~
6479ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6480
6481# Add read-only remote to sb ovsdb-server
6482AT_CHECK(
6483 [ovsdb-tool transact ovn-sb.db \
6484 ['["OVN_Southbound",
6485 {"op": "insert",
6486 "table": "SB_Global",
6487 "row": {
6488 "connections": ["set", [["named-uuid", "xyz"]]]}},
6489 {"op": "insert",
6490 "table": "Connection",
6491 "uuid-name": "xyz",
6492 "row": {"target": "pssl:0:127.0.0.1",
6493 "read_only": true}}]']], [0], [ignore], [ignore])
6494
6495start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6496 --remote=db:OVN_Southbound,SB_Global,connections \
6497 --private-key="$PKIDIR/testpki-privkey2.pem" \
6498 --certificate="$PKIDIR/testpki-cert2.pem" \
6499 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6500 ovn-sb.db
6501
6502PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6503
6504# read-only accesses should succeed
6505AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6506 --private-key=$PKIDIR/testpki-privkey.pem \
6507 --certificate=$PKIDIR/testpki-cert.pem \
6508 --ca-cert=$PKIDIR/testpki-cacert.pem \
6509 list SB_Global], [0], [stdout], [ignore])
6510AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6511 --private-key=$PKIDIR/testpki-privkey.pem \
6512 --certificate=$PKIDIR/testpki-cert.pem \
6513 --ca-cert=$PKIDIR/testpki-cacert.pem \
6514 list Connection], [0], [stdout], [ignore])
6515
6516# write access should fail
6517AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6518 --private-key=$PKIDIR/testpki-privkey.pem \
6519 --certificate=$PKIDIR/testpki-cert.pem \
6520 --ca-cert=$PKIDIR/testpki-cacert.pem \
6521 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6522[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6523])
6524
6525OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6526AT_CLEANUP
6527
821302cf
LR
6528AT_SETUP([ovn -- nb connection/ssl commands])
6529AT_SKIP_IF([test $HAVE_PYTHON = no])
6530AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6531PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6532AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6533\\]"])
6534
6535: > .$1.db.~lock~
6536ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6537
6538# Start nb db server using db connection/ssl entries (unpopulated initially)
6539start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6540 --remote=db:OVN_Northbound,NB_Global,connections \
6541 --private-key=db:OVN_Northbound,SSL,private_key \
6542 --certificate=db:OVN_Northbound,SSL,certificate \
6543 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6544 ovn-nb.db
6545
6546# Populate SSL configuration entries in nb db
6547AT_CHECK(
6548 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6549 $PKIDIR/testpki-cert.pem \
6550 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6551
6552# Populate a passive SSL connection in nb db
6553AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6554
6555PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6556
6557# Verify SSL connetivity to nb db server
6558AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6559 --private-key=$PKIDIR/testpki-privkey.pem \
6560 --certificate=$PKIDIR/testpki-cert.pem \
6561 --ca-cert=$PKIDIR/testpki-cacert.pem \
6562 list NB_Global],
6563 [0], [stdout], [ignore])
6564AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6565 --private-key=$PKIDIR/testpki-privkey.pem \
6566 --certificate=$PKIDIR/testpki-cert.pem \
6567 --ca-cert=$PKIDIR/testpki-cacert.pem \
6568 list Connection],
6569 [0], [stdout], [ignore])
6570AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6571 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6572 --certificate=$PKIDIR/testpki-cert.pem \
6573 --ca-cert=$PKIDIR/testpki-cacert.pem \
6574 get-connection],
6575 [0], [stdout], [ignore])
6576
6577OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6578AT_CLEANUP
6579
6580AT_SETUP([ovn -- sb connection/ssl commands])
6581AT_SKIP_IF([test $HAVE_PYTHON = no])
6582AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6583PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6584AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6585\\]"])
6586
6587: > .$1.db.~lock~
6588ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6589
6590# Start sb db server using db connection/ssl entries (unpopulated initially)
6591start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6592 --remote=db:OVN_Southbound,SB_Global,connections \
6593 --private-key=db:OVN_Southbound,SSL,private_key \
6594 --certificate=db:OVN_Southbound,SSL,certificate \
6595 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6596 ovn-sb.db
6597
6598# Populate SSL configuration entries in sb db
6599AT_CHECK(
6600 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6601 $PKIDIR/testpki-cert.pem \
6602 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6603
6604# Populate a passive SSL connection in sb db
6605AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6606
6607PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6608
6609# Verify SSL connetivity to sb db server
6610AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6611 --private-key=$PKIDIR/testpki-privkey.pem \
6612 --certificate=$PKIDIR/testpki-cert.pem \
6613 --ca-cert=$PKIDIR/testpki-cacert.pem \
6614 list SB_Global],
6615 [0], [stdout], [ignore])
6616AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6617 --private-key=$PKIDIR/testpki-privkey.pem \
6618 --certificate=$PKIDIR/testpki-cert.pem \
6619 --ca-cert=$PKIDIR/testpki-cacert.pem \
6620 list Connection],
6621 [0], [stdout], [ignore])
6622AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6623 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
6624 --certificate=$PKIDIR/testpki-cert.pem \
6625 --ca-cert=$PKIDIR/testpki-cacert.pem \
6626 get-connection],
6627 [0], [stdout], [ignore])
6628
6629OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6630AT_CLEANUP
6631
75fd74f8
GS
6632AT_SETUP([ovn -- nested containers])
6633ovn_start
6634
6635# Physical network:
6636# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6637
6638# Logical network:
6639# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6640# and "bar" (192.168.2.0/24). They are all connected to router R1.
6641
6642ovn-nbctl lr-add R1
6643ovn-nbctl ls-add mgmt
6644ovn-nbctl ls-add foo
6645ovn-nbctl ls-add bar
6646
6647# Connect mgmt to R1
6648ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6649ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6650 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6651
6652# Connect foo to R1
6653ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6654ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6655 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6656
6657# Connect bar to R1
6658ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6659ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6660 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6661
6662# "mgmt" has VM1 and VM2 connected
6663ovn-nbctl lsp-add mgmt vm1 \
6664-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6665
6666ovn-nbctl lsp-add mgmt vm2 \
6667-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6668
6669# "foo1" and "foo2" are containers belonging to switch "foo"
6670# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6671ovn-nbctl lsp-add foo foo1 vm1 1 \
6672-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6673
6674ovn-nbctl lsp-add foo foo2 vm2 2 \
6675-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6676
6677# "bar1" and "bar2" are containers belonging to switch "bar"
6678# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6679ovn-nbctl lsp-add bar bar1 vm1 2 \
6680-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6681
6682ovn-nbctl lsp-add bar bar2 vm2 1 \
6683-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6684
6685# bar3 is a standalone VM belonging to switch "bar"
6686ovn-nbctl lsp-add bar bar3 \
6687-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6688
6689# Create two hypervisor and create OVS ports corresponding to logical ports.
6690net_add n1
6691
6692sim_add hv1
6693as hv1
6694ovs-vsctl add-br br-phys
6695ovn_attach n1 br-phys 192.168.0.1
6696ovs-vsctl -- add-port br-int vm1 -- \
6697 set interface vm1 external-ids:iface-id=vm1 \
6698 options:tx_pcap=hv1/vm1-tx.pcap \
6699 options:rxq_pcap=hv1/vm1-rx.pcap \
6700 ofport-request=1
6701
6702ovs-vsctl -- add-port br-int bar3 -- \
6703 set interface bar3 external-ids:iface-id=bar3 \
6704 options:tx_pcap=hv1/bar3-tx.pcap \
6705 options:rxq_pcap=hv1/bar3-rx.pcap \
6706 ofport-request=2
6707
6708sim_add hv2
6709as hv2
6710ovs-vsctl add-br br-phys
6711ovn_attach n1 br-phys 192.168.0.2
6712ovs-vsctl -- add-port br-int vm2 -- \
6713 set interface vm2 external-ids:iface-id=vm2 \
6714 options:tx_pcap=hv2/vm2-tx.pcap \
6715 options:rxq_pcap=hv2/vm2-rx.pcap \
6716 ofport-request=1
6717
6718# Pre-populate the hypervisors' ARP tables so that we don't lose any
6719# packets for ARP resolution (native tunneling doesn't queue packets
6720# for ARP resolution).
74868f2c 6721OVN_POPULATE_ARP
75fd74f8
GS
6722
6723# Allow some time for ovn-northd and ovn-controller to catch up.
6724# XXX This should be more systematic.
6725sleep 1
6726
6727ip_to_hex() {
6728 printf "%02x%02x%02x%02x" "$@"
6729}
6730
6731# Send ip packets between foo1 and foo2 (same switch, different HVs and
6732# different VLAN tags).
6733src_mac="f00000010205"
6734dst_mac="f00000010206"
6735src_ip=`ip_to_hex 192 168 1 2`
6736dst_ip=`ip_to_hex 192 168 1 3`
6737packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6738as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6739
6740# expected packet at foo2
6741packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6742echo $packet > expected
6743OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6744
6745# Send ip packets between foo1 and bar2 (different switch, different HV)
6746src_mac="f00000010205"
6747dst_mac="000000010203"
6748src_ip=`ip_to_hex 192 168 1 2`
6749dst_ip=`ip_to_hex 192 168 2 3`
6750packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6751as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6752
6753# expected packet at bar2
6754src_mac="000000010204"
6755dst_mac="f00000010208"
6756packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6757echo $packet >> expected
6758OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6759
6760# Send ip packets between foo1 and bar1
6761# (different switch, loopback to same vm but different tag)
6762src_mac="f00000010205"
6763dst_mac="000000010203"
6764src_ip=`ip_to_hex 192 168 1 2`
6765dst_ip=`ip_to_hex 192 168 2 2`
6766packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6767as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6768
6769# expected packet at bar1
6770src_mac="000000010204"
6771dst_mac="f00000010207"
6772packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6773echo $packet > expected1
6774OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6775
6776# Send ip packets between bar1 and bar3
6777# (same switch. But one is container and another is a standalone VM)
6778src_mac="f00000010207"
6779dst_mac="f00000010209"
6780src_ip=`ip_to_hex 192 168 2 2`
6781dst_ip=`ip_to_hex 192 168 2 3`
6782packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6783as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6784
6785# expected packet at bar3
6786packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6787echo $packet > expected
6788OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6789
6790# Send ip packets between foo1 and vm1.
6791(different switch, container to the VM hosting it.)
6792src_mac="f00000010205"
6793dst_mac="000000010203"
6794src_ip=`ip_to_hex 192 168 1 2`
6795dst_ip=`ip_to_hex 172 16 1 2`
6796packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6797as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6798
6799# expected packet at vm1
6800src_mac="000000010202"
6801dst_mac="f00000010203"
6802packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6803echo $packet >> expected1
6804OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6805
6806# Send packets from vm1 to bar1.
6807(different switch, A hosting VM to a container inside it)
6808src_mac="f00000010203"
6809dst_mac="000000010202"
6810src_ip=`ip_to_hex 172 16 1 2`
6811dst_ip=`ip_to_hex 192 168 2 2`
6812packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6813as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6814
6815# expected packet at vm1
6816src_mac="000000010204"
6817dst_mac="f00000010207"
6818packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6819echo $packet >> expected1
6820OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6821
6822OVN_CLEANUP([hv1],[hv2])
6823
6824AT_CLEANUP
440a9f4b
GS
6825
6826AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6827AT_SKIP_IF([test $HAVE_PYTHON = no])
6828ovn_start
6829
6830# Logical network:
6831# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6832# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6833# (192.168.2.0/24) connected to it.
6834#
6835# R2 and R3 are gateway routers.
6836# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6837# connected to it. Note how both alice and bob have the same subnet behind it.
6838# We are trying to simulate external network via those 2 switches. In real
6839# world the switch ports of these switches will have addresses set as "unknown"
6840# to make them learning switches. Or those switches will be "localnet" ones.
6841
6842# Create three hypervisors and create OVS ports corresponding to logical ports.
6843net_add n1
6844
6845sim_add hv1
6846as hv1
6847ovs-vsctl add-br br-phys
6848ovn_attach n1 br-phys 192.168.0.1
6849ovs-vsctl -- add-port br-int hv1-vif1 -- \
6850 set interface hv1-vif1 external-ids:iface-id=foo1 \
6851 options:tx_pcap=hv1/vif1-tx.pcap \
6852 options:rxq_pcap=hv1/vif1-rx.pcap \
6853 ofport-request=1
6854
6855ovs-vsctl -- add-port br-int hv1-vif2 -- \
6856 set interface hv1-vif2 external-ids:iface-id=bar1 \
6857 options:tx_pcap=hv1/vif2-tx.pcap \
6858 options:rxq_pcap=hv1/vif2-rx.pcap \
6859 ofport-request=2
6860
6861sim_add hv2
6862as hv2
6863ovs-vsctl add-br br-phys
6864ovn_attach n1 br-phys 192.168.0.2
6865ovs-vsctl -- add-port br-int hv2-vif1 -- \
6866 set interface hv2-vif1 external-ids:iface-id=alice1 \
6867 options:tx_pcap=hv2/vif1-tx.pcap \
6868 options:rxq_pcap=hv2/vif1-rx.pcap \
6869 ofport-request=1
6870
6871sim_add hv3
6872as hv3
6873ovs-vsctl add-br br-phys
6874ovn_attach n1 br-phys 192.168.0.3
6875ovs-vsctl -- add-port br-int hv3-vif1 -- \
6876 set interface hv3-vif1 external-ids:iface-id=bob1 \
6877 options:tx_pcap=hv3/vif1-tx.pcap \
6878 options:rxq_pcap=hv3/vif1-rx.pcap \
6879 ofport-request=1
6880
6881
6882ovn-nbctl create Logical_Router name=R1
6883ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6884ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6885
6886ovn-nbctl ls-add foo
6887ovn-nbctl ls-add bar
6888ovn-nbctl ls-add alice
6889ovn-nbctl ls-add bob
6890ovn-nbctl ls-add join
6891
6892# Connect foo to R1
6893ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6894ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6895 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6896
6897# Connect bar to R1
6898ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6899ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6900 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6901
6902# Connect alice to R2
6903ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6904ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6905 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6906
6907# Connect bob to R3
6908ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6909ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6910 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6911
6912# Connect R1 to join
6913ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6914ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6915 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6916
6917# Connect R2 to join
6918ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6919ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6920 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6921
6922# Connect R3 to join
6923ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6924ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6925 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6926
6927# Install static routes with source ip address as the policy for routing.
6928# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6929ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6930ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6931
6932# Install static routes with destination ip address as the policy for routing.
6933ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6934
6935ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6936
6937# Create logical port foo1 in foo
6938ovn-nbctl lsp-add foo foo1 \
6939-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6940
6941# Create logical port bar1 in bar
6942ovn-nbctl lsp-add bar bar1 \
6943-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6944
6945# Create logical port alice1 in alice
6946ovn-nbctl lsp-add alice alice1 \
6947-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6948
6949# Create logical port bob1 in bob
6950ovn-nbctl lsp-add bob bob1 \
6951-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6952
6953# Pre-populate the hypervisors' ARP tables so that we don't lose any
6954# packets for ARP resolution (native tunneling doesn't queue packets
6955# for ARP resolution).
74868f2c 6956OVN_POPULATE_ARP
440a9f4b
GS
6957
6958# Allow some time for ovn-northd and ovn-controller to catch up.
6959# XXX This should be more systematic.
6960sleep 1
6961
6962ip_to_hex() {
6963 printf "%02x%02x%02x%02x" "$@"
6964}
6965trim_zeros() {
6966 sed 's/\(00\)\{1,\}$//'
6967}
6968
6969# Send ip packets between foo1 and bar1
6970# (East-west traffic should flow normally)
6971src_mac="f00000010203"
6972dst_mac="000001010203"
6973src_ip=`ip_to_hex 192 168 1 2`
6974dst_ip=`ip_to_hex 192 168 2 2`
6975packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6976as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6977
6978# Send ip packets between foo1 and alice1
6979src_mac="f00000010203"
6980dst_mac="000001010203"
6981src_ip=`ip_to_hex 192 168 1 2`
6982dst_ip=`ip_to_hex 172 16 1 3`
6983packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6984as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 6985as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
6986
6987# Send ip packets between bar1 and bob1
6988src_mac="f00000010204"
6989dst_mac="000001010204"
6990src_ip=`ip_to_hex 192 168 2 2`
6991dst_ip=`ip_to_hex 172 16 1 4`
6992packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6993as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6994#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6995
6996# Packet to expect at bar1
6997src_mac="000001010204"
6998dst_mac="f00000010204"
6999src_ip=`ip_to_hex 192 168 1 2`
7000dst_ip=`ip_to_hex 192 168 2 2`
7001expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7002echo $expected > expected
7003OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7004
7005# Packet to Expect at alice1
7006src_mac="000002010203"
7007dst_mac="f00000010205"
7008src_ip=`ip_to_hex 192 168 1 2`
7009dst_ip=`ip_to_hex 172 16 1 3`
7010expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7011echo $expected > expected
7012OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7013
7014# Packet to Expect at bob1
7015src_mac="000003010203"
7016dst_mac="f00000010206"
7017src_ip=`ip_to_hex 192 168 2 2`
7018dst_ip=`ip_to_hex 172 16 1 4`
7019expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7020echo $expected > expected
7021OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
7022
7023for sim in hv1 hv2 hv3; do
7024 as $sim
7025 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7026 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7027 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7028done
7029
7030as ovn-sb
7031OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7032
7033as ovn-nb
7034OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7035
7036as northd
7037OVS_APP_EXIT_AND_WAIT([ovn-northd])
7038
7039as main
7040OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7041OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7042
7043AT_CLEANUP
41a15b71 7044
302eda27
NS
7045AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
7046AT_SKIP_IF([test $HAVE_PYTHON = no])
7047ovn_start
7048
7049ovn-nbctl ls-add ls1
7050
7051ovn-nbctl lsp-add ls1 ls1-lp1 \
7052-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7053
7054ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7055
7056ovn-nbctl lsp-add ls1 ls1-lp2 \
7057-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7058
7059ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7060
7061DNS1=`ovn-nbctl create DNS records={}`
7062DNS2=`ovn-nbctl create DNS records={}`
7063
7064ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7065ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
7066ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
7067
7068ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
7069
7070net_add n1
7071sim_add hv1
7072
7073as hv1
7074ovs-vsctl add-br br-phys
7075ovn_attach n1 br-phys 192.168.0.1
7076ovs-vsctl -- add-port br-int hv1-vif1 -- \
7077 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
7078 options:tx_pcap=hv1/vif1-tx.pcap \
7079 options:rxq_pcap=hv1/vif1-rx.pcap \
7080 ofport-request=1
7081
7082ovs-vsctl -- add-port br-int hv1-vif2 -- \
7083 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
7084 options:tx_pcap=hv1/vif2-tx.pcap \
7085 options:rxq_pcap=hv1/vif2-rx.pcap \
7086 ofport-request=2
7087
74868f2c 7088OVN_POPULATE_ARP
302eda27
NS
7089sleep 2
7090as hv1 ovs-vsctl show
7091
7092echo "*************************"
7093ovn-sbctl list DNS
7094echo "*************************"
7095
7096ip_to_hex() {
7097 printf "%02x%02x%02x%02x" "$@"
7098}
7099
7100reset_pcap_file() {
7101 local iface=$1
7102 local pcap_file=$2
7103 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7104options:rxq_pcap=dummy-rx.pcap
7105 rm -f ${pcap_file}*.pcap
7106 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7107options:rxq_pcap=${pcap_file}-rx.pcap
7108}
7109
7110# set_dns_params host_name
7111# Sets the dns_req_data and dns_resp_data
7112set_dns_params() {
7113 local hname=$1
7114 local ttl=00000e10
7115 an_count=0001
7116 type=0001
7117 case $hname in
7118 vm1)
7119 # vm1.ovn.org
7120 query_name=03766d31036f766e036f726700
7121 # IPv4 address - 10.0.0.4
7122 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7123 ;;
7124 vm2)
7125 # vm2.ovn.org
7126 query_name=03766d32036f766e036f726700
7127 # IPv4 address - 10.0.0.6
7128 expected_dns_answer=${query_name}00010001${ttl}00040a000006
7129 # IPv4 address - 20.0.0.4
7130 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
7131 an_count=0002
7132 ;;
7133 vm3)
7134 # vm3.ovn.org
7135 query_name=03766d33036f766e036f726700
7136 # IPv4 address - 40.0.0.4
7137 expected_dns_answer=${query_name}00010001${ttl}000428000004
7138 ;;
7139 vm1_ipv6_only)
7140 # vm1.ovn.org
7141 query_name=03766d31036f766e036f726700
7142 # IPv6 address - aef0::4
7143 type=001c
7144 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
7145 ;;
7146 vm1_ipv4_v6)
7147 # vm1.ovn.org
7148 query_name=03766d31036f766e036f726700
7149 type=00ff
7150 an_count=0002
7151 # IPv4 address - 10.0.0.4
7152 # IPv6 address - aef0::4
7153 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7154 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7155 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7156 ;;
7157 vm1_invalid_type)
7158 # vm1.ovn.org
7159 query_name=03766d31036f766e036f726700
7160 # IPv6 address - aef0::4
7161 type=0002
7162 ;;
7163 vm1_incomplete)
7164 # set type to none
7165 type=''
7166 esac
7167 # TTL - 3600
7168 local dns_req_header=010201200001000000000000
7169 local dns_resp_header=010281200001${an_count}00000000
7170 dns_req_data=${dns_req_header}${query_name}${type}0001
7171 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7172}
7173
7174# This shell function sends a DNS request packet
7175# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7176test_dns() {
7177 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7178 local dns_query_data=$7
7179 shift; shift; shift; shift; shift; shift; shift;
7180 # Packet size => IPv4 header (20) + UDP header (8) +
7181 # DNS data (header + query)
7182 ip_len=`expr 28 + ${#dns_query_data} / 2`
7183 udp_len=`expr $ip_len - 20`
7184 ip_len=$(printf "%x" $ip_len)
7185 udp_len=$(printf "%x" $udp_len)
7186 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7187 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7188 # dns data
7189 request=${request}${dns_query_data}
7190
7191 if test $dns_reply != 0; then
7192 local dns_reply=$1
7193 ip_len=`expr 28 + ${#dns_reply} / 2`
7194 udp_len=`expr $ip_len - 20`
7195 ip_len=$(printf "%x" $ip_len)
7196 udp_len=$(printf "%x" $udp_len)
7197 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7198 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7199 echo $reply >> $inport.expected
7200 else
7201 for outport; do
7202 echo $request >> $outport.expected
7203 done
7204 fi
7205 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7206}
7207
f8e79d82
MM
7208test_dns6() {
7209 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7210 local dns_query_data=$7
7211 shift; shift; shift; shift; shift; shift; shift;
7212 # Packet size => UDP header (8) +
7213 # DNS data (header + query)
7214 ip_len=`expr 8 + ${#dns_query_data} / 2`
7215 udp_len=$ip_len
7216 ip_len=$(printf "%x" $ip_len)
7217 udp_len=$(printf "%x" $udp_len)
7218 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7219 request=${request}9234003500${udp_len}0000
7220 #dns data
7221 request=${request}${dns_query_data}
7222
7223 if test $dns_reply != 0; then
7224 local dns_reply=$1
7225 ip_len=`expr 8 + ${#dns_reply} / 2`
7226 udp_len=$ip_len
7227 ip_len=$(printf "%x" $ip_len)
7228 udp_len=$(printf "%x" $udp_len)
7229 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7230 reply=${reply}0035923400${udp_len}0000${dns_reply}
7231 echo $reply >> $inport.expected
7232 else
7233 for outport; do
7234 echo $request >> $outport.expected
7235 done
7236 fi
7237 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7238}
7239
302eda27
NS
7240AT_CAPTURE_FILE([ofctl_monitor0.log])
7241as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7242--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7243
7244set_dns_params vm2
7245src_ip=`ip_to_hex 10 0 0 4`
7246dst_ip=`ip_to_hex 10 0 0 1`
7247dns_reply=1
7248test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7249
7250# NXT_RESUMEs should be 1.
7251OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7252
7253$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7254cat 1.expected | cut -c -48 > expout
7255AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7256# Skipping the IPv4 checksum.
7257cat 1.expected | cut -c 53- > expout
7258AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7259
7260reset_pcap_file hv1-vif1 hv1/vif1
7261reset_pcap_file hv1-vif2 hv1/vif2
7262rm -f 1.expected
7263rm -f 2.expected
7264
7265set_dns_params vm1
7266src_ip=`ip_to_hex 10 0 0 6`
7267dst_ip=`ip_to_hex 10 0 0 1`
7268dns_reply=1
7269test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7270
7271# NXT_RESUMEs should be 2.
7272OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7273
7274$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7275cat 2.expected | cut -c -48 > expout
7276AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7277# Skipping the IPv4 checksum.
7278cat 2.expected | cut -c 53- > expout
7279AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7280
7281reset_pcap_file hv1-vif1 hv1/vif1
7282reset_pcap_file hv1-vif2 hv1/vif2
7283rm -f 1.expected
7284rm -f 2.expected
7285
7286# Clear the query name options for ls1-lp2
7287ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7288
7289set_dns_params vm2
7290src_ip=`ip_to_hex 10 0 0 4`
7291dst_ip=`ip_to_hex 10 0 0 1`
7292dns_reply=0
7293test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7294
7295# NXT_RESUMEs should be 3.
7296OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7297
7298$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7299AT_CHECK([cat 1.packets], [0], [])
7300
7301reset_pcap_file hv1-vif1 hv1/vif1
7302reset_pcap_file hv1-vif2 hv1/vif2
7303rm -f 1.expected
7304rm -f 2.expected
7305
7306# Clear the query name for ls1-lp1
7307# Since ls1 has no query names configued,
7308# ovn-northd should not add the DNS flows.
7309ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7310
7311set_dns_params vm1
7312src_ip=`ip_to_hex 10 0 0 6`
7313dst_ip=`ip_to_hex 10 0 0 1`
7314dns_reply=0
7315test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7316
7317# NXT_RESUMEs should be 3 only.
7318OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7319
7320$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7321AT_CHECK([cat 2.packets], [0], [])
7322
7323reset_pcap_file hv1-vif1 hv1/vif1
7324reset_pcap_file hv1-vif2 hv1/vif2
7325rm -f 1.expected
7326rm -f 2.expected
7327
7328# Test IPv6 (AAAA records) using IPv4 packet.
7329# Add back the DNS options for ls1-lp1.
4f4ac4bb 7330ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
302eda27
NS
7331
7332set_dns_params vm1_ipv6_only
7333src_ip=`ip_to_hex 10 0 0 6`
7334dst_ip=`ip_to_hex 10 0 0 1`
7335dns_reply=1
7336test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7337
7338# NXT_RESUMEs should be 4.
7339OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7340
7341$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7342cat 2.expected | cut -c -48 > expout
7343AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7344# Skipping the IPv4 checksum.
7345cat 2.expected | cut -c 53- > expout
7346AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7347
7348reset_pcap_file hv1-vif1 hv1/vif1
7349reset_pcap_file hv1-vif2 hv1/vif2
7350rm -f 1.expected
7351rm -f 2.expected
7352
7353# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7354set_dns_params vm1_ipv4_v6
7355src_ip=`ip_to_hex 10 0 0 6`
7356dst_ip=`ip_to_hex 10 0 0 1`
7357dns_reply=1
7358test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7359
7360# NXT_RESUMEs should be 5.
7361OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7362
7363$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7364cat 2.expected | cut -c -48 > expout
7365AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7366# Skipping the IPv4 checksum.
7367cat 2.expected | cut -c 53- > expout
7368AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7369
7370reset_pcap_file hv1-vif1 hv1/vif1
7371reset_pcap_file hv1-vif2 hv1/vif2
7372rm -f 1.expected
7373rm -f 2.expected
7374
7375# Invalid type.
7376set_dns_params vm1_invalid_type
7377src_ip=`ip_to_hex 10 0 0 6`
7378dst_ip=`ip_to_hex 10 0 0 1`
7379dns_reply=0
7380test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7381
7382# NXT_RESUMEs should be 6.
7383OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7384
7385$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7386AT_CHECK([cat 2.packets], [0], [])
7387
7388reset_pcap_file hv1-vif1 hv1/vif1
7389reset_pcap_file hv1-vif2 hv1/vif2
7390rm -f 1.expected
7391rm -f 2.expected
7392
7393# Incomplete DNS packet.
7394set_dns_params vm1_incomplete
7395src_ip=`ip_to_hex 10 0 0 6`
7396dst_ip=`ip_to_hex 10 0 0 1`
7397dns_reply=0
7398test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7399
7400# NXT_RESUMEs should be 7.
7401OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7402
7403$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7404AT_CHECK([cat 2.packets], [0], [])
7405
7406reset_pcap_file hv1-vif1 hv1/vif1
7407reset_pcap_file hv1-vif2 hv1/vif2
7408rm -f 1.expected
7409rm -f 2.expected
7410
7411# Add one more DNS record to the ls1.
7412ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7413
7414set_dns_params vm3
7415src_ip=`ip_to_hex 10 0 0 4`
7416dst_ip=`ip_to_hex 10 0 0 1`
7417dns_reply=1
7418test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7419
7420# NXT_RESUMEs should be 8.
7421OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7422
7423$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7424cat 1.expected | cut -c -48 > expout
7425AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7426# Skipping the IPv4 checksum.
7427cat 1.expected | cut -c 53- > expout
7428AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7429
7430reset_pcap_file hv1-vif1 hv1/vif1
7431reset_pcap_file hv1-vif2 hv1/vif2
7432rm -f 1.expected
7433rm -f 2.expected
7434
f8e79d82
MM
7435# Try DNS query over IPv6
7436set_dns_params vm1
7437src_ip=aef00000000000000000000000000004
7438dst_ip=aef00000000000000000000000000001
7439dns_reply=1
7440test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7441
7442# NXT_RESUMEs should be 9.
7443OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7444
7445$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
b75f2651
MM
7446# Skipping the UDP checksum.
7447cat 1.expected | cut -c 1-120,125- > expout
7448AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
f8e79d82
MM
7449
7450reset_pcap_file hv1-vif1 hv1/vif1
7451reset_pcap_file hv1-vif2 hv1/vif2
7452rm -f 1.expected
7453rm -f 2.expected
7454
302eda27
NS
7455as hv1
7456 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7457OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7458OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7459
7460as ovn-sb
7461OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7462
7463as ovn-nb
7464OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7465
7466as northd
7467OVS_APP_EXIT_AND_WAIT([ovn-northd])
7468
7469as main
7470OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7471OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7472AT_CLEANUP
7473
75f9e007 7474AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 7475AT_SKIP_IF([test $HAVE_PYTHON = no])
7476ovn_start
7477
7478net_add n1
7479
7480sim_add hv1
7481as hv1
7482ovs-vsctl add-br br-phys
7483ovn_attach n1 br-phys 192.168.0.1
7484ovs-vsctl -- add-port br-int hv1-vif1 -- \
7485 set interface hv1-vif1 external-ids:iface-id=foo1 \
7486 options:tx_pcap=hv1/vif1-tx.pcap \
7487 options:rxq_pcap=hv1/vif1-rx.pcap \
7488 ofport-request=1
7489
7490sim_add gw1
7491as gw1
7492ovs-vsctl add-br br-phys
7493ovn_attach n1 br-phys 192.168.0.2
7494
7495sim_add gw2
7496as gw2
7497ovs-vsctl add-br br-phys
7498ovn_attach n1 br-phys 192.168.0.4
7499
7500sim_add ext1
7501as ext1
7502ovs-vsctl add-br br-phys
7503ovn_attach n1 br-phys 192.168.0.3
7504ovs-vsctl -- add-port br-int ext1-vif1 -- \
7505 set interface ext1-vif1 external-ids:iface-id=outside1 \
7506 options:tx_pcap=ext1/vif1-tx.pcap \
7507 options:rxq_pcap=ext1/vif1-rx.pcap \
7508 ofport-request=1
7509
7510# Pre-populate the hypervisors' ARP tables so that we don't lose any
7511# packets for ARP resolution (native tunneling doesn't queue packets
7512# for ARP resolution).
74868f2c 7513OVN_POPULATE_ARP
1da17a0b 7514
7515ovn-nbctl create Logical_Router name=R1
7516
7517ovn-nbctl ls-add foo
7518ovn-nbctl ls-add alice
7519ovn-nbctl ls-add outside
7520
7521# Connect foo to R1
7522ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7523ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7524 type=router options:router-port=foo \
7525 -- lsp-set-addresses rp-foo router
7526
7527# Connect alice to R1 as distributed router gateway port on gw1
7528ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7529
7530ovn-nbctl \
7531 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7532 chassis_name=gw1 \
7533 priority=20 -- \
7534 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7535 chassis_name=gw2 \
7536 priority=10 -- \
7537 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7538
7539ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7540 type=router options:router-port=alice \
7541 -- lsp-set-addresses rp-alice router
7542
7543# Create logical port foo1 in foo
7544ovn-nbctl lsp-add foo foo1 \
7545-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7546
7547# Create logical port outside1 in outside
7548ovn-nbctl lsp-add outside outside1 \
7549-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7550
7551# Create localnet port in alice
7552ovn-nbctl lsp-add alice ln-alice
7553ovn-nbctl lsp-set-addresses ln-alice unknown
7554ovn-nbctl lsp-set-type ln-alice localnet
7555ovn-nbctl lsp-set-options ln-alice network_name=phys
7556
7557# Create localnet port in outside
7558ovn-nbctl lsp-add outside ln-outside
7559ovn-nbctl lsp-set-addresses ln-outside unknown
7560ovn-nbctl lsp-set-type ln-outside localnet
7561ovn-nbctl lsp-set-options ln-outside network_name=phys
7562
7563# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7564# mapping to the external network, is the one generating packets
7565as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7566as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7567as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7568
7569AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7570
7571# Allow some time for ovn-northd and ovn-controller to catch up.
7572# XXX This should be more systematic.
7573sleep 2
7574
7575ip_to_hex() {
7576 printf "%02x%02x%02x%02x" "$@"
7577}
7578
7579reset_pcap_file() {
7580 local iface=$1
7581 local pcap_file=$2
7582 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7583options:rxq_pcap=dummy-rx.pcap
7584 rm -f ${pcap_file}*.pcap
7585 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7586options:rxq_pcap=${pcap_file}-rx.pcap
7587}
7588
7589test_ip_packet()
7590{
7591 local active_gw=$1
7592 local backup_gw=$2
7593
7594 # Send ip packet between foo1 and outside1
7595 src_mac="f00000010203" # foo1 mac
7596 dst_mac="000001010203" # rp-foo mac (internal router leg)
7597 src_ip=`ip_to_hex 192 168 1 2`
7598 dst_ip=`ip_to_hex 172 16 1 3`
7599 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7600
7601 # ARP request packet to expect at outside1
7602 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7603
7604 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7605
7606 # Send ARP reply from outside1 back to the router
7607 # XXX: note, we could avoid this if we plug this port into a netns
7608 # and setup the IP address into the port, so the kernel would simply reply
7609 src_mac="000002010203"
7610 reply_mac="f00000010204"
7611 dst_ip=`ip_to_hex 172 16 1 3`
7612 src_ip=`ip_to_hex 172 16 1 1`
7613 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7614
7615 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7616
86c9d79a
NS
7617 OVS_WAIT_UNTIL([
7618 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7619grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7620 ])
7621
1da17a0b 7622 # Packet to Expect at ext1 chassis, outside1 port
7623 src_mac="000002010203"
7624 dst_mac="f00000010204"
7625 src_ip=`ip_to_hex 192 168 1 2`
7626 dst_ip=`ip_to_hex 172 16 1 3`
7627 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7628 echo $expected > ext1-vif1.expected
7629
7630 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7631 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7632 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7633
7634 # Resend packet from foo1 to outside1
7635 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7636
7637 sleep 1
7638
7639 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7640 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7641 AT_CHECK([grep $expected packets | sort], [0], [expout])
7642 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7643 AT_CHECK([grep $expected packets | sort], [0], [])
7644}
7645
7646test_ip_packet gw1 gw2
7647
75f9e007
GZ
7648ovn-nbctl --timeout=3 --wait=hv \
7649 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7650 chassis_name=gw1 \
7651 priority=10 -- \
7652 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7653 chassis_name=gw2 \
7654 priority=20 -- \
7655 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7656
7657test_ip_packet gw2 gw1
7658
7659OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7660AT_CLEANUP
7661
7662AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7663AT_SKIP_IF([test $HAVE_PYTHON = no])
7664ovn_start
7665
7666net_add n1
7667
7668sim_add hv1
7669as hv1
7670ovs-vsctl add-br br-phys
7671ovn_attach n1 br-phys 192.168.0.1
7672ovs-vsctl -- add-port br-int hv1-vif1 -- \
7673 set interface hv1-vif1 external-ids:iface-id=foo1 \
7674 options:tx_pcap=hv1/vif1-tx.pcap \
7675 options:rxq_pcap=hv1/vif1-rx.pcap \
7676 ofport-request=1
7677
7678sim_add gw1
7679as gw1
7680ovs-vsctl add-br br-phys
7681ovn_attach n1 br-phys 192.168.0.2
7682
7683sim_add gw2
7684as gw2
7685ovs-vsctl add-br br-phys
7686ovn_attach n1 br-phys 192.168.0.4
7687
7688sim_add ext1
7689as ext1
7690ovs-vsctl add-br br-phys
7691ovn_attach n1 br-phys 192.168.0.3
7692ovs-vsctl -- add-port br-int ext1-vif1 -- \
7693 set interface ext1-vif1 external-ids:iface-id=outside1 \
7694 options:tx_pcap=ext1/vif1-tx.pcap \
7695 options:rxq_pcap=ext1/vif1-rx.pcap \
7696 ofport-request=1
7697
7698# Pre-populate the hypervisors' ARP tables so that we don't lose any
7699# packets for ARP resolution (native tunneling doesn't queue packets
7700# for ARP resolution).
74868f2c 7701OVN_POPULATE_ARP
75f9e007
GZ
7702
7703ovn-nbctl create Logical_Router name=R0
7704ovn-nbctl create Logical_Router name=R1
7705
7706ovn-nbctl ls-add foo
7707ovn-nbctl ls-add join
7708ovn-nbctl ls-add alice
7709ovn-nbctl ls-add outside
7710
7711#Connect foo to R0
7712ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7713ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7714 type=router options:router-port=R0-foo \
7715 -- lsp-set-addresses foo-R0 router
7716
7717#Connect R0 to join
7718ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7719ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7720 type=router options:router-port=R0-join \
7721 -- lsp-set-addresses join-R0 router
7722
7723#Connect join to R1
7724ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7725ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7726 type=router options:router-port=R1-join \
7727 -- lsp-set-addresses join-R1 router
7728
7729#add route rules
7730ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7731ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7732
7733# Connect alice to R1 as distributed router gateway port on gw1
7734ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7735
7736ovn-nbctl \
7737 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7738 chassis_name=gw1 \
7739 priority=20 -- \
7740 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7741 chassis_name=gw2 \
7742 priority=10 -- \
7743 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7744
7745ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7746 type=router options:router-port=alice \
7747 -- lsp-set-addresses rp-alice router
7748
7749# Create logical port foo1 in foo
7750ovn-nbctl lsp-add foo foo1 \
7751-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7752
7753# Create logical port outside1 in outside
7754ovn-nbctl lsp-add outside outside1 \
7755-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7756
7757# Create localnet port in alice
7758ovn-nbctl lsp-add alice ln-alice
7759ovn-nbctl lsp-set-addresses ln-alice unknown
7760ovn-nbctl lsp-set-type ln-alice localnet
7761ovn-nbctl lsp-set-options ln-alice network_name=phys
7762
7763# Create localnet port in outside
7764ovn-nbctl lsp-add outside ln-outside
7765ovn-nbctl lsp-set-addresses ln-outside unknown
7766ovn-nbctl lsp-set-type ln-outside localnet
7767ovn-nbctl lsp-set-options ln-outside network_name=phys
7768
7769# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7770# mapping to the external network, is the one generating packets
7771as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7772as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7773as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7774
7775AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7776
7777# Allow some time for ovn-northd and ovn-controller to catch up.
7778# XXX This should be more systematic.
7779sleep 2
7780
7781ip_to_hex() {
7782 printf "%02x%02x%02x%02x" "$@"
7783}
7784
7785reset_pcap_file() {
7786 local iface=$1
7787 local pcap_file=$2
7788 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7789options:rxq_pcap=dummy-rx.pcap
7790 rm -f ${pcap_file}*.pcap
7791 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7792options:rxq_pcap=${pcap_file}-rx.pcap
7793}
7794
7795test_ip_packet()
7796{
7797 local active_gw=$1
7798 local backup_gw=$2
7799
7800 # Send ip packet between foo1 and outside1
7801 src_mac="f00000010203" # foo1 mac
7802 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7803 src_ip=`ip_to_hex 192 168 1 2`
7804 dst_ip=`ip_to_hex 172 16 1 3`
7805 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7806
7807 # ARP request packet to expect at outside1
7808 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7809
7810 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7811
7812 # Send ARP reply from outside1 back to the router
7813 # XXX: note, we could avoid this if we plug this port into a netns
7814 # and setup the IP address into the port, so the kernel would simply reply
7815 src_mac="000002010203"
7816 reply_mac="f00000010204"
7817 dst_ip=`ip_to_hex 172 16 1 3`
7818 src_ip=`ip_to_hex 172 16 1 1`
7819 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7820
7821 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7822
86c9d79a
NS
7823 OVS_WAIT_UNTIL([
7824 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7825grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7826 ])
7827
75f9e007
GZ
7828 # Packet to Expect at ext1 chassis, outside1 port
7829 src_mac="000002010203"
7830 dst_mac="f00000010204"
7831 src_ip=`ip_to_hex 192 168 1 2`
7832 dst_ip=`ip_to_hex 172 16 1 3`
7833 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7834 echo $expected > ext1-vif1.expected
7835
7836 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7837 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7838 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7839
7840 # Resend packet from foo1 to outside1
7841 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7842
7843 sleep 1
7844
7845 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7846 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7847 AT_CHECK([grep $expected packets | sort], [0], [expout])
7848 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7849 AT_CHECK([grep $expected packets | sort], [0], [])
7850}
7851
7852test_ip_packet gw1 gw2
7853
8e1d9349 7854ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 7855 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7856 chassis_name=gw1 \
7857 priority=10 -- \
7858 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7859 chassis_name=gw2 \
7860 priority=20 -- \
7861 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7862
7863test_ip_packet gw2 gw1
7864
7865OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7866AT_CLEANUP
7867
41a15b71
MS
7868AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7869AT_SKIP_IF([test $HAVE_PYTHON = no])
7870ovn_start
7871
7872# Logical network:
7873# One LR R1 that has switches foo (192.168.1.0/24) and
7874# alice (172.16.1.0/24) connected to it. The logical port
7875# between R1 and alice has a "redirect-chassis" specified,
7876# i.e. it is the distributed router gateway port.
7877# Switch alice also has a localnet port defined.
7878# An additional switch outside has a localnet port and the
7879# same subnet as alice (172.16.1.0/24).
7880
7881# Physical network:
7882# Three hypervisors hv[123].
7883# hv1 hosts vif foo1.
7884# hv2 is the "redirect-chassis" that hosts the distributed
7885# router gateway port.
7886# hv3 hosts vif outside1.
7887# In order to show that connectivity works only through hv2,
7888# an initial round of tests is run without any bridge-mapping
7889# defined for the localnet on hv2. These tests are expected
7890# to fail.
7891# Subsequent tests are run after defining the bridge-mapping
7892# for the localnet on hv2. These tests are expected to succeed.
7893
7894# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 7895# to logical ports.
41a15b71
MS
7896net_add n1
7897
7898sim_add hv1
7899as hv1
7900ovs-vsctl add-br br-phys
7901ovn_attach n1 br-phys 192.168.0.1
7902ovs-vsctl -- add-port br-int hv1-vif1 -- \
7903 set interface hv1-vif1 external-ids:iface-id=foo1 \
7904 options:tx_pcap=hv1/vif1-tx.pcap \
7905 options:rxq_pcap=hv1/vif1-rx.pcap \
7906 ofport-request=1
7907
7908sim_add hv2
7909as hv2
7910ovs-vsctl add-br br-phys
7911ovn_attach n1 br-phys 192.168.0.2
7912
7913sim_add hv3
7914as hv3
7915ovs-vsctl add-br br-phys
7916ovn_attach n1 br-phys 192.168.0.3
7917ovs-vsctl -- add-port br-int hv3-vif1 -- \
7918 set interface hv3-vif1 external-ids:iface-id=outside1 \
7919 options:tx_pcap=hv3/vif1-tx.pcap \
7920 options:rxq_pcap=hv3/vif1-rx.pcap \
7921 ofport-request=1
7922
7923# Pre-populate the hypervisors' ARP tables so that we don't lose any
7924# packets for ARP resolution (native tunneling doesn't queue packets
7925# for ARP resolution).
74868f2c 7926OVN_POPULATE_ARP
41a15b71
MS
7927
7928ovn-nbctl create Logical_Router name=R1
7929
7930ovn-nbctl ls-add foo
7931ovn-nbctl ls-add alice
7932ovn-nbctl ls-add outside
7933
7934# Connect foo to R1
7935ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7936ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7937 type=router options:router-port=foo \
7938 -- lsp-set-addresses rp-foo router
7939
7940# Connect alice to R1 as distributed router gateway port on hv2
7941ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7942 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7943ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7944 type=router options:router-port=alice \
7945 -- lsp-set-addresses rp-alice router
7946
7947# Create logical port foo1 in foo
7948ovn-nbctl lsp-add foo foo1 \
7949-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7950
7951# Create logical port outside1 in outside
7952ovn-nbctl lsp-add outside outside1 \
7953-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7954
7955# Create localnet port in alice
7956ovn-nbctl lsp-add alice ln-alice
7957ovn-nbctl lsp-set-addresses ln-alice unknown
7958ovn-nbctl lsp-set-type ln-alice localnet
7959ovn-nbctl lsp-set-options ln-alice network_name=phys
7960
7961# Create localnet port in outside
7962ovn-nbctl lsp-add outside ln-outside
7963ovn-nbctl lsp-set-addresses ln-outside unknown
7964ovn-nbctl lsp-set-type ln-outside localnet
7965ovn-nbctl lsp-set-options ln-outside network_name=phys
7966
7967# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7968as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7969as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7970
7971
7972# Allow some time for ovn-northd and ovn-controller to catch up.
7973# XXX This should be more systematic.
7974sleep 2
7975
7976echo "---------NB dump-----"
7977ovn-nbctl show
7978echo "---------------------"
7979ovn-nbctl list logical_router
7980echo "---------------------"
7981ovn-nbctl list logical_router_port
7982echo "---------------------"
7983
7984echo "---------SB dump-----"
7985ovn-sbctl list datapath_binding
7986echo "---------------------"
7987ovn-sbctl list port_binding
7988echo "---------------------"
7989ovn-sbctl dump-flows
7990echo "---------------------"
7991ovn-sbctl list chassis
7992ovn-sbctl list encap
1da17a0b 7993echo "------ Gateway_Chassis dump (SBDB) -------"
7994ovn-sbctl list Gateway_Chassis
7995echo "------ Port_Binding chassisredirect -------"
7996ovn-sbctl find Port_Binding type=chassisredirect
7997echo "-------------------------------------------"
41a15b71
MS
7998
7999echo "------ hv1 dump ----------"
8000as hv1 ovs-ofctl show br-int
8001as hv1 ovs-ofctl dump-flows br-int
8002echo "------ hv2 dump ----------"
8003as hv2 ovs-ofctl show br-int
8004as hv2 ovs-ofctl dump-flows br-int
8005echo "------ hv3 dump ----------"
8006as hv3 ovs-ofctl show br-int
8007as hv3 ovs-ofctl dump-flows br-int
8008echo "--------------------------"
8009
1da17a0b 8010
41a15b71
MS
8011# Check that redirect mapping is programmed only on hv2
8012AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8013])
8014AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
8015])
8016# Check that hv1 sends chassisredirect port traffic to hv2
8017AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
8018])
8019AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8020])
8021# Check that arp reply on distributed gateway port is only programmed on hv2
8022AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
8023])
8024AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
8025])
8026
8027
8028ip_to_hex() {
8029 printf "%02x%02x%02x%02x" "$@"
8030}
8031
8032
8033: > hv2-vif1.expected
8034: > hv3-vif1.expected
8035
8036# test_arp INPORT SHA SPA TPA [REPLY_HA]
8037#
8038# Causes a packet to be received on INPORT. The packet is an ARP
8039# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
8040# it should be the hardware address of the target to expect to receive in an
8041# ARP reply; otherwise no reply is expected.
8042#
8043# INPORT is an logical switch port number, e.g. 11 for vif11.
8044# SHA and REPLY_HA are each 12 hex digits.
8045# SPA and TPA are each 8 hex digits.
8046test_arp() {
8047 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
8048 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
8049 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
8050
8051 if test X$reply_ha != X; then
8052 # Expect to receive the reply, if any.
8053 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
8054 echo $reply >> hv${hv}-vif$inport.expected
8055 fi
8056}
8057
8058rtr_ip=$(ip_to_hex 172 16 1 1)
8059foo_ip=$(ip_to_hex 192 168 1 2)
8060outside_ip=$(ip_to_hex 172 16 1 3)
8061
8062echo $rtr_ip
8063echo $foo_ip
8064echo $outside_ip
8065
8066# ARP for router IP address from outside1, no response expected
8067test_arp 3 1 f00000010204 $outside_ip $rtr_ip
8068
8069# Now check the packets actually received against the ones expected.
8070OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8071
8072# Send ip packet between foo1 and outside1
8073src_mac="f00000010203"
8074dst_mac="000001010203"
8075src_ip=`ip_to_hex 192 168 1 2`
8076dst_ip=`ip_to_hex 172 16 1 3`
8077packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8078
8079# Now check the packets actually received against the ones expected.
8080OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8081
8082# Now add bridge-mappings on hv2, which should make everything work
8083as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8084
8085# Allow some time for ovn-northd and ovn-controller to catch up.
8086# XXX This should be more systematic.
8087sleep 2
8088
8089# ARP for router IP address from outside1
8090test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
8091
8092# Now check the packets actually received against the ones expected.
8093OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8094
8095# Send ip packet between foo1 and outside1
8096src_mac="f00000010203"
8097dst_mac="000001010203"
8098src_ip=`ip_to_hex 192 168 1 2`
8099dst_ip=`ip_to_hex 172 16 1 3`
8100packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8101
8102# ARP request packet to expect at outside1
8103src_mac="000002010203"
8104src_ip=`ip_to_hex 172 16 1 1`
8105arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8106
8107as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8108
8109echo $arp_request >> hv3-vif1.expected
8110OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8111
8112# Send ARP reply from outside1 back to the router
8113reply_mac="f00000010204"
8114arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8115
8116as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
8117
8118# Allow some time for ovn-northd and ovn-controller to catch up.
8119# XXX This should be more systematic.
8120sleep 1
8121
8122# Packet to Expect at outside1
8123src_mac="000002010203"
8124dst_mac="f00000010204"
8125src_ip=`ip_to_hex 192 168 1 2`
8126dst_ip=`ip_to_hex 172 16 1 3`
8127expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8128
8129# Resend packet from foo1 to outside1
8130as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8131
8132echo "------ hv1 dump ----------"
8133as hv1 ovs-ofctl show br-int
8134as hv1 ovs-ofctl dump-flows br-int
8135echo "------ hv2 dump ----------"
8136as hv2 ovs-ofctl show br-int
8137as hv2 ovs-ofctl dump-flows br-int
8138echo "------ hv3 dump ----------"
8139as hv3 ovs-ofctl show br-int
8140as hv3 ovs-ofctl dump-flows br-int
8141echo "----------------------------"
8142
8143echo $expected >> hv3-vif1.expected
8144OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8145
8146#Check ovn-trace over "chassisredirect" port
8147AT_CAPTURE_FILE([trace])
8148ovn_trace () {
8149 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
8150}
8151
8152echo 'ip.ttl--;' > expout
8153echo 'eth.src = 00:00:02:01:02:03;' >> expout
8154echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8155echo 'output("ln-alice");' >> expout
8156AT_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])
8157
8158# Create logical port alice1 in alice on hv1
8159as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8160 set interface hv1-vif2 external-ids:iface-id=alice1 \
8161 options:tx_pcap=hv1/vif2-tx.pcap \
8162 options:rxq_pcap=hv1/vif2-rx.pcap \
8163 ofport-request=1
8164
8165ovn-nbctl lsp-add alice alice1 \
8166-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8167
8168# Create logical port foo2 in foo on hv2
8169as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8170 set interface hv2-vif1 external-ids:iface-id=foo2 \
8171 options:tx_pcap=hv2/vif1-tx.pcap \
8172 options:rxq_pcap=hv2/vif1-rx.pcap \
8173 ofport-request=1
8174
8175ovn-nbctl lsp-add foo foo2 \
8176-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8177
8178# Allow some time for ovn-northd and ovn-controller to catch up.
8179# XXX This should be more systematic.
8180sleep 1
8181
8182: > hv1-vif2.expected
8183
8184# Send ip packet between alice1 and foo2
8185src_mac="f00000010205"
8186dst_mac="000002010203"
8187src_ip=`ip_to_hex 172 16 1 4`
8188dst_ip=`ip_to_hex 192 168 1 3`
8189packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8190
8191as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8192
8193# Packet to Expect at foo2
8194src_mac="000001010203"
8195dst_mac="f00000010206"
8196src_ip=`ip_to_hex 172 16 1 4`
8197dst_ip=`ip_to_hex 192 168 1 3`
8198expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8199
8200echo $expected >> hv2-vif1.expected
f5f64552 8201OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 8202
0d31e5be 8203AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 8204])
8205
8e1d9349 8206ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 8207
0d31e5be 8208AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 8209])
8210
41a15b71
MS
8211OVN_CLEANUP([hv1],[hv2],[hv3])
8212
8213AT_CLEANUP
26b9e08d
MS
8214
8215AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8216AT_SKIP_IF([test $HAVE_PYTHON = no])
8217ovn_start
8218# Create logical switches
8219ovn-nbctl ls-add ls0
8220ovn-nbctl ls-add ls1
8221# Create distributed router
8222ovn-nbctl create Logical_Router name=lr0
8223# Add distributed gateway port to distributed router
8224ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8225 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8226ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8227 type=router options:router-port=lrp0 addresses="router"
8228# Add router port to ls1
8229ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8230ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8231 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
8232# Add logical ports for NAT rules
8233ovn-nbctl lsp-add ls1 foo1 \
8234-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8235ovn-nbctl lsp-add ls1 foo2 \
8236-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
8237# Add nat-addresses option
8238ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8239# Add NAT rules
8240AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8241AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8242AT_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 8243AT_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
8244
8245net_add n1
8246sim_add hv1
8247as hv1
8248ovs-vsctl add-br br-phys
8249ovn_attach n1 br-phys 192.168.0.1
8250
8251AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8252AT_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])
8253
8254sim_add hv2
8255as hv2
8256ovs-vsctl add-br br-phys
8257ovn_attach n1 br-phys 192.168.0.2
8258# Initially test with no bridge-mapping on hv2, expect to receive no packets
8259
f40c5588
MS
8260sim_add hv3
8261as hv3
8262ovs-vsctl add-br br-phys
8263ovn_attach n1 br-phys 192.168.0.3
8264# Initially test with no bridge-mapping on hv3
8265
26b9e08d
MS
8266# Create a localnet port.
8267AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8268AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8269AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8270AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8271
8272# Allow some time for ovn-northd and ovn-controller to catch up.
8273# XXX This should be more systematic.
8274sleep 2
8275
8276# Expect no packets when hv2 bridge-mapping is not present
8277: > packets
8278OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8279
8280# Add bridge-mapping on hv2
f40c5588 8281AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
8282
8283# Wait for packets to be received.
8284OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8285trim_zeros() {
8286 sed 's/\(00\)\{1,\}$//'
8287}
8288$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8289expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8290echo $expected > expout
8291expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8292echo $expected >> expout
8293AT_CHECK([sort packets], [0], [expout])
f40c5588 8294sort packets | cat
26b9e08d 8295
f40c5588
MS
8296# Temporarily remove nat-addresses option to avoid race conditions
8297# due to GARP backoff
8298ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8299
8300reset_pcap_file() {
8301 local iface=$1
8302 local pcap_file=$2
8303 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8304options:rxq_pcap=dummy-rx.pcap
8305 rm -f ${pcap_file}*.pcap
8306 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8307options:rxq_pcap=${pcap_file}-rx.pcap
8308}
8309
8310as hv1 reset_pcap_file snoopvif hv1/snoopvif
8311
8312# Add OVS ports for foo1 and foo2 on hv3
8313ovs-vsctl -- add-port br-int hv3-vif1 -- \
8314 set interface hv3-vif1 external-ids:iface-id=foo1 \
8315 ofport-request=1
8316ovs-vsctl -- add-port br-int hv3-vif2 -- \
8317 set interface hv3-vif2 external-ids:iface-id=foo2 \
8318 ofport-request=2
8319
8320# Add bridge-mapping on hv3
8321AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8322
8323# Re-add nat-addresses option
8324ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8325
8326# Wait for packets to be received.
8327OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8328trim_zeros() {
8329 sed 's/\(00\)\{1,\}$//'
8330}
8331
8332$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8333expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8334echo $expected >> expout
8335expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8336echo $expected >> expout
8337AT_CHECK([sort packets], [0], [expout])
8338sort packets | cat
8339
8340OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
8341
8342AT_CLEANUP
6b785fd8 8343
4364646c
ZKL
8344AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8345AT_KEYWORDS([ovn-nd_ra])
8346AT_SKIP_IF([test $HAVE_PYTHON = no])
8347ovn_start
8348
8349# In this test case we create 1 lswitch with 3 VIF ports attached,
8350# and a lrouter connected to the lswitch.
8351# We generate the Router solicitation packet and verify the Router Advertisement
8352# reply packet from the ovn-controller.
8353
8354# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8355# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8356# 'slaac' to allow lrp0 send RA for SLAAC mode.
8357ovn-nbctl ls-add lsw0
8358ovn-nbctl lr-add lr0
8359ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8360ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8361ovn-nbctl \
8362 -- lsp-add lsw0 lsp0 \
8363 -- set Logical_Switch_Port lsp0 type=router \
8364 options:router-port=lrp0 \
8365 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8366net_add n1
8367sim_add hv1
8368as hv1
8369ovs-vsctl add-br br-phys
8370ovn_attach n1 br-phys 192.168.0.2
8371
8372ovn-nbctl lsp-add lsw0 lp1
8373ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8374ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8375
8376ovn-nbctl lsp-add lsw0 lp2
8377ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8378ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8379
8380ovn-nbctl lsp-add lsw0 lp3
8381ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8382ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8383
8384# Add ACL rule for ICMPv6 on lsw0
8385ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8386ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8387ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8388ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8389
8390ovs-vsctl -- add-port br-int hv1-vif1 -- \
8391 set interface hv1-vif1 external-ids:iface-id=lp1 \
8392 options:tx_pcap=hv1/vif1-tx.pcap \
8393 options:rxq_pcap=hv1/vif1-rx.pcap \
8394 ofport-request=1
8395
8396ovs-vsctl -- add-port br-int hv1-vif2 -- \
8397 set interface hv1-vif2 external-ids:iface-id=lp2 \
8398 options:tx_pcap=hv1/vif2-tx.pcap \
8399 options:rxq_pcap=hv1/vif2-rx.pcap \
8400 ofport-request=2
8401
8402ovs-vsctl -- add-port br-int hv1-vif3 -- \
8403 set interface hv1-vif3 external-ids:iface-id=lp3 \
8404 options:tx_pcap=hv1/vif3-tx.pcap \
8405 options:rxq_pcap=hv1/vif3-rx.pcap \
8406 ofport-request=3
8407
8408# Allow some time for ovn-northd and ovn-controller to catch up.
8409# XXX This should be more systematic.
8410sleep 1
8411
8412reset_pcap_file() {
8413 local iface=$1
8414 local pcap_file=$2
8415 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8416options:rxq_pcap=dummy-rx.pcap
8417 rm -f ${pcap_file}*.pcap
8418 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8419options:rxq_pcap=${pcap_file}-rx.pcap
8420}
8421
8422# Make sure that ovn-controller has installed the corresponding OF Flow.
8423OVS_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"`])
8424
8425# This shell function sends a Router Solicitation packet.
8426# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8427test_ipv6_ra() {
8428 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8429 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8430
8431 local len=24
8432 local mtu_opt=""
8433 if test $mtu != 0; then
8434 len=`expr $len + 8`
8435 mtu_opt=05010000${mtu}
8436 fi
8437
8438 if test ${#prefix_opt} != 0; then
8439 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8440 len=`expr $len + ${#prefix_opt} / 2`
8441 fi
8442
8443 len=$(printf "%x" $len)
8444 local lrp_mac=fa163e000001
8445 local lrp_lla=fe80000000000000f8163efffe000001
8446 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8447 echo $reply >> $inport.expected
8448
8449 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8450}
8451
8452AT_CAPTURE_FILE([ofctl_monitor0.log])
8453as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8454--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8455
8456# MTU is not set and the address mode is set to slaac
8457addr_mode=00
8458default_prefix_option_config=030440c0ffffffffffffffff00000000
8459src_mac=fa163e000002
8460src_lla=fe80000000000000f8163efffe000002
8461test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8462
8463# NXT_RESUME should be 1.
8464OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8465
8466$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8467
8468cat 1.expected | cut -c -112 > expout
8469AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8470
8471# Skipping the ICMPv6 checksum.
8472cat 1.expected | cut -c 117- > expout
8473AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8474
8475rm -f *.expected
8476reset_pcap_file hv1-vif1 hv1/vif1
8477reset_pcap_file hv1-vif2 hv1/vif2
8478reset_pcap_file hv1-vif3 hv1/vif3
8479
8480# Set the MTU to 1500
8481ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8482
8483# Make sure that ovn-controller has installed the corresponding OF Flow.
8484OVS_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"`])
8485
8486addr_mode=00
8487default_prefix_option_config=030440c0ffffffffffffffff00000000
8488src_mac=fa163e000003
8489src_lla=fe80000000000000f8163efffe000003
8490mtu=000005dc
8491
8492test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8493
8494# NXT_RESUME should be 2.
8495OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8496
8497$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8498
8499cat 2.expected | cut -c -112 > expout
8500AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8501
8502# Skipping the ICMPv6 checksum.
8503cat 2.expected | cut -c 117- > expout
8504AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8505
8506rm -f *.expected
8507reset_pcap_file hv1-vif1 hv1/vif1
8508reset_pcap_file hv1-vif2 hv1/vif2
8509reset_pcap_file hv1-vif3 hv1/vif3
8510
8511# Set the address mode to dhcpv6_stateful
8512ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8513# Make sure that ovn-controller has installed the corresponding OF Flow.
8514OVS_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"`])
8515
8516addr_mode=80
8517default_prefix_option_config=""
8518src_mac=fa163e000004
8519src_lla=fe80000000000000f8163efffe000004
8520mtu=000005dc
8521
8522test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8523
8524# NXT_RESUME should be 3.
8525OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8526
8527$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8528
8529cat 3.expected | cut -c -112 > expout
8530AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8531
8532# Skipping the ICMPv6 checksum.
8533cat 3.expected | cut -c 117- > expout
8534AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8535
8536rm -f *.expected
8537reset_pcap_file hv1-vif1 hv1/vif1
8538reset_pcap_file hv1-vif2 hv1/vif2
8539reset_pcap_file hv1-vif3 hv1/vif3
8540
8541# Set the address mode to dhcpv6_stateless
8542ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8543# Make sure that ovn-controller has installed the corresponding OF Flow.
8544OVS_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"`])
8545
8546addr_mode=40
8547default_prefix_option_config=030440c0ffffffffffffffff00000000
8548src_mac=fa163e000002
8549src_lla=fe80000000000000f8163efffe000002
8550mtu=000005dc
8551
8552test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8553
8554# NXT_RESUME should be 4.
8555OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8556
8557$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8558
8559cat 1.expected | cut -c -112 > expout
8560AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8561
8562# Skipping the ICMPv6 checksum.
8563cat 1.expected | cut -c 117- > expout
8564AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8565
8566rm -f *.expected
8567reset_pcap_file hv1-vif1 hv1/vif1
8568reset_pcap_file hv1-vif2 hv1/vif2
8569reset_pcap_file hv1-vif3 hv1/vif3
8570
8571# Set the address mode to invalid.
8572ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8573# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8574OVS_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"`])
8575
8576addr_mode=40
8577default_prefix_option_config=""
8578src_mac=fa163e000002
8579src_lla=fe80000000000000f8163efffe000002
8580mtu=000005dc
8581
8582test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8583
8584# NXT_RESUME should be 4 only.
8585OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8586
8587$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8588AT_CHECK([cat 1.packets], [0], [])
8589
8590OVN_CLEANUP([hv1])
8591AT_CLEANUP
8592
6b785fd8
GS
8593AT_SETUP([ovn -- /32 router IP address])
8594AT_SKIP_IF([test $HAVE_PYTHON = no])
8595ovn_start
8596
8597# Logical network:
8598# 2 LS 'foo' and 'alice' connected via router R1.
8599# R1 connects to 'alice' with a /32 IP address. We use static routes and
8600# nexthop to push traffic to a logical port in switch 'alice'
8601
8602ovn-nbctl lr-add R1
8603
8604ovn-nbctl ls-add foo
8605ovn-nbctl ls-add alice
8606
8607# Connect foo to R1
8608ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8609ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8610 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8611
8612# Connect alice to R1.
8613ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8614ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8615 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8616
8617# Create logical port foo1 in foo
8618ovn-nbctl lsp-add foo foo1 \
8619-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8620
8621# Create logical port alice1 in alice
8622ovn-nbctl lsp-add alice alice1 \
8623-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8624
8625#install default route in R1 to use alice1's IP address as nexthop
8626ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8627
8628# Create two hypervisor and create OVS ports corresponding to logical ports.
8629net_add n1
8630
8631sim_add hv1
8632as hv1
8633ovs-vsctl add-br br-phys
8634ovn_attach n1 br-phys 192.168.0.1
8635ovs-vsctl -- add-port br-int hv1-vif1 -- \
8636 set interface hv1-vif1 external-ids:iface-id=foo1 \
8637 options:tx_pcap=hv1/vif1-tx.pcap \
8638 options:rxq_pcap=hv1/vif1-rx.pcap \
8639 ofport-request=1
8640
8641sim_add hv2
8642as hv2
8643ovs-vsctl add-br br-phys
8644ovn_attach n1 br-phys 192.168.0.2
8645ovs-vsctl -- add-port br-int hv2-vif1 -- \
8646 set interface hv2-vif1 external-ids:iface-id=alice1 \
8647 options:tx_pcap=hv2/vif1-tx.pcap \
8648 options:rxq_pcap=hv2/vif1-rx.pcap \
8649 ofport-request=1
8650
8651
8652# Pre-populate the hypervisors' ARP tables so that we don't lose any
8653# packets for ARP resolution (native tunneling doesn't queue packets
8654# for ARP resolution).
74868f2c 8655OVN_POPULATE_ARP
6b785fd8
GS
8656
8657# Allow some time for ovn-northd and ovn-controller to catch up.
8658# XXX This should be more systematic.
8659sleep 1
8660
8661ip_to_hex() {
8662 printf "%02x%02x%02x%02x" "$@"
8663}
8664
8665# Send ip packets between foo1 and alice1
8666src_mac="f00000010203"
8667dst_mac="000000010203"
8668src_ip=`ip_to_hex 192 168 1 2`
8669dst_ip=`ip_to_hex 10 0 0 2`
8670packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8671
8672# Send the first packet to trigger a ARP response and population of
8673# mac_bindings table.
8674as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8675OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
b0b27a83 8676ovn-nbctl --wait=hv sync
6b785fd8
GS
8677# Send the second packet to reach the destination.
8678as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8679
8680# Packet to Expect at 'alice1'
8681src_mac="000000010204"
8682dst_mac="f00000010204"
8683src_ip=`ip_to_hex 192 168 1 2`
8684dst_ip=`ip_to_hex 10 0 0 2`
8685echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8686
8687OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8688
8689OVN_CLEANUP([hv1],[hv2])
8690
8691AT_CLEANUP
2a38ef45
DA
8692
8693AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8694AT_SKIP_IF([test $HAVE_PYTHON = no])
8695ovn_start
8696
8697ovn-nbctl ls-add ls1
8698
8699# Add localport to the switch
8700ovn-nbctl lsp-add ls1 lp01
8701ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8702ovn-nbctl lsp-set-type lp01 localport
8703
8704net_add n1
8705
8706for i in 1 2; do
8707 sim_add hv$i
8708 as hv$i
8709 ovs-vsctl add-br br-phys
8710 ovn_attach n1 br-phys 192.168.0.$i
8711 ovs-vsctl add-port br-int vif01 -- \
8712 set Interface vif01 external-ids:iface-id=lp01 \
8713 options:tx_pcap=hv${i}/vif01-tx.pcap \
8714 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8715 ofport-request=${i}0
8716
8717 ovs-vsctl add-port br-int vif${i}1 -- \
8718 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8719 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8720 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8721 ofport-request=${i}1
8722
8723 ovn-nbctl lsp-add ls1 lp${i}1
8724 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8725 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8726
8727 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8728done
8729
8730ovn-nbctl --wait=sb sync
8731ovn-sbctl dump-flows
8732
74868f2c 8733OVN_POPULATE_ARP
2a38ef45
DA
8734
8735# Given the name of a logical port, prints the name of the hypervisor
8736# on which it is located.
8737vif_to_hv() {
8738 echo hv${1%?}
8739}
8740#
8741# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8742#
8743# This shell function causes a packet to be received on INPORT. The packet's
8744# content has Ethernet destination DST and source SRC (each exactly 12 hex
8745# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8746# logical switch port numbers, e.g. 11 for vif11.
8747#
8748# EOUT is the end-to-end output port, that is, where the packet will end up
8749# after possibly bouncing through one or more localnet ports. LOUT is the
8750# logical output port, which might be a localnet port, as seen by ovn-trace
8751# (which doesn't know what localnet ports are connected to and therefore can't
8752# figure out the end-to-end answer).
8753#
8754# DEFHV is the default hypervisor from where the packet is going to be sent
8755# if the source port is a localport.
8756for i in 1 2; do
8757 for j in 0 1; do
8758 : > $i$j.expected
8759 done
8760done
8761test_packet() {
8762 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8763 echo "$@"
8764
8765 # First try tracing the packet.
8766 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8767 if test $lout != drop; then
8768 echo "output(\"$lout\");"
8769 fi > expout
8770 AT_CAPTURE_FILE([trace])
8771 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8772
8773 # Then actually send a packet, for an end-to-end test.
8774 local packet=$(echo $dst$src | sed 's/://g')${eth}
8775 hv=`vif_to_hv $inport`
8776 # If hypervisor 0 (localport) use the defhv parameter
da88b550 8777 if test $hv = hv0; then
2a38ef45
DA
8778 hv=$defhv
8779 fi
8780 vif=vif$inport
8781 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8782 if test $eout != drop; then
8783 echo $packet >> ${eout#lp}.expected
8784 fi
8785}
8786
8787
8788# lp11 and lp21 are on different hypervisors
8789test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8790test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8791
8792# Both VIFs should be able to reach the localport on their own HV
8793test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8794test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8795
8796# Packet sent from localport on same hv should reach the vif
8797test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8798test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8799
8800# Packet sent from localport on different hv should be dropped
8801test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8802test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8803
8804# Now check the packets actually received against the ones expected.
8805for i in 1 2; do
8806 for j in 0 1; do
8807 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8808 done
8809done
8810
8811OVN_CLEANUP([hv1],[hv2])
8812
8813AT_CLEANUP
1da17a0b 8814
8815AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8816AT_SKIP_IF([test $HAVE_PYTHON = no])
8817ovn_start
8818
8819net_add n1
8820
8821# create gateways with external network connectivity
8822
8823for i in 1 2; do
8824 sim_add gw$i
8825 as gw$i
8826 ovs-vsctl add-br br-phys
8827 ovn_attach n1 br-phys 192.168.0.$i
8828 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8829done
8830
8831ovn-nbctl ls-add inside
8832ovn-nbctl ls-add outside
8833
8834# create hypervisors with a vif port each to an internal network
8835
8836for i in 1 2; do
8837 sim_add hv$i
8838 as hv$i
8839 ovs-vsctl add-br br-phys
8840 ovn_attach n1 br-phys 192.168.0.1$i
8841 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8842 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8843 options:tx_pcap=hv$i/vif1-tx.pcap \
8844 options:rxq_pcap=hv$i/vif1-rx.pcap \
8845 ofport-request=1
8846
8847 ovn-nbctl lsp-add inside inside$i \
8848 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8849
8850done
8851
74868f2c 8852OVN_POPULATE_ARP
1da17a0b 8853
8854ovn-nbctl create Logical_Router name=R1
8855
8856# Connect inside to R1
8857ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8858ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8859 type=router options:router-port=inside \
8860 -- lsp-set-addresses rp-inside router
8861
8862# Connect outside to R1 as distributed router gateway port on gw1+gw2
8863ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8864
8865ovn-nbctl --id=@gc0 create Gateway_Chassis \
8866 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8867 --id=@gc1 create Gateway_Chassis \
8868 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8869 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8870
8871ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8872 type=router options:router-port=outside \
8873 -- lsp-set-addresses rp-outside router
8874
8875# Create localnet port in outside
8876ovn-nbctl lsp-add outside ln-outside
8877ovn-nbctl lsp-set-addresses ln-outside unknown
8878ovn-nbctl lsp-set-type ln-outside localnet
8879ovn-nbctl lsp-set-options ln-outside network_name=phys
8880
8881# Allow some time for ovn-northd and ovn-controller to catch up.
8882# XXX This should be more systematic.
8e1d9349 8883ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8884
8885echo "---------NB dump-----"
8886ovn-nbctl show
8887echo "---------------------"
8888ovn-nbctl list logical_router
8889echo "---------------------"
8890ovn-nbctl list logical_router_port
8891echo "---------------------"
8892
8893echo "---------SB dump-----"
8894ovn-sbctl list datapath_binding
8895echo "---------------------"
8896ovn-sbctl list port_binding
8897echo "---------------------"
8898ovn-sbctl dump-flows
8899echo "---------------------"
8900ovn-sbctl list chassis
8901ovn-sbctl list encap
8902echo "---------------------"
8903echo "------ Gateway_Chassis dump (SBDB) -------"
8904ovn-sbctl list Gateway_Chassis
8905echo "------ Port_Binding chassisredirect -------"
8906ovn-sbctl find Port_Binding type=chassisredirect
8907echo "-------------------------------------------"
8908
3475695e
VA
8909for chassis in gw1 gw2 hv1 hv2; do
8910 as $chassis
8911 echo "------ $chassis dump ----------"
8912 ovs-ofctl show br-int
8913 ovs-ofctl dump-flows br-int
3475695e
VA
8914 echo "--------------------------"
8915done
508b7f96 8916function bfd_dump() {
8917 for chassis in gw1 gw2 hv1 hv2; do
8918 as $chassis
8919 echo "------ $chassis dump (BFD)----"
8920 echo "BFD (from $chassis):"
8921 # dump BFD config and status to the other chassis
8922 for chassis2 in gw1 gw2 hv1 hv2; do
8923 if [[ "$chassis" != "$chassis2" ]]; then
8924 echo " -> $chassis2:"
8925 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8926 fi
8927 done
8928 echo "--------------------------"
8929 done
8930}
8931
8932bfd_dump
1da17a0b 8933
8934hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8935hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8936hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8937hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8938
8939echo $hv1_gw1_ofport
8940echo $hv1_gw2_ofport
8941echo $hv2_gw1_ofport
8942echo $hv2_gw2_ofport
8943
8944echo "--- hv1 ---"
8945as hv1 ovs-ofctl dump-flows br-int table=32
8946
8947echo "--- hv2 ---"
8948as hv2 ovs-ofctl dump-flows br-int table=32
8949
508b7f96 8950gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8951gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8952
1da17a0b 8953AT_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
8954])
8955
8956AT_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
8957])
8958
508b7f96 8959sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8960
8961# make sure that flows for handling the outside router port reside on gw1
66d89287 8962AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8963]])
66d89287 8964AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8965]])
8966
8967# make sure ARP responder flows for outside router port reside on gw1 too
8968AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8969]])
8970AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8971]])
8972
8973
8974
8975# check that the chassis redirect port has been claimed by the gw1 chassis
8976AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8977 [0],[[1
8978]])
8979
8980
8981# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 8982
8983ovn-nbctl --id=@gc0 create Gateway_Chassis \
8984 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8985 --id=@gc1 create Gateway_Chassis \
8986 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8987 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8988
508b7f96 8989
1da17a0b 8990# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 8991ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8992
508b7f96 8993# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 8994AT_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
8995])
8996
8997AT_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
8998])
8999
508b7f96 9000# check that the chassis redirect port has been reclaimed by the gw2 chassis
9001AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
9002 [0],[[1
9003]])
1da17a0b 9004
3475695e
VA
9005# check BFD enablement on tunnel ports from gw1 #########
9006as gw1
9007for chassis in gw2 hv1 hv2; do
9008 echo "checking gw1 -> $chassis"
9009 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9010 [[enable=true
9011]])
9012done
9013
9014
9015# check BFD enablement on tunnel ports from gw2 ##########
9016as gw2
9017for chassis in gw1 hv1 hv2; do
9018 echo "checking gw2 -> $chassis"
9019 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9020 [[enable=true
9021]])
9022done
9023
9024# check BFD enablement on tunnel ports from hv1 ###########
9025as hv1
9026for chassis in gw1 gw2; do
9027 echo "checking hv1 -> $chassis"
9028 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9029 [[enable=true
9030]])
9031done
9032# make sure BFD is not enabled to hv2, we don't need it
9033AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
9034 [[enable=false
9035]])
9036
9037
9038# check BFD enablement on tunnel ports from hv2 ##########
9039as hv2
9040for chassis in gw1 gw2; do
9041 echo "checking hv2 -> $chassis"
9042 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9043 [[enable=true
9044]])
9045done
9046# make sure BFD is not enabled to hv1, we don't need it
9047AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
9048 [[enable=false
9049]])
9050
508b7f96 9051sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9052
9053# make sure that flows for handling the outside router port reside on gw2 now
66d89287 9054AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9055]])
66d89287 9056AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9057]])
9058
9059# disconnect GW2 from the network, GW1 should take over
9060as gw2
9061port=${sandbox}_br-phys
9062as main ovs-vsctl del-port n1 $port
9063sleep 4
9064
9065bfd_dump
9066
9067# make sure that flows for handling the outside router port reside on gw2 now
66d89287 9068AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9069]])
66d89287 9070AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9071]])
9072
9073# check that the chassis redirect port has been reclaimed by the gw1 chassis
9074AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9075 [0],[[1
9076]])
9077
1da17a0b 9078OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
9079
9080AT_CLEANUP
acfc41ff
VAK
9081
9082AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
9083AT_SKIP_IF([test $HAVE_PYTHON = no])
9084ovn_start
9085ovn-nbctl ls-add ls0
9086ovn-nbctl ls-add ls1
9087ovn-nbctl create Logical_Router name=lr0
9088ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
9089
9090ovn-nbctl --id=@gc0 create Gateway_Chassis \
9091 name=outside_gw1 chassis_name=hv2 priority=10 -- \
9092 --id=@gc1 create Gateway_Chassis \
9093 name=outside_gw2 chassis_name=hv3 priority=1 -- \
9094 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9095
9096ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9097 type=router options:router-port=lrp0 addresses="router"
9098ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9099ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9100 type=router options:router-port=lrp1 addresses="router"
9101
9102# Add NAT rules
9103AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
9104
9105net_add n1
9106sim_add hv1
9107as hv1
9108ovs-vsctl add-br br-phys
9109ovn_attach n1 br-phys 192.168.0.1
9110AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9111AT_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])
9112
9113sim_add hv2
9114as hv2
9115ovs-vsctl add-br br-phys
9116ovn_attach n1 br-phys 192.168.0.2
9117AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9118
9119sim_add hv3
9120as hv3
9121ovs-vsctl add-br br-phys
9122ovn_attach n1 br-phys 192.168.0.3
9123AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9124
9125# Create a localnet port.
9126AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9127AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9128AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9129AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
9130
9131# wait for earlier changes to take effect
6c8d3d69 9132AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
acfc41ff
VAK
9133
9134reset_pcap_file() {
9135 local iface=$1
9136 local pcap_file=$2
9137 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9138options:rxq_pcap=dummy-rx.pcap
9139 rm -f ${pcap_file}*.pcap
9140 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9141options:rxq_pcap=${pcap_file}-rx.pcap
9142}
9143
9144as hv1 reset_pcap_file snoopvif hv1/snoopvif
9145as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9146as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9147# add nat-addresses option
6c8d3d69 9148ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
acfc41ff
VAK
9149
9150# Wait for packets to be received through hv2.
9151OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9152trim_zeros() {
9153 sed 's/\(00\)\{1,\}$//'
9154}
9155
2db7bb2c 9156only_broadcast_from_lrp1() {
9157 grep "fffffffffffff00000000001"
9158}
9159
acfc41ff 9160garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 9161echo $garp > expout
9162
9163$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
9164echo "packets on hv1-snoopvif:"
9165cat hv1_snoop_tx
9166AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 9167$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
9168echo "packets on hv2 br-phys tx"
9169cat hv2_br_phys_tx
9170AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 9171$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
9172echo "packets on hv3 br-phys tx"
9173cat hv3_br_phys_tx
9174AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9175
9176
9177# at this point, we invert the priority of the gw chassis between hv2 and hv3
9178
9179ovn-nbctl --wait=hv \
9180 --id=@gc0 create Gateway_Chassis \
9181 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9182 --id=@gc1 create Gateway_Chassis \
9183 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9184 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9185
9186
9187as hv1 reset_pcap_file snoopvif hv1/snoopvif
9188as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9189as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9190
9191# Wait for packets to be received.
9192OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9193trim_zeros() {
9194 sed 's/\(00\)\{1,\}$//'
9195}
9196
2db7bb2c 9197$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 9198AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 9199$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 9200AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 9201$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 9202AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
9203
9204# change localnet port tag.
9205AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9206
9207# wait for earlier changes to take effect
6c8d3d69 9208AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
03b85a58
GL
9209
9210# update nat-addresses option
6c8d3d69
HZ
9211ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9212ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
03b85a58
GL
9213
9214as hv1 reset_pcap_file snoopvif hv1/snoopvif
9215as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9216as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9217
9218# Wait for packets to be received.
9219OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9220trim_zeros() {
9221 sed 's/\(00\)\{1,\}$//'
9222}
9223
9224garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9225echo $garp > expout
9226
9227$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9228AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9229$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9230AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9231$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9232AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9233
acfc41ff
VAK
9234OVN_CLEANUP([hv1],[hv2],[hv3])
9235
9236AT_CLEANUP
79371ff5 9237
9238AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9239AT_SKIP_IF([test $HAVE_PYTHON = no])
9240ovn_start
9241
9242net_add n1
9243
9244# create two gateways with external network connectivity
9245for i in 1 2; do
9246 sim_add gw$i
9247 as gw$i
9248 ovs-vsctl add-br br-phys
9249 ovn_attach n1 br-phys 192.168.0.$i
9250 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9251done
9252
9253ovn-nbctl ls-add inside
9254ovn-nbctl ls-add outside
9255
9256# create one hypervisors with a vif port the internal network
9257sim_add hv1
9258as hv1
9259ovs-vsctl add-br br-phys
9260ovn_attach n1 br-phys 192.168.0.11
9261ovs-vsctl -- add-port br-int hv1-vif1 -- \
9262 set interface hv1-vif1 external-ids:iface-id=inside1 \
9263 options:tx_pcap=hv1/vif1-tx.pcap \
9264 options:rxq_pcap=hv1/vif1-rx.pcap \
9265 ofport-request=1
9266
9267ovn-nbctl lsp-add inside inside1 \
9268 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9269
9270
74868f2c 9271OVN_POPULATE_ARP
79371ff5 9272
9273ovn-nbctl create Logical_Router name=R1
9274
9275# Connect inside to R1
9276ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9277ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9278 type=router options:router-port=inside \
9279 -- lsp-set-addresses rp-inside router
9280
9281# Connect outside to R1 as distributed router gateway port on gw1+gw2
9282ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9283
9284ovn-nbctl --id=@gc0 create Gateway_Chassis \
9285 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9286 --id=@gc1 create Gateway_Chassis \
9287 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9288 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9289
9290ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9291 type=router options:router-port=outside \
9292 -- lsp-set-addresses rp-outside router
9293
9294# Create localnet port in outside
9295ovn-nbctl lsp-add outside ln-outside
9296ovn-nbctl lsp-set-addresses ln-outside unknown
9297ovn-nbctl lsp-set-type ln-outside localnet
9298ovn-nbctl lsp-set-options ln-outside network_name=phys
9299
9300# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 9301ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 9302
9303# currently when ovn-controller is restarted, the old entry is deleted
9304# and a new one is created, which leaves the Gateway_Chassis with
9305# an empty chassis for a while. NOTE: restarting ovn-controller in tests
9306# doesn't have the same effect because "name" is conserved, and the
9307# Chassis entry is not replaced.
9308
3a0c5805 9309> gw1/ovn-controller.log
325b2b1a 9310
79371ff5 9311gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9312ovn-sbctl destroy Chassis $gw2_chassis
9313
9314# Ensure ovn-controller has processed latest sbdb update
9315# ovn-nbctl --wait=hv sync
9316
9317AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9318
9319OVN_CLEANUP([gw1],[gw2],[hv1])
9320
9321AT_CLEANUP
63d91afa 9322
b1a3a6a4
NS
9323AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9324AT_KEYWORDS([ovn-nd_ns for unknown mac])
9325AT_SKIP_IF([test $HAVE_PYTHON = no])
9326ovn_start
9327
9328ovn-nbctl ls-add sw0_ip6
9329ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9330ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9331"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9332
9333ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9334"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9335
9336ovn-nbctl lr-add lr0_ip6
847dc1c2 9337ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
9338ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9339ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9340ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
9341ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9342ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9343
9344ovn-nbctl ls-add public
9345ovn-nbctl lsp-add public ln-public
9346ovn-nbctl lsp-set-addresses ln-public unknown
9347ovn-nbctl lsp-set-type ln-public localnet
9348ovn-nbctl lsp-set-options ln-public network_name=phys
9349
9350ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
93512001:db8:1:0:200:02ff:fe01:0204/64 \
9352-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9353
9354
9355ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9356rp-ip6_public type=router options:router-port=ip6_public \
9357-- lsp-set-addresses rp-ip6_public router
9358
9359net_add n1
9360sim_add hv1
9361as hv1
9362ovs-vsctl add-br br-phys
9363ovn_attach n1 br-phys 192.168.0.2
9364
9365ovs-vsctl -- add-port br-int hv1-vif1 -- \
9366 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9367 options:tx_pcap=hv1/vif1-tx.pcap \
9368 options:rxq_pcap=hv1/vif1-rx.pcap \
9369 ofport-request=1
9370ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9371
86c9d79a
NS
9372OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9373cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9374
9375# There is only one chassis.
9376chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9377OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
b1a3a6a4
NS
9378
9379trim_zeros() {
9380 sed 's/\(00\)\{1,\}$//'
9381}
9382
9383# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9384# addresses. ovn-controller should generate an IPv6 NS request for IPv6
9385# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9386# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9387# This function sends ipv6 packet
9388test_ipv6() {
9389 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9390 dst_ip=20010db800010000020002fffe010205
9391
9392 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9393 packet=${packet}8000000000000000
9394 shift; shift; shift; shift
9395
9396 dst_mac=3333ff010205
9397 src_mac=000002010204
9398 mcast_node_ip=ff0200000000000000000001ff010205
9399 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9400 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9401 expected_packet=${expected_packet}0101${src_mac}
9402
9403 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9404 echo $expected_packet >> ipv6_ns.expected
9405}
9406
9407src_mac=506400000002
9408dst_mac=00000000af01
9409src_ip=aef0000000000000526400fffe000002
9410# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9411# should be received by the ports attached to br-phys.
9412test_ipv6 1 $src_mac $dst_mac $src_ip 2
9413
86c9d79a
NS
9414OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9415OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9416
b1a3a6a4
NS
9417$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9418trim_zeros > 1.packets
9419$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9420trim_zeros > 2.packets
9421
9422cat ipv6_ns.expected | cut -c -112 > expout
9423AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9424AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9425
9426# Skipping the ICMPv6 checksum
9427cat ipv6_ns.expected | cut -c 117- > expout
9428AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9429AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9430
9431OVN_CLEANUP([hv1])
9432
9433AT_CLEANUP
9434
63d91afa
LR
9435AT_SETUP([ovn -- options:requested-chassis for logical port])
9436ovn_start
9437
9438net_add n1
9439
9440ovn-nbctl ls-add ls0
9441ovn-nbctl lsp-add ls0 lsp0
9442
9443# create two hypervisors, each with one vif port
9444sim_add hv1
9445as hv1
9446ovs-vsctl add-br br-phys
9447ovn_attach n1 br-phys 192.168.0.11
99cc5c92
NS
9448ovs-vsctl -- add-port br-int hv1-vif0 -- \
9449set Interface hv1-vif0 ofport-request=1
63d91afa
LR
9450
9451sim_add hv2
9452as hv2
9453ovs-vsctl add-br br-phys
9454ovn_attach n1 br-phys 192.168.0.12
99cc5c92
NS
9455ovs-vsctl -- add-port br-int hv2-vif0 -- \
9456set Interface hv2-vif0 ofport-request=1
63d91afa
LR
9457
9458# Allow only chassis hv1 to bind logical port lsp0.
9459ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9460
9461# Allow some time for ovn-northd and ovn-controller to catch up.
9462ovn-nbctl --wait=hv --timeout=3 sync
9463
9464# Retrieve hv1 and hv2 chassis UUIDs from southbound database
2aa57f08
HZ
9465ovn-sbctl wait-until chassis hv1
9466ovn-sbctl wait-until chassis hv2
63d91afa
LR
9467hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9468hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9469
9470# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9471echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9472as hv2
9473ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9474
9475OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9476AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9477
99cc5c92
NS
9478# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9479AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9480AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9481
9482# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
63d91afa
LR
9483echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9484as hv1
9485ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9486
9487OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
2aa57f08 9488AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
63d91afa 9489
99cc5c92
NS
9490# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9491as hv1 ovs-ofctl dump-flows br-int
9492AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9493AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9494
9495# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
63d91afa
LR
9496# the requested chassis for lsp0 is changed from hv1 to hv2.
9497echo "verifying that lsp0 binding moves when requested-chassis is changed"
9498
9499ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9500OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
2aa57f08 9501OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
63d91afa 9502
99cc5c92
NS
9503# (6) Chassis hv2 should add flows and hv1 should not.
9504AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9505AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9506
9507AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9508AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9509
63d91afa
LR
9510OVN_CLEANUP([hv1],[hv2])
9511
9512AT_CLEANUP
bd32425f
RB
9513
9514AT_SETUP([ovn -- options:requested-chassis with hostname])
9515
9516ovn_start
9517
9518ovn-nbctl ls-add ls0
9519ovn-nbctl lsp-add ls0 lsp0
9520
9521net_add n1
9522sim_add hv1
9523as hv1
9524ovs-vsctl add-br br-phys
9525ovn_attach n1 br-phys 192.168.0.11
99cc5c92 9526ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
bd32425f 9527
362ab40a 9528ovn-sbctl wait-until chassis hv1
bd32425f
RB
9529hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9530echo "hv1_hostname=${hv1_hostname}"
9531ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9532as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9533
9534hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9535echo "hv1_uuid=${hv1_uuid}"
9536OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9537AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
99cc5c92
NS
9538AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9539AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
bd32425f
RB
9540
9541ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9542OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9543ovn-nbctl --wait=hv --timeout=3 sync
9544AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
99cc5c92
NS
9545AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9546AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
bd32425f
RB
9547
9548OVN_CLEANUP([hv1])
9549
9550AT_CLEANUP
4446661a
MM
9551
9552AT_SETUP([ovn -- IPv6 periodic RA])
9553ovn_start
9554
9555# This test sets up two hypervisors.
9556# hv1 and hv2 run ovn-controllers, and
9557# each has a VIF connected to the same
9558# logical switch in OVN. The logical
9559# switch is connected to a logical
9560# router port that is configured to send
9561# periodic router advertisements.
9562#
9563# The reason for having two ovn-controller
9564# hypervisors is to ensure that the
9565# periodic RAs being sent by each ovn-controller
9566# are kept to their local hypervisors. If the
9567# packets are not kept local, then each port
9568# will receive too many RAs.
9569
9570net_add n1
9571sim_add hv1
9572sim_add hv2
9573as hv1
9574ovs-vsctl add-br br-phys
9575ovn_attach n1 br-phys 192.168.0.2
9576as hv2
9577ovs-vsctl add-br br-phys
9578ovn_attach n1 br-phys 192.168.0.3
9579
9580ovn-nbctl lr-add ro
1ea1b0d0 9581ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
4446661a
MM
9582
9583ovn-nbctl ls-add sw
9584ovn-nbctl lsp-add sw sw-ro
9585ovn-nbctl lsp-set-type sw-ro router
9586ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9587ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9588ovn-nbctl lsp-add sw sw-p1
9589ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9590ovn-nbctl lsp-add sw sw-p2
9591ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9592
9593ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9594ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9595ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9596ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9597
86c9d79a
NS
9598for i in 1 2 ; do
9599 as hv$i
9600 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9601 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9602 options:tx_pcap=hv$i/vif1-tx.pcap \
9603 options:rxq_pcap=hv$i/vif1-rx.pcap \
4446661a
MM
9604 ofport-request=1
9605done
9606
86c9d79a
NS
9607OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9608OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
4446661a
MM
9609
9610reset_pcap_file() {
9611 local iface=$1
9612 local pcap_file=$2
9613 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9614options:rxq_pcap=dummy-rx.pcap
9615 rm -f ${pcap_file}*.pcap
9616 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9617options:rxq_pcap=${pcap_file}-rx.pcap
9618
9619}
9620
9621construct_expected_ra() {
9622 local src_mac=000000000001
9623 local dst_mac=333300000001
9624 local src_addr=fe80000000000000020000fffe000001
9625 local dst_addr=ff020000000000000000000000000001
9626
9627 local mtu=$1
9628 local ra_mo=$2
9629 local ra_prefix_la=$3
9630
9631 local slla=0101${src_mac}
9632 local mtu_opt=""
9633 if test $mtu != 0; then
9634 mtu_opt=05010000${mtu}
9635 fi
9636 shift 3
9637
9638 local prefix=""
9639 while [[ $# -gt 0 ]] ; do
9640 local size=$1
9641 local net=$2
9642 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9643 shift 2
9644 done
9645
895ceaf7 9646 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
4446661a
MM
9647 local icmp=8600XXXX${ra}
9648
9649 local ip_len=$(expr ${#icmp} / 2)
1ea1b0d0 9650 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
4446661a
MM
9651
9652 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9653 local eth=${dst_mac}${src_mac}86dd${ip}
9654 local packet=${eth}
9655 echo $packet >> expected
9656}
9657
9658ra_test() {
9659 construct_expected_ra $@
9660
9661 for i in hv1 hv2 ; do
9662 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9663
9664 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9665
9666 cat expected | cut -c -112 > expout
9667 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9668
9669 # Skip ICMPv6 checksum.
9670 cat expected | cut -c 117- > expout
9671 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9672
9673 rm -f packets
9674 as $i reset_pcap_file $i-vif1 $i/vif1
9675 done
9676
9677 rm -f expected
9678}
9679
9680# Baseline test with no MTU
9681ra_test 0 00 c0 40 aef00000000000000000000000000000
9682
9683# Now make sure an MTU option makes it
9684ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9685ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9686
9687# Now test for multiple network prefixes
9688ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9689ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9690
9691# Test a different address mode now
9692ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9693ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9694
9695# And the other address mode
9696ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9697ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9698
9699OVN_CLEANUP([hv1],[hv2])
9700AT_CLEANUP
4826add0
LB
9701
9702AT_SETUP([ovn -- ACL reject rule test])
9703AT_KEYWORDS([acl-reject])
9704AT_SKIP_IF([test $HAVE_PYTHON = no])
9705ovn_start
9706
9707# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9708#
9709# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9710# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9711# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9712# unreachable frame generated from ACL rule hit
9713#
9714# INPORT is a lport number, e.g. 11 for vif11.
9715# HV is a hypervisor number
9716# ETH_SRC and ETH_DST are each 12 hex digits.
9717# IPV4_SRC and IPV4_DST are each 8 hex digits.
9718# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9719test_ip_packet() {
9720 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9721 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9722 shift 9
9723
9724 local ip_ttl=ff
9725 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9726
9727 local reply_icmp_ttl=ff
9728 local icmp_type_code_response=0301
9729 local icmp_data=00000000
9730 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9731 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9732 echo $reply >> vif$inport.expected
9733
9734 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9735}
9736
c319fabc
LB
9737# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
9738#
9739# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
9740# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
9741# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
9742test_ipv6_packet() {
9743 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
9744 shift 7
9745
9746 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9747 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
9748
9749 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
9750 echo $reply >> vif$inport.expected
9751
9752 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9753}
9754
c20ab6aa
LB
9755# 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
9756#
9757# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
9758# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
9759# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
9760#
9761# INPORT is an lport number, e.g. 11 for vif11.
9762# HV is an hypervisor number
9763# ETH_SRC and ETH_DST are each 12 hex digits.
9764# IPV4_SRC and IPV4_DST are each 8 hex digits.
9765# TCP_SPORT and TCP_DPORT are 4 hex digits.
9766# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
9767test_tcp_syn_packet() {
9768 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9769 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
9770 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
9771 shift 12
9772
9773 local ip_ttl=ff
9774 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
9775
9776 local tcp_rst_ttl=ff
9777 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
9778 echo $reply >> vif$inport.expected
9779
9780 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9781}
9782
4826add0
LB
9783# Create hypervisors hv[123].
9784# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
9785# Add all of the vifs to a single logical switch sw0.
9786
9787net_add n1
9788ovn-nbctl ls-add sw0
9789for i in 1 2 3; do
9790 sim_add hv$i
9791 as hv$i
9792 ovs-vsctl add-br br-phys
9793 ovn_attach n1 br-phys 192.168.0.$i
9794
9795 for j in 1 2 3; do
9796 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
9797 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
9798
9799 ovs-vsctl -- add-port br-int vif$i$j -- \
9800 set interface vif$i$j \
9801 external-ids:iface-id=sw0-p$i$j \
9802 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
9803 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
9804 ofport-request=$i$j
9805 done
9806done
9807
9808OVN_POPULATE_ARP
9809# allow some time for ovn-northd and ovn-controller to catch up.
9810sleep 1
9811
9812ip_to_hex() {
9813 printf "%02x%02x%02x%02x" "$@"
9814}
9815
9816for i in 1 2 3; do
9817 : > vif${i}1.expected
9818done
9819
9820ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
9821ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
9822ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
732965bc
HZ
9823
9824# Allow some time for ovn-northd and ovn-controller to catch up.
9825ovn-nbctl --timeout=3 --wait=hv sync
4826add0
LB
9826
9827test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
9828test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
9829test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
9830
c319fabc
LB
9831test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
9832
c20ab6aa
LB
9833test_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
9834test_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
9835test_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
9836
4826add0
LB
9837for i in 1 2 3; do
9838 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
9839done
9840
9841OVN_CLEANUP([hv1], [hv2], [hv3])
9842AT_CLEANUP
689829d5
HZ
9843
9844AT_SETUP([ovn -- Port Groups])
9845AT_KEYWORDS([ovnpg])
9846AT_SKIP_IF([test $HAVE_PYTHON = no])
9847ovn_start
9848
9849# Logical network:
9850#
9851# Three logical switches ls1, ls2, ls3.
9852# One logical router lr0 connected to ls[123],
9853# with nine subnets, three per logical switch:
9854#
9855# lrp11 on ls1 for subnet 192.168.11.0/24
9856# lrp12 on ls1 for subnet 192.168.12.0/24
9857# lrp13 on ls1 for subnet 192.168.13.0/24
9858# ...
9859# lrp33 on ls3 for subnet 192.168.33.0/24
9860#
9861# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9862# digits are the subnet and the last digit distinguishes the VIF.
9863#
9864# This test will create two port groups and uses them in ACL.
9865
9866get_lsp_uuid () {
9867 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9868}
9869
9870pg1_ports=
9871pg2_ports=
9872for i in 1 2 3; do
9873 ovn-nbctl ls-add ls$i
9874 for j in 1 2 3; do
9875 for k in 1 2 3; do
9876 ovn-nbctl \
9877 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
9878 -- lsp-set-addresses lp$i$j$k \
9879 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
689829d5
HZ
9880 # logical ports lp[12]?1 belongs to port group pg1
9881 if test $i != 3 && test $k == 1; then
9882 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9883 fi
9884 # logical ports lp[23]?2 belongs to port group pg2
9885 if test $i != 1 && test $k == 2; then
9886 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9887 fi
9888 done
9889 done
9890done
9891
9892ovn-nbctl lr-add lr0
9893for i in 1 2 3; do
9894 for j in 1 2 3; do
9895 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9896 ovn-nbctl \
9897 -- lsp-add ls$i lrp$i$j-attachment \
9898 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9899 options:router-port=lrp$i$j \
9900 addresses='"00:00:00:00:ff:'$i$j'"'
9901 done
9902done
9903
9904ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9905ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9906
9907# create ACLs on all lswitches to drop traffic from pg2 to pg1
9908ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9909ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9910ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9911
9912# Physical network:
9913#
9914# Three hypervisors hv[123].
9915# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9916# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9917# lp?3[123] all on hv3.
9918
9919# Given the name of a logical port, prints the name of the hypervisor
9920# on which it is located.
9921vif_to_hv() {
9922 case $1 in dnl (
9923 ?11) echo 1 ;; dnl (
9924 ?12 | ?21 | ?22) echo 2 ;; dnl (
9925 ?13 | ?23 | ?3?) echo 3 ;;
9926 esac
9927}
9928
9929# Given the name of a logical port, prints the name of its logical router
9930# port, e.g. "vif_to_lrp 123" yields 12.
9931vif_to_lrp() {
9932 echo ${1%?}
9933}
9934
9935# Given the name of a logical port, prints the name of its logical
9936# switch, e.g. "vif_to_ls 123" yields 1.
9937vif_to_ls() {
9938 echo ${1%??}
9939}
9940
9941net_add n1
9942for i in 1 2 3; do
9943 sim_add hv$i
9944 as hv$i
9945 ovs-vsctl add-br br-phys
9946 ovn_attach n1 br-phys 192.168.0.$i
9947done
9948for i in 1 2 3; do
9949 for j in 1 2 3; do
9950 for k in 1 2 3; do
9951 hv=`vif_to_hv $i$j$k`
9952 as hv$hv ovs-vsctl \
9953 -- add-port br-int vif$i$j$k \
9954 -- set Interface vif$i$j$k \
9955 external-ids:iface-id=lp$i$j$k \
9956 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
9957 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
9958 ofport-request=$i$j$k
9959 done
9960 done
9961done
9962
9963# Pre-populate the hypervisors' ARP tables so that we don't lose any
9964# packets for ARP resolution (native tunneling doesn't queue packets
9965# for ARP resolution).
9966OVN_POPULATE_ARP
9967
9968# Allow some time for ovn-northd and ovn-controller to catch up.
9969# XXX This should be more systematic.
9970sleep 1
9971
9972# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9973#
9974# This shell function causes a packet to be received on INPORT. The packet's
9975# content has Ethernet destination DST and source SRC (each exactly 12 hex
9976# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
9977# more) list the VIFs on which the packet should be received. INPORT and the
9978# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9979for i in 1 2 3; do
9980 for j in 1 2 3; do
9981 for k in 1 2 3; do
9982 : > $i$j$k.expected
9983 done
9984 done
9985done
9986test_ip() {
9987 # This packet has bad checksums but logical L3 routing doesn't check.
9988 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
9989 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9990 shift; shift; shift; shift; shift
9991 hv=hv`vif_to_hv $inport`
9992 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
9993 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
9994 in_ls=`vif_to_ls $inport`
9995 in_lrp=`vif_to_lrp $inport`
9996 for outport; do
9997 out_ls=`vif_to_ls $outport`
9998 if test $in_ls = $out_ls; then
9999 # Ports on the same logical switch receive exactly the same packet.
10000 echo $packet
10001 else
10002 # Routing decrements TTL and updates source and dest MAC
10003 # (and checksum).
10004 out_lrp=`vif_to_lrp $outport`
10005 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10006 fi >> $outport.expected
10007 done
10008}
10009
10010as hv1 ovs-vsctl --columns=name,ofport list interface
10011as hv1 ovn-sbctl list port_binding
10012as hv1 ovn-sbctl list datapath_binding
10013as hv1 ovn-sbctl list port_group
10014as hv1 ovn-sbctl list address_set
10015as hv1 ovn-sbctl dump-flows
10016as hv1 ovs-ofctl dump-flows br-int
10017
10018# Send IP packets between all pairs of source and destination ports,
10019# packets matches ACL (pg2 to pg1) should be dropped
10020ip_to_hex() {
10021 printf "%02x%02x%02x%02x" "$@"
10022}
10023for is in 1 2 3; do
10024 for js in 1 2 3; do
10025 for ks in 1 2 3; do
10026 bcast=
10027 s=$is$js$ks
10028 smac=f00000000$s
10029 sip=`ip_to_hex 192 168 $is$js $ks`
10030 for id in 1 2 3; do
10031 for jd in 1 2 3; do
10032 for kd in 1 2 3; do
10033 d=$id$jd$kd
10034 dip=`ip_to_hex 192 168 $id$jd $kd`
10035 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10036 if test $d != $s; then unicast=$d; else unicast=; fi
10037
10038 # packets matches ACL should be dropped
10039 if test $id != 3 && test $kd == 1; then
10040 if test $is != 1 && test $ks == 2; then
10041 unicast=
10042 fi
10043 fi
10044 test_ip $s $smac $dmac $sip $dip $unicast #1
10045 done
10046 done
10047 done
10048 done
10049 done
10050done
10051
10052# Allow some time for packet forwarding.
10053# XXX This can be improved.
10054sleep 1
10055
10056# Now check the packets actually received against the ones expected.
10057for i in 1 2 3; do
10058 for j in 1 2 3; do
10059 for k in 1 2 3; do
10060 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10061 [$i$j$k.expected])
10062 done
10063 done
10064done
10065
10066# Gracefully terminate daemons
10067OVN_CLEANUP([hv1], [hv2], [hv3])
10068AT_CLEANUP
1beb60af
HZ
10069
10070AT_SETUP([ovn -- ACLs on Port Groups])
10071AT_KEYWORDS([ovnpg_acl])
10072AT_SKIP_IF([test $HAVE_PYTHON = no])
10073ovn_start
10074
10075# Logical network:
10076#
10077# Three logical switches ls1, ls2, ls3.
10078# One logical router lr0 connected to ls[123],
10079# with nine subnets, three per logical switch:
10080#
10081# lrp11 on ls1 for subnet 192.168.11.0/24
10082# lrp12 on ls1 for subnet 192.168.12.0/24
10083# lrp13 on ls1 for subnet 192.168.13.0/24
10084# ...
10085# lrp33 on ls3 for subnet 192.168.33.0/24
10086#
10087# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10088# digits are the subnet and the last digit distinguishes the VIF.
10089#
10090# This test will create two port groups and ACLs will be applied on them.
10091
10092get_lsp_uuid () {
10093 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10094}
10095
10096pg1_ports=
10097pg2_ports=
10098for i in 1 2 3; do
10099 ovn-nbctl ls-add ls$i
10100 for j in 1 2 3; do
10101 for k in 1 2 3; do
10102 ovn-nbctl \
10103 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
10104 -- lsp-set-addresses lp$i$j$k \
10105 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
1beb60af
HZ
10106 # logical ports lp[12]?1 belongs to port group pg1
10107 if test $i != 3 && test $k == 1; then
10108 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10109 fi
10110 # logical ports lp[23]?2 belongs to port group pg2
10111 if test $i != 1 && test $k == 2; then
10112 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10113 fi
10114 done
10115 done
10116done
10117
10118ovn-nbctl lr-add lr0
10119for i in 1 2 3; do
10120 for j in 1 2 3; do
10121 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10122 ovn-nbctl \
10123 -- lsp-add ls$i lrp$i$j-attachment \
10124 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10125 options:router-port=lrp$i$j \
10126 addresses='"00:00:00:00:ff:'$i$j'"'
10127 done
10128done
10129
d87e0897 10130ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
1beb60af
HZ
10131ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10132
10133# create ACLs on pg1 to drop traffic from pg2 to pg1
d87e0897
HZ
10134ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
10135ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
cdc9a84a 10136 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
1beb60af
HZ
10137
10138# Physical network:
10139#
10140# Three hypervisors hv[123].
10141# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10142# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10143# lp?3[123] all on hv3.
10144
10145# Given the name of a logical port, prints the name of the hypervisor
10146# on which it is located.
10147vif_to_hv() {
10148 case $1 in dnl (
10149 ?11) echo 1 ;; dnl (
10150 ?12 | ?21 | ?22) echo 2 ;; dnl (
10151 ?13 | ?23 | ?3?) echo 3 ;;
10152 esac
10153}
10154
10155# Given the name of a logical port, prints the name of its logical router
10156# port, e.g. "vif_to_lrp 123" yields 12.
10157vif_to_lrp() {
10158 echo ${1%?}
10159}
10160
10161# Given the name of a logical port, prints the name of its logical
10162# switch, e.g. "vif_to_ls 123" yields 1.
10163vif_to_ls() {
10164 echo ${1%??}
10165}
10166
10167net_add n1
10168for i in 1 2 3; do
10169 sim_add hv$i
10170 as hv$i
10171 ovs-vsctl add-br br-phys
10172 ovn_attach n1 br-phys 192.168.0.$i
10173done
10174for i in 1 2 3; do
10175 for j in 1 2 3; do
10176 for k in 1 2 3; do
10177 hv=`vif_to_hv $i$j$k`
10178 as hv$hv ovs-vsctl \
10179 -- add-port br-int vif$i$j$k \
10180 -- set Interface vif$i$j$k \
10181 external-ids:iface-id=lp$i$j$k \
10182 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10183 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10184 ofport-request=$i$j$k
10185 done
10186 done
10187done
10188
10189# Pre-populate the hypervisors' ARP tables so that we don't lose any
10190# packets for ARP resolution (native tunneling doesn't queue packets
10191# for ARP resolution).
10192OVN_POPULATE_ARP
10193
10194# Allow some time for ovn-northd and ovn-controller to catch up.
10195# XXX This should be more systematic.
10196sleep 1
10197
cdc9a84a
HZ
10198lsp_to_mac() {
10199 echo f0:00:00:00:0${1:0:1}:${1:1:2}
10200}
10201
10202lrp_to_mac() {
10203 echo 00:00:00:00:ff:$1
10204}
10205
10206# test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
1beb60af 10207#
cdc9a84a
HZ
10208# This shell function causes a ICMP packet to be received on INPORT.
10209# The OUTPORTs (zero or more) list the VIFs on which the packet should
10210# be received. INPORT and the OUTPORTs are specified as logical switch
10211# port numbers, e.g. 123 for vif123.
1beb60af
HZ
10212for i in 1 2 3; do
10213 for j in 1 2 3; do
10214 for k in 1 2 3; do
10215 : > $i$j$k.expected
10216 done
10217 done
10218done
cdc9a84a
HZ
10219
10220test_icmp() {
10221 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
10222 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
10223 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
10224 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
10225 icmp4.code==0"
10226 shift; shift; shift; shift; shift; shift
1beb60af 10227 hv=hv`vif_to_hv $inport`
cdc9a84a 10228 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
1beb60af
HZ
10229 in_ls=`vif_to_ls $inport`
10230 in_lrp=`vif_to_lrp $inport`
10231 for outport; do
10232 out_ls=`vif_to_ls $outport`
10233 if test $in_ls = $out_ls; then
10234 # Ports on the same logical switch receive exactly the same packet.
cdc9a84a 10235 echo $packet | ovstest test-ovn expr-to-packets
1beb60af
HZ
10236 else
10237 # Routing decrements TTL and updates source and dest MAC
10238 # (and checksum).
10239 out_lrp=`vif_to_lrp $outport`
cdc9a84a
HZ
10240 exp_smac=`lrp_to_mac $out_lrp`
10241 exp_dmac=`lsp_to_mac $outport`
10242 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
10243 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
10244 icmp4.type==$icmp_type && icmp4.code==0"
10245 echo $exp_packet | ovstest test-ovn expr-to-packets
10246
1beb60af
HZ
10247 fi >> $outport.expected
10248 done
10249}
10250
10251as hv1 ovs-vsctl --columns=name,ofport list interface
10252as hv1 ovn-sbctl list port_binding
10253as hv1 ovn-sbctl list datapath_binding
10254as hv1 ovn-sbctl list port_group
10255as hv1 ovn-sbctl list address_set
10256as hv1 ovn-sbctl dump-flows
10257as hv1 ovs-ofctl dump-flows br-int
10258
10259# Send IP packets between all pairs of source and destination ports,
10260# packets matches ACL1 but not ACL2 should be dropped
10261ip_to_hex() {
10262 printf "%02x%02x%02x%02x" "$@"
10263}
10264for is in 1 2 3; do
10265 for js in 1 2 3; do
10266 for ks in 1 2 3; do
10267 bcast=
10268 s=$is$js$ks
cdc9a84a
HZ
10269 slsp_mac=`lsp_to_mac $s`
10270 slrp_mac=`lrp_to_mac $is$js`
10271 sip=192.168.$is$js.$ks
1beb60af
HZ
10272 for id in 1 2 3; do
10273 for jd in 1 2 3; do
10274 for kd in 1 2 3; do
10275 d=$id$jd$kd
cdc9a84a
HZ
10276 dlsp_mac=`lsp_to_mac $d`
10277 dlrp_mac=`lrp_to_mac $id$jd`
10278 dip=192.168.$id$jd.$kd
10279 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
1beb60af
HZ
10280 if test $d != $s; then unicast=$d; else unicast=; fi
10281
10282 # packets matches ACL1 but not ACL2 should be dropped
10283 if test $id != 3 && test $kd == 1; then
10284 if test $is == 1 || test $ks != 2; then
10285 unicast=
10286 fi
10287 fi
cdc9a84a
HZ
10288 # icmp request (type = 8)
10289 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
10290
10291 # if packets are not dropped, test the return traffic (icmp echo)
10292 # to make sure stateful works, too.
10293 if test x$unicast != x; then
10294 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
10295 # icmp echo (type = 0)
10296 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
10297 fi
1beb60af
HZ
10298 done
10299 done
10300 done
10301 done
10302 done
10303done
10304
10305# Allow some time for packet forwarding.
10306# XXX This can be improved.
10307sleep 1
10308
10309# Now check the packets actually received against the ones expected.
10310for i in 1 2 3; do
10311 for j in 1 2 3; do
10312 for k in 1 2 3; do
10313 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10314 [$i$j$k.expected])
10315 done
10316 done
10317done
10318
10319# Gracefully terminate daemons
10320OVN_CLEANUP([hv1], [hv2], [hv3])
10321AT_CLEANUP
55b25947 10322
2342c266
JS
10323AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
10324ovn_start
10325
10326ovn-nbctl ls-add ls1
10327
10328ovn-nbctl lsp-add ls1 lp1
10329ovn-nbctl lsp-add ls1 lp2
10330ovn-nbctl lsp-add ls1 lp3
10331
10332ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
10333ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
10334ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
10335
10336ovn-nbctl create Port_Group name=pg1
10337ovn-nbctl create Port_Group name=pg2
10338
10339ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
10340ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
10341ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
10342ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
10343
10344ovn-nbctl --wait=sb sync
10345
10346dnl Check if port group address sets were populated with ports' addresses
10347AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10348 [0], [[["10.0.0.1", "10.0.0.2"]]
10349])
10350AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
10351 [0], [[["10.0.0.2", "10.0.0.3"]]
10352])
10353AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10354 [0], [[["2001:db8::1", "2001:db8::2"]]
10355])
10356AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
10357 [0], [[["2001:db8::2", "2001:db8::3"]]
10358])
10359
10360ovn-nbctl --wait=sb lsp-set-addresses lp1 \
10361 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
10362
10363dnl Check if updated address got propagated to the port group address sets
10364AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10365 [0], [[["10.0.0.11", "10.0.0.2"]]
10366])
10367AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10368 [0], [[["2001:db8::11", "2001:db8::2"]]
10369])
10370
10371AT_CLEANUP
10372
984c7d5e
JS
10373AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
10374ovn_start
10375
10376ovn-nbctl ls-add ls1
10377ovn-nbctl ls-add ls2
10378ovn-nbctl ls-add ls3
10379
10380ovn-nbctl set Logical_Switch ls1 \
10381 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
10382ovn-nbctl set Logical_Switch ls2 \
10383 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
10384ovn-nbctl set Logical_Switch ls3 \
10385 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
10386
10387ovn-nbctl lsp-add ls1 lp1
10388ovn-nbctl lsp-add ls2 lp2
10389ovn-nbctl lsp-add ls3 lp3
10390
10391ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
10392ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
10393ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
10394
10395ovn-nbctl create Port_Group name=pg1
10396ovn-nbctl create Port_Group name=pg2
10397
10398ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
10399ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
10400ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
10401ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
10402
10403ovn-nbctl --wait=sb sync
10404
10405dnl Check if port group address sets were populated with ports' addresses
10406AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10407 [0], [[["10.1.0.2", "10.2.0.2"]]
10408])
10409AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
10410 [0], [[["10.2.0.2", "10.3.0.2"]]
10411])
10412AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10413 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
10414])
10415AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
10416 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
10417])
10418
10419ovn-nbctl set Logical_Switch ls1 \
10420 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
10421
10422dnl Check if updated address got propagated to the port group address sets
10423AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
451624fe 10424 [0], [[["10.11.0.2", "10.2.0.2"]]
984c7d5e
JS
10425])
10426AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
451624fe 10427 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
984c7d5e
JS
10428])
10429
10430AT_CLEANUP
10431
55b25947
NS
10432AT_SETUP([ovn -- ACL conjunction])
10433ovn_start
10434
10435ovn-nbctl ls-add ls1
10436
10437ovn-nbctl lsp-add ls1 ls1-lp1 \
10438-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10439
10440ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10441
10442ovn-nbctl lsp-add ls1 ls1-lp2 \
10443-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10444
10445ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10446
10447net_add n1
10448sim_add hv1
10449
10450as hv1
10451ovs-vsctl add-br br-phys
10452ovn_attach n1 br-phys 192.168.0.1
10453ovs-vsctl -- add-port br-int hv1-vif1 -- \
10454 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
10455 options:tx_pcap=hv1/vif1-tx.pcap \
10456 options:rxq_pcap=hv1/vif1-rx.pcap \
10457 ofport-request=1
10458
10459ovs-vsctl -- add-port br-int hv1-vif2 -- \
10460 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
10461 options:tx_pcap=hv1/vif2-tx.pcap \
10462 options:rxq_pcap=hv1/vif2-rx.pcap \
10463 ofport-request=2
10464
10465ovn-nbctl create Address_Set name=set1 \
10466addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
10467ovn-nbctl create Address_Set name=set2 \
10468addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
10469ovn-nbctl acl-add ls1 to-lport 1002 \
10470'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
10471ovn-nbctl acl-add ls1 to-lport 1001 \
10472'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
10473
10474# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10475#
10476# This shell function causes an ip packet to be received on INPORT.
10477# The packet's content has Ethernet destination DST and source SRC
10478# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
10479# The OUTPORTs (zero or more) list the VIFs on which the packet should
10480# be received. INPORT and the OUTPORTs are specified as logical switch
10481# port numbers, e.g. 11 for vif11.
10482test_ip() {
10483 # This packet has bad checksums but logical L3 routing doesn't check.
10484 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10485 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
10486${dst_ip}0035111100080000
10487 shift; shift; shift; shift; shift
10488 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
10489 for outport; do
10490 echo $packet >> $outport.expected
10491 done
10492}
10493
10494ip_to_hex() {
10495 printf "%02x%02x%02x%02x" "$@"
10496}
10497
10498reset_pcap_file() {
10499 local iface=$1
10500 local pcap_file=$2
10501 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10502options:rxq_pcap=dummy-rx.pcap
10503 rm -f ${pcap_file}*.pcap
10504 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10505options:rxq_pcap=${pcap_file}-rx.pcap
10506}
10507
10508
10509sip=`ip_to_hex 10 0 0 4`
10510dip=`ip_to_hex 10 0 0 6`
10511
10512test_ip 1 f00000000001 f00000000002 $sip $dip 2
10513
10514cat 2.expected > expout
10515$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10516AT_CHECK([cat 2.packets], [0], [expout])
10517
10518# There should be total of 12 flows present with conjunction action and 2 flows
10519# with conj match. Eg.
10520# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
10521# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
10522# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
10523# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
10524# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
10525# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
10526# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
10527# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
10528# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
10529# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
10530# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
10531# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
10532# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
10533# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
10534
10535OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
10536grep conjunction | wc -l`])
10537OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
10538grep conj_id | wc -l`])
10539
10540as hv1 ovs-ofctl dump-flows br-int
10541
10542# Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
10543ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10544ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10545
10546reset_pcap_file hv1-vif2 hv1/vif2
10547
10548rm -f 2.packets
10549
10550sip=`ip_to_hex 10 0 0 4`
10551dip=`ip_to_hex 10 0 0 7`
10552
10553test_ip 1 f00000000001 f00000000002 $sip $dip
10554$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10555AT_CHECK([cat 2.packets], [0], [])
10556
10557AT_CLEANUP
0e2751ed
LB
10558
10559AT_SETUP([ovn -- TTL exceeded])
10560AT_KEYWORDS([ttl-exceeded])
10561AT_SKIP_IF([test $HAVE_PYTHON = no])
10562ovn_start
10563
10564# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
10565#
10566# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10567# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
10568# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
10569# generated by OVN logical router
10570#
10571# INPORT is a lport number, e.g. 11 for vif11.
10572# HV is a hypervisor number
10573# ETH_SRC and ETH_DST are each 12 hex digits.
10574# IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
10575# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10576test_ip_packet() {
10577 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
10578 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
10579 shift 10
10580
10581 local ip_ttl=01
10582 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
10583
10584 local reply_icmp_ttl=fe
10585 local icmp_type_code_response=0b00
10586 local icmp_data=00000000
10587 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
10588 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10589 echo $reply >> vif$inport.expected
10590
10591 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10592}
10593
e6a84e1e
LB
10594# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
10595#
10596# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
10597# packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
10598# IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
10599# packet sent by OVN logical router
10600test_ip6_packet() {
10601 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
10602 shift 8
10603
10604 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
10605 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
10606
10607 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
10608 echo $reply >> vif$inport.expected
10609
10610 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10611}
10612
0e2751ed
LB
10613ip_to_hex() {
10614 printf "%02x%02x%02x%02x" "$@"
10615}
10616
10617for i in 1 2; do
10618 net_add n$i
10619 ovn-nbctl ls-add sw$i
10620
10621 sim_add hv$i
10622 as hv$i
10623 ovs-vsctl add-br br-phys
10624 ovn_attach n$i br-phys 192.168.$i.1
10625
10626 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
e6a84e1e 10627 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
0e2751ed
LB
10628
10629 ovs-vsctl -- add-port br-int vif$i -- \
10630 set interface vif$i \
10631 external-ids:iface-id=sw$i-p${i}0 \
10632 options:tx_pcap=hv$i/vif$i-tx.pcap \
10633 options:rxq_pcap=hv$i/vif$i-rx.pcap \
10634 ofport-request=$i
10635done
10636
10637ovn-nbctl lr-add lr0
10638for i in 1 2; do
e6a84e1e 10639 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
0e2751ed
LB
10640 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
10641 -- set Logical_Switch_Port lrp$i-attachment type=router \
e6a84e1e 10642 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
0e2751ed
LB
10643done
10644
10645OVN_POPULATE_ARP
10646# allow some time for ovn-northd and ovn-controller to catch up.
10647ovn-nbctl --wait=hv sync
10648
10649test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 1 254) 0000 7dae f4ff
e6a84e1e 10650test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
0e2751ed
LB
10651OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
10652
10653OVN_CLEANUP([hv1], [hv2])
10654AT_CLEANUP
86558ac2
LB
10655
10656AT_SETUP([ovn -- router port unreachable])
10657AT_KEYWORDS([router-port-unreachable])
10658AT_SKIP_IF([test $HAVE_PYTHON = no])
10659ovn_start
10660
10661# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER L4_PROTCOL IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM EXP_ICMP_CODE
10662#
10663# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10664# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
10665# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
10666# EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
10667#
10668# INPORT is a lport number, e.g. 11 for vif11.
10669# HV is a hypervisor number
10670# ETH_SRC and ETH_DST are each 12 hex digits.
10671# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10672# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10673test_ip_packet() {
10674 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
10675 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
10676 shift 11
10677
10678 local ip_ttl=ff
10679 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
10680
10681 local reply_icmp_ttl=fe
10682 local icmp_data=00000000
10683 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
10684 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10685 echo $reply >> vif$inport.expected
10686
10687 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10688}
10689
159932c9
LB
10690# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
10691#
10692# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10693# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10694# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
10695#
10696# INPORT is an lport number, e.g. 11 for vif11.
10697# HV is an hypervisor number
10698# ETH_SRC and ETH_DST are each 12 hex digits.
10699# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10700# TCP_SPORT and TCP_DPORT are 4 hex digits.
10701# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10702test_tcp_syn_packet() {
10703 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
10704 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10705 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10706 shift 12
10707
10708 local ip_ttl=ff
10709 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10710
10711 local tcp_rst_ttl=fe
10712 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ip_router}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10713 echo $reply >> vif$inport.expected
10714
10715 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10716}
10717
98af55fc
LB
10718# test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
10719#
10720# Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
10721# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
10722# EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
10723test_tcp6_packet() {
10724 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
10725 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
10726 local exp_tcp_rst_chksum=${10}
10727 shift 10
10728
10729 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
10730 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10731
10732 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10733 echo $reply >> vif$inport.expected
10734
10735 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10736}
10737
4c25c3b8
LB
10738# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
10739#
10740# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
10741# packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
10742# EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
10743test_ip6_packet() {
10744 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_proto=$7 ipv6_len=$8 data=$9
10745 local exp_icmp_code=${10} exp_icmp_chksum=${11}
10746 shift 11
10747
10748 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
10749 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
10750
10751 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
10752 echo $reply >> vif$inport.expected
10753
10754 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10755}
10756
86558ac2
LB
10757ip_to_hex() {
10758 printf "%02x%02x%02x%02x" "$@"
10759}
10760
10761for i in 1 2; do
10762 net_add n$i
10763 ovn-nbctl ls-add sw$i
10764
10765 sim_add hv$i
10766 as hv$i
10767 ovs-vsctl add-br br-phys
10768 ovn_attach n$i br-phys 192.168.$i.1
10769
10770 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
4c25c3b8 10771 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
86558ac2
LB
10772
10773 ovs-vsctl -- add-port br-int vif$i -- \
10774 set interface vif$i \
10775 external-ids:iface-id=sw$i-p${i}0 \
10776 options:tx_pcap=hv$i/vif$i-tx.pcap \
10777 options:rxq_pcap=hv$i/vif$i-rx.pcap \
10778 ofport-request=$i
10779done
10780
10781ovn-nbctl lr-add lr0
10782for i in 1 2; do
4c25c3b8 10783 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
86558ac2
LB
10784 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
10785 -- set Logical_Switch_Port lrp$i-attachment type=router \
4c25c3b8 10786 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
86558ac2
LB
10787done
10788
10789OVN_POPULATE_ARP
10790# allow some time for ovn-northd and ovn-controller to catch up.
10791ovn-nbctl --wait=hv sync
10792
10793test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 11 0000 7dae fcfc 0303
0e858e05 10794test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 84 0000 7dae fcfd 0302
4c25c3b8 10795test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
86558ac2
LB
10796OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
10797
159932c9 10798test_tcp_syn_packet 2 2 000000000002 00000000ff02 $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 2 254) 0000 8b40 3039 0000 7bae 4486
9c937ec5 10799test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
98af55fc 10800test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
159932c9
LB
10801OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
10802
86558ac2
LB
10803OVN_CLEANUP([hv1], [hv2])
10804AT_CLEANUP
96ea0ecb
MM
10805
10806AT_SETUP([ovn -- ovn-controller exit])
10807AT_SKIP_IF([test $HAVE_PYTHON = no])
10808ovn_start
10809# Logical network:
10810# One Logical Router: ro, with two logical switches sw1 and sw2.
10811# sw1 is for subnet 10.0.0.0/8
10812# sw2 is for subnet 20.0.0.0/8
10813# sw1 has a single port bound on hv1
10814# sw2 has a single port bound on hv2
10815
10816ovn-nbctl lr-add ro
10817ovn-nbctl ls-add sw1
10818ovn-nbctl ls-add sw2
10819
10820sw1_ro_mac=00:00:10:00:00:01
10821sw1_ro_ip=10.0.0.1
10822sw2_ro_mac=00:00:20:00:00:01
10823sw2_ro_ip=20.0.0.1
10824sw1_p1_mac=00:00:10:00:00:02
10825sw1_p1_ip=10.0.0.2
10826sw2_p1_mac=00:00:20:00:00:02
10827sw2_p1_ip=20.0.0.2
10828
10829ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
10830ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
10831ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
10832 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
10833ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
10834 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
10835
10836ovn-nbctl lsp-add sw1 sw1-p1 \
10837-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
10838
10839ovn-nbctl lsp-add sw2 sw2-p1 \
10840-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
10841
10842net_add n1
10843
10844sim_add hv1
10845as hv1
10846ovs-vsctl add-br br-phys
10847ovn_attach n1 br-phys 192.168.0.1
10848ovs-vsctl -- add-port br-int hv1-vif1 -- \
10849 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
10850 options:tx_pcap=hv1/vif1-tx.pcap \
10851 options:rxq_pcap=hv1/vif1-rx.pcap \
10852 ofport-request=1
10853
10854sim_add hv2
10855as hv2
10856ovs-vsctl add-br br-phys
10857ovn_attach n1 br-phys 192.168.0.2
10858ovs-vsctl -- add-port br-int hv2-vif1 -- \
10859 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
10860 options:tx_pcap=hv2/vif1-tx.pcap \
10861 options:rxq_pcap=hv2/vif1-rx.pcap \
10862 ofport-request=1
10863
10864OVN_POPULATE_ARP
10865
10866sleep 1
10867
10868packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
10869 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
10870 udp && udp.src==53 && udp.dst==4369"
10871
10872# Start by Sending the packet and make sure it makes it there as expected
10873as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
10874
10875# Expected packet has TTL decreased by 1
10876expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
10877 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
10878 udp && udp.src==53 && udp.dst==4369"
10879echo $expected | ovstest test-ovn expr-to-packets > expected
10880
10881OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
10882
10883# Stop ovn-controller on hv2
10884as hv2 ovs-appctl -t ovn-controller exit
10885
10886# Now send the packet again. This time, it should not arrive.
10887as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
10888
10889OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
10890
10891# Start ovn-controller again just so OVN_CLEANUP doesn't complain
10892as hv2 start_daemon ovn-controller
10893
10894OVN_CLEANUP([hv1],[hv2])
10895AT_CLEANUP
10896
10897AT_SETUP([ovn -- ovn-controller restart])
10898AT_SKIP_IF([test $HAVE_PYTHON = no])
10899ovn_start
10900
10901# Logical network:
10902# One Logical Router: ro, with two logical switches sw1 and sw2.
10903# sw1 is for subnet 10.0.0.0/8
10904# sw2 is for subnet 20.0.0.0/8
10905# sw1 has a single port bound on hv1
10906# sw2 has a single port bound on hv2
10907
10908ovn-nbctl lr-add ro
10909ovn-nbctl ls-add sw1
10910ovn-nbctl ls-add sw2
10911
10912sw1_ro_mac=00:00:10:00:00:01
10913sw1_ro_ip=10.0.0.1
10914sw2_ro_mac=00:00:20:00:00:01
10915sw2_ro_ip=20.0.0.1
10916sw1_p1_mac=00:00:10:00:00:02
10917sw1_p1_ip=10.0.0.2
10918sw2_p1_mac=00:00:20:00:00:02
10919sw2_p1_ip=20.0.0.2
10920
10921ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
10922ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
10923ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
10924 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
10925ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
10926 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
10927
10928ovn-nbctl lsp-add sw1 sw1-p1 \
10929-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
10930
10931ovn-nbctl lsp-add sw2 sw2-p1 \
10932-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
10933
10934net_add n1
10935
10936sim_add hv1
10937as hv1
10938ovs-vsctl add-br br-phys
10939ovn_attach n1 br-phys 192.168.0.1
10940ovs-vsctl -- add-port br-int hv1-vif1 -- \
10941 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
10942 options:tx_pcap=hv1/vif1-tx.pcap \
10943 options:rxq_pcap=hv1/vif1-rx.pcap \
10944 ofport-request=1
10945
10946sim_add hv2
10947as hv2
10948ovs-vsctl add-br br-phys
10949ovn_attach n1 br-phys 192.168.0.2
10950ovs-vsctl -- add-port br-int hv2-vif1 -- \
10951 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
10952 options:tx_pcap=hv2/vif1-tx.pcap \
10953 options:rxq_pcap=hv2/vif1-rx.pcap \
10954 ofport-request=1
10955
10956OVN_POPULATE_ARP
10957
10958sleep 1
10959
10960packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
10961 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
10962 udp && udp.src==53 && udp.dst==4369"
10963
10964# Start by Sending the packet and make sure it makes it there as expected
10965as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
10966
10967# Expected packet has TTL decreased by 1
10968expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
10969 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
10970 udp && udp.src==53 && udp.dst==4369"
10971echo $expected | ovstest test-ovn expr-to-packets > expected
10972
10973OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
10974
10975# Stop ovn-controller on hv2 with --restart flag
10976as hv2 ovs-appctl -t ovn-controller exit --restart
10977
10978# Now send the packet again. This time, it should still arrive
10979as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
10980
10981cat expected expected > expected2
10982
10983OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
10984
10985# Start ovn-controller again just so OVN_CLEANUP doesn't complain
10986as hv2 start_daemon ovn-controller
10987
10988OVN_CLEANUP([hv1],[hv2])
10989
10990AT_CLEANUP