]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
ovn.at: fix occasional failure - options:requested-chassis with hostname
[ovs.git] / tests / ovn.at
CommitLineData
49d7c759
BP
1# OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2#
3# This compares packets read from PCAP, in pcap format, to those read
4# from EXPECTED, which is a text file containing packets as hex
5# strings, one per line. If PCAP contains fewer packets than
6# EXPECTED, it waits up to 10 seconds for more packets to appear.
7#
8# The implementation is an m4 macro that is mostly implemented in
9# terms of a shell function. This reduces the size of the generated
10# testsuite file since the shell function is only emitted once even
11# when this macro is invoked many times.
12m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
20 ovs_wait_cond () {
abb37b6b
FF
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
49d7c759
BP
24 }
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
26
e4543cfe 27 sort $exp_text > expout
49d7c759
BP
28 }
29])
30m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
33
f295c17b 34AT_BANNER([OVN components])
10b1662b
BP
35
36AT_SETUP([ovn -- lexer])
37dnl For lines without =>, input and expected output are identical.
38dnl For lines with =>, input precedes => and expected output follows =>.
39AT_DATA([test-cases.txt], [dnl
40foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41"abc\u0020def" => "abc def"
42" => error("Input ends inside quoted string.")dnl "
43
2c5cbb15
RB
44$foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45$1 => error("`$' must be followed by a valid identifier.") 1
46
10b1662b
BP
47a/*b*/c => a c
48a//b c => a
49a/**/b => a b
50a/*/b => a error("`/*' without matching `*/'.")
51a/*/**/b => a b
52a/b => a error("`/' is only valid as part of `//' or `/*'.") b
53
540 1 12345 18446744073709551615
5518446744073709551616 => error("Decimal constants must be less than 2**64.")
569999999999999999999999 => error("Decimal constants must be less than 2**64.")
5701 => error("Decimal constants must not have leading zeros.")
58
590/0
600/1
611/0 => error("Value contains unmasked 1-bits.")
621/1
63128/384
641/3
651/ => error("Integer constant expected.")
66
671/0x123 => error("Value and mask have incompatible formats.")
68
690x1234
700x01234 => 0x1234
710x0 => 0
720x000 => 0
730xfedcba9876543210
740XFEDCBA9876543210 => 0xfedcba9876543210
750xfedcba9876543210fedcba9876543210
10b1662b
BP
760x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
770x => error("Hex digits expected following 0x.")
780X => error("Hex digits expected following 0X.")
790x0/0x0 => 0/0
800x0/0x1 => 0/0x1
810x1/0x0 => error("Value contains unmasked 1-bits.")
820xffff/0x1ffff
830x. => error("Invalid syntax in hexadecimal constant.")
84
85192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86256.1.2.3 => error("Invalid numeric constant.")
87192.168.0.0/16
88192.168.0.0/255.255.0.0 => 192.168.0.0/16
89192.168.0.0/255.255.255.0 => 192.168.0.0/24
90192.168.0.0/255.255.0.255
91192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
92192.168.0.0/32
93192.168.0.0/255.255.255.255 => 192.168.0.0/32
52c0fc39 941.2.3.4:5 => 1.2.3.4 : 5
10b1662b
BP
95
96::
97::1
98ff00::1234 => ff00::1234
992001:db8:85a3::8a2e:370:7334
1002001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
1012001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
102::ffff:192.0.2.128
103::ffff:c000:0280 => ::ffff:192.0.2.128
104::1/::1
105::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
106::1/128
107ff00::/8
108ff00::/ff00:: => ff00::/8
109
11001:23:45:67:ab:cd
11101:23:45:67:AB:CD => 01:23:45:67:ab:cd
112fe:dc:ba:98:76:54
113FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
11401:00:00:00:00:00/01:00:00:00:00:00
115ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118fe:x => error("Invalid numeric constant.")
11900:01:02:03:04:x => error("Invalid numeric constant.")
120
a20c96c6 121# Test that operators are tokenized as expected, even without white space.
52c0fc39 122(){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
10b1662b
BP
123& => error("`&' is only valid as part of `&&'.")
124| => error("`|' is only valid as part of `||'.")
56091efe 125- => error("`-' is only valid as part of `--'.")
10b1662b
BP
126
127^ => error("Invalid character `^' in input.")
128])
129AT_CAPTURE_FILE([input.txt])
130sed 's/ =>.*//' test-cases.txt > input.txt
131sed 's/.* => //' test-cases.txt > expout
132AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
133AT_CLEANUP
e0840f11 134
7700eea0
BP
135dnl The OVN expression parser needs to know what fields overlap with one
136dnl another. This test therefore verifies that all the smaller registers
137dnl are defined as terms of subfields of the larger ones.
138dnl
139dnl When we add or remove registers this test needs to be updated, of course.
140AT_SETUP([ovn -- registers])
141AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142[[reg0 = xxreg0[96..127]
143reg1 = xxreg0[64..95]
144reg2 = xxreg0[32..63]
145reg3 = xxreg0[0..31]
146reg4 = xxreg1[96..127]
147reg5 = xxreg1[64..95]
148reg6 = xxreg1[32..63]
149reg7 = xxreg1[0..31]
150reg8 = xreg4[32..63]
151reg9 = xreg4[0..31]
152xreg0 = xxreg0[64..127]
153xreg1 = xxreg0[0..63]
154xreg2 = xxreg1[64..127]
155xreg3 = xxreg1[0..63]
156xreg4 = OXM_OF_PKT_REG4
157xxreg0 = NXM_NX_XXREG0
158xxreg1 = NXM_NX_XXREG1
159]])
160AT_CLEANUP
161
2277b860
BP
162dnl Check that the OVN conntrack field definitions are correct.
163AT_SETUP([ovn -- conntrack fields])
164AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
858c2f76
GS
165[[ct.dnat = ct_state[7]
166ct.est = ct_state[1]
2277b860
BP
167ct.inv = ct_state[4]
168ct.new = ct_state[0]
169ct.rel = ct_state[2]
170ct.rpl = ct_state[3]
858c2f76 171ct.snat = ct_state[6]
2277b860
BP
172ct.trk = ct_state[5]
173ct_label = NXM_NX_CT_LABEL
b73db61d 174ct_label.blocked = ct_label[0]
2277b860
BP
175ct_mark = NXM_NX_CT_MARK
176ct_state = NXM_NX_CT_STATE
177]])
178AT_CLEANUP
179
42d36b58
AZ
180AT_SETUP([ovn -- compsition])
181AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
182AT_CLEANUP
183
e0840f11
BP
184AT_SETUP([ovn -- expression parser])
185dnl For lines without =>, input and expected output are identical.
186dnl For lines with =>, input precedes => and expected output follows =>.
187AT_DATA([test-cases.txt], [[
188eth.type == 0x800
189eth.type==0x800 => eth.type == 0x800
190eth.type[0..15] == 0x800 => eth.type == 0x800
191
192vlan.present
193vlan.present == 1 => vlan.present
194!(vlan.present == 0) => vlan.present
195!(vlan.present != 1) => vlan.present
196!vlan.present
197vlan.present == 0 => !vlan.present
198vlan.present != 1 => !vlan.present
199!(vlan.present == 1) => !vlan.present
200!(vlan.present != 0) => !vlan.present
201
202eth.dst[0]
203eth.dst[0] == 1 => eth.dst[0]
204eth.dst[0] != 0 => eth.dst[0]
205!(eth.dst[0] == 0) => eth.dst[0]
206!(eth.dst[0] != 1) => eth.dst[0]
207
208!eth.dst[0]
209eth.dst[0] == 0 => !eth.dst[0]
210eth.dst[0] != 1 => !eth.dst[0]
211!(eth.dst[0] == 1) => !eth.dst[0]
212!(eth.dst[0] != 0) => !eth.dst[0]
213
214vlan.tci[12..15] == 0x3
215vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
216vlan.tci[12..15] != 0x3
217vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
218
219!vlan.pcp => vlan.pcp == 0
220!(vlan.pcp) => vlan.pcp == 0
221vlan.pcp == 0x4
222vlan.pcp != 0x4
223vlan.pcp > 0x4
224vlan.pcp >= 0x4
225vlan.pcp < 0x4
226vlan.pcp <= 0x4
227!(vlan.pcp != 0x4) => vlan.pcp == 0x4
228!(vlan.pcp == 0x4) => vlan.pcp != 0x4
229!(vlan.pcp <= 0x4) => vlan.pcp > 0x4
230!(vlan.pcp < 0x4) => vlan.pcp >= 0x4
231!(vlan.pcp >= 0x4) => vlan.pcp < 0x4
232!(vlan.pcp > 0x4) => vlan.pcp <= 0x4
2330x4 == vlan.pcp => vlan.pcp == 0x4
2340x4 != vlan.pcp => vlan.pcp != 0x4
2350x4 < vlan.pcp => vlan.pcp > 0x4
2360x4 <= vlan.pcp => vlan.pcp >= 0x4
2370x4 > vlan.pcp => vlan.pcp < 0x4
2380x4 >= vlan.pcp => vlan.pcp <= 0x4
239!(0x4 != vlan.pcp) => vlan.pcp == 0x4
240!(0x4 == vlan.pcp) => vlan.pcp != 0x4
241!(0x4 >= vlan.pcp) => vlan.pcp > 0x4
242!(0x4 > vlan.pcp) => vlan.pcp >= 0x4
243!(0x4 <= vlan.pcp) => vlan.pcp < 0x4
244!(0x4 < vlan.pcp) => vlan.pcp <= 0x4
245
2461 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
2471 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2481 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
2491 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
2501 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2514 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
2524 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
2534 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
2544 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
255!(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
256!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
257!(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
258!(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
259!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
260!(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
261!(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
262!(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
263!(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
264
265vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
267
268vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
269vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
270
271vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
272vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
273vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
274
275ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
276ip6.src == ::1 => ip6.src == 0x1
277
278ip4.src == 1.2.3.4 => ip4.src == 0x1020304
279ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
280ip6.src == ::1 => ip6.src == 0x1
281
2821
2830
284!1 => 0
285!0 => 1
286
287inport == "eth0"
288!(inport != "eth0") => inport == "eth0"
289
3b7cb7e1
BP
290ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
291inport == 1 => String field inport is not compatible with integer constant.
76da94b5 292ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
e0840f11
BP
293
294ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
295eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
296vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
297
298inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
299!(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
300eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
301!(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
76da94b5 302inport = "eth0" => Syntax error at `=' expecting relational operator.
e0840f11
BP
303
304123 == 123 => Syntax error at `123' expecting field name.
305
2c5cbb15 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 =>.
364AT_DATA([test-cases.txt], [[
365ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
366ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
367ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
368ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
369ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
370
371ip => eth.type == 0x800 || eth.type == 0x86dd
372ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
373ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
374ip > 0 => Only == and != operators may be used with nominal field ip.
375!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
376ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
377
378vlan.present => vlan.tci[12]
379!vlan.present => !vlan.tci[12]
380
381!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
382vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
7700eea0 383!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
e0840f11
BP
384
385ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
386!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
387ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
388
389bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
390self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
391mutual_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'.
392mutual_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'.
393]])
394sed 's/ =>.*//' test-cases.txt > input.txt
395sed 's/.* => //' test-cases.txt > expout
396AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
397AT_CLEANUP
398
9d4aecca 399AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 400AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 401 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
402])
403AT_CLEANUP
404
9d4aecca 405AT_SETUP([ovn -- 2-term expression conversion])
e0840f11 406AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
8c3caa2c 407 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
408])
409AT_CLEANUP
410
9d4aecca 411AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 412AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
8c3caa2c 413 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
414])
415AT_CLEANUP
416
9d4aecca
BP
417AT_SETUP([ovn -- 3-term numeric expression simplification])
418AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
8c3caa2c 419 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
420])
421AT_CLEANUP
422
9d4aecca
BP
423AT_SETUP([ovn -- 4-term string expression simplification])
424AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
425 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
426])
427AT_CLEANUP
428
9d4aecca
BP
429AT_SETUP([ovn -- 3-term mixed expression simplification])
430AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
8c3caa2c 431 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
432])
433AT_CLEANUP
434
97ba1d55
BP
435AT_SETUP([ovn -- simplification special cases])
436simplify() {
437 echo "$1" | ovstest test-ovn simplify-expr
438}
439AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
440])
a3d79068
BP
441AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
442])
33f15d17
BP
443AT_CHECK([simplify 'tcp.dst >= 0'], [0],
444 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
445])
446AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
447 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
448])
449AT_CHECK([simplify 'tcp.dst > 0'], [0],
450 [[(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)
451]])
452AT_CHECK([simplify 'tcp.dst < 65535'], [0],
453 [[(!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)
454]])
97ba1d55
BP
455AT_CLEANUP
456
ba8d3816
MS
457AT_SETUP([ovn -- is_chassis_resident simplification])
458simplify() {
459 echo "$1" | ovstest test-ovn simplify-expr
460}
461AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
462])
463AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
464])
465AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
466])
467AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
468])
469AT_CLEANUP
470
9d4aecca
BP
471AT_SETUP([ovn -- 4-term numeric expression normalization])
472AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
8c3caa2c 473 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
474])
475AT_CLEANUP
476
9d4aecca
BP
477AT_SETUP([ovn -- 4-term string expression normalization])
478AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
479 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
480])
481AT_CLEANUP
482
483AT_SETUP([ovn -- 4-term mixed expression normalization])
484AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
8c3caa2c 485 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
9d4aecca
BP
486])
487AT_CLEANUP
488
489AT_SETUP([ovn -- 5-term numeric expression normalization])
490AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
8c3caa2c 491 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
9d4aecca
BP
492])
493AT_CLEANUP
494
495AT_SETUP([ovn -- 5-term string expression normalization])
496AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
497 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
498])
499AT_CLEANUP
500
501AT_SETUP([ovn -- 5-term mixed expression normalization])
502AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
8c3caa2c 503 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
504])
505AT_CLEANUP
506
507AT_SETUP([ovn -- 4-term numeric expressions to flows])
8c3caa2c 508AT_KEYWORDS([expression])
9d4aecca 509AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
8c3caa2c 510 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
9d4aecca
BP
511])
512AT_CLEANUP
513
514AT_SETUP([ovn -- 4-term string expressions to flows])
8c3caa2c 515AT_KEYWORDS([expression])
9d4aecca
BP
516AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
517 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
518])
519AT_CLEANUP
520
521AT_SETUP([ovn -- 4-term mixed expressions to flows])
8c3caa2c 522AT_KEYWORDS([expression])
9d4aecca 523AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
8c3caa2c 524 [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
525])
526AT_CLEANUP
527
528AT_SETUP([ovn -- 3-term numeric expressions to flows])
8c3caa2c 529AT_KEYWORDS([expression])
9d4aecca 530AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
8c3caa2c 531 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
532])
533AT_CLEANUP
f386a8a7
BP
534
535AT_SETUP([ovn -- converting expressions to flows -- string fields])
8c3caa2c 536AT_KEYWORDS([expression])
f386a8a7
BP
537expr_to_flow () {
538 echo "$1" | ovstest test-ovn expr-to-flows | sort
539}
cc5e28d8 540AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 541])
cc5e28d8 542AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
543])
544AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
545])
546AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
547ip,reg14=0x5
548ipv6,reg14=0x5
f386a8a7
BP
549])
550AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
551ip,reg14=0x6
552ipv6,reg14=0x6
f386a8a7
BP
553])
554AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
555])
556AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
557[reg14=0x5
558reg14=0x6
559reg14=0xfffe
f386a8a7
BP
560])
561AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
562ip,reg14=0x5
563ip,reg14=0x6
564ipv6,reg14=0x5
565ipv6,reg14=0x6
f386a8a7 566])
9d4aecca
BP
567AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
568(no flows)
569])
f386a8a7 570AT_CLEANUP
3b7cb7e1 571
2c5cbb15 572AT_SETUP([ovn -- converting expressions to flows -- address sets])
8c3caa2c 573AT_KEYWORDS([expression])
2c5cbb15
RB
574expr_to_flow () {
575 echo "$1" | ovstest test-ovn expr-to-flows | sort
576}
577AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
578ip,nw_src=10.0.0.1
579ip,nw_src=10.0.0.2
580ip,nw_src=10.0.0.3
581])
582AT_CHECK([expr_to_flow 'ip4.src == $set1'], [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 == {1.2.3.4, $set1}'], [0], [dnl
588ip,nw_src=1.2.3.4
589ip,nw_src=10.0.0.1
590ip,nw_src=10.0.0.2
591ip,nw_src=10.0.0.3
592])
593AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
594ip,nw_src=1.2.0.0/20
595ip,nw_src=10.0.0.1
596ip,nw_src=10.0.0.2
597ip,nw_src=10.0.0.3
598ip,nw_src=5.5.5.0/24
599])
600AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
601ipv6,ipv6_src=::1
602ipv6,ipv6_src=::2
603ipv6,ipv6_src=::3
604])
605AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
606ipv6,ipv6_src=::1
607ipv6,ipv6_src=::2
608ipv6,ipv6_src=::3
609ipv6,ipv6_src=::4
610])
611AT_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
612dl_src=00:00:00:00:00:01
613dl_src=00:00:00:00:00:02
614dl_src=00:00:00:00:00:03
615])
616AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [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])
ea382567
RB
621AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $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
625dl_src=ba:be:be:ef:de:ad
626])
f3a4e992
HZ
627AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
628(no flows)
629])
630AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
631ip,nw_src=1.2.3.4
632])
633AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
634ip,nw_src=1.2.3.4
635])
636AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
637
638])
639AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
640ip,nw_src=0.0.0.0/1.0.0.0
641ip,nw_src=128.0.0.0/1
642ip,nw_src=16.0.0.0/16.0.0.0
643ip,nw_src=2.0.0.0/2.0.0.0
644ip,nw_src=32.0.0.0/32.0.0.0
645ip,nw_src=4.0.0.0/4.0.0.0
646ip,nw_src=64.0.0.0/64.0.0.0
647ip,nw_src=8.0.0.0/8.0.0.0
648])
649AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
650ip,nw_src=0.0.0.0/1.0.0.0
651ip,nw_src=128.0.0.0/1
652ip,nw_src=16.0.0.0/16.0.0.0
653ip,nw_src=2.0.0.0/2.0.0.0
654ip,nw_src=32.0.0.0/32.0.0.0
655ip,nw_src=4.0.0.0/4.0.0.0
656ip,nw_src=64.0.0.0/64.0.0.0
657ip,nw_src=8.0.0.0/8.0.0.0
658])
2c5cbb15
RB
659AT_CLEANUP
660
3d2848ba
HZ
661AT_SETUP([ovn -- converting expressions to flows -- port groups])
662AT_KEYWORDS([expression])
663expr_to_flow () {
664 echo "$1" | ovstest test-ovn expr-to-flows | sort
665}
666AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
667reg15=0x11
668reg15=0x12
669reg15=0x13
670])
671AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
672(no flows)
673])
674AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
675reg15=0x11
676])
677AT_CLEANUP
678
3b7cb7e1 679AT_SETUP([ovn -- action parsing])
d5a76da4
BP
680dnl Unindented text is input (a set of OVN logical actions).
681dnl Indented text is expected output.
682AT_DATA([test-cases.txt],
683[[# drop
684drop;
685 encodes as drop
686drop; next;
687 Syntax error at `next' expecting end of input.
688next; drop;
689 Syntax error at `drop' expecting action.
5f822129
BP
690
691# output
d5a76da4
BP
692output;
693 encodes as resubmit(,64)
5f822129
BP
694
695# next
d5a76da4 696next;
00c875d0 697 encodes as resubmit(,19)
d5a76da4 698next(11);
8f5de083 699 formats as next;
00c875d0 700 encodes as resubmit(,19)
d5a76da4 701next(0);
00c875d0
MS
702 encodes as resubmit(,8)
703next(23);
d5a76da4
BP
704 encodes as resubmit(,31)
705
706next();
4c99cb18 707 Syntax error at `)' expecting "pipeline" or "table".
d5a76da4
BP
708next(10;
709 Syntax error at `;' expecting `)'.
00c875d0
MS
710next(24);
711 "next" action cannot advance beyond table 23.
5f822129 712
4c99cb18
BP
713next(table=11);
714 formats as next;
00c875d0 715 encodes as resubmit(,19)
4c99cb18
BP
716next(pipeline=ingress);
717 formats as next;
00c875d0 718 encodes as resubmit(,19)
4c99cb18
BP
719next(table=11, pipeline=ingress);
720 formats as next;
00c875d0 721 encodes as resubmit(,19)
4c99cb18
BP
722next(pipeline=ingress, table=11);
723 formats as next;
00c875d0 724 encodes as resubmit(,19)
4c99cb18
BP
725
726next(pipeline=egress);
727 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
728
729next(table=10);
730 formats as next(10);
00c875d0 731 encodes as resubmit(,18)
4c99cb18 732
5f822129 733# Loading a constant value.
d5a76da4
BP
734tcp.dst=80;
735 formats as tcp.dst = 80;
736 encodes as set_field:80->tcp_dst
737 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
738eth.dst[40] = 1;
739 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
740vlan.pcp = 2;
741 encodes as set_field:0x4000/0xe000->vlan_tci
742 has prereqs vlan.tci[12]
743vlan.tci[13..15] = 2;
744 encodes as set_field:0x4000/0xe000->vlan_tci
745inport = "";
746 encodes as set_field:0->reg14
747ip.ttl=4;
748 formats as ip.ttl = 4;
749 encodes as set_field:4->nw_ttl
750 has prereqs eth.type == 0x800 || eth.type == 0x86dd
751outport="eth0"; next; outport="LOCAL"; next;
8f5de083 752 formats as outport = "eth0"; next; outport = "LOCAL"; next;
00c875d0 753 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
d5a76da4
BP
754
755inport[1] = 1;
756 Cannot select subfield of string field inport.
757ip.proto[1] = 1;
758 Cannot select subfield of nominal field ip.proto.
759eth.dst[40] == 1;
760 Syntax error at `==' expecting `=' or `<->'.
761ip = 1;
762 Predicate symbol ip used where lvalue required.
763ip.proto = 6;
764 Field ip.proto is not modifiable.
765inport = {"a", "b"};
766 Syntax error at `{' expecting constant.
767inport = {};
768 Syntax error at `{' expecting constant.
769bad_prereq = 123;
770 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
771self_recurse = 123;
772 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'.
773vlan.present = 0;
774 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
775
776# Moving one field into another.
d5a76da4
BP
777reg0=reg1;
778 formats as reg0 = reg1;
779 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
780vlan.pcp = reg0[0..2];
781 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
782 has prereqs vlan.tci[12]
783reg0[10] = vlan.pcp[1];
784 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
785 has prereqs vlan.tci[12]
786outport = inport;
787 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
788
789reg0[0] = vlan.present;
790 Predicate symbol vlan.present used where lvalue required.
791reg0 = reg1[0..10];
792 Can't assign 11-bit value to 32-bit destination.
793inport = reg0;
794 Can't assign integer field (reg0) to string field (inport).
795inport = big_string;
796 String fields inport and big_string are incompatible for assignment.
797ip.proto = reg0[0..7];
798 Field ip.proto is not modifiable.
5f822129
BP
799
800# Exchanging fields.
d5a76da4
BP
801reg0 <-> reg1;
802 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]
803vlan.pcp <-> reg0[0..2];
804 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]
805 has prereqs vlan.tci[12]
806reg0[10] <-> vlan.pcp[1];
807 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
808 has prereqs vlan.tci[12]
809outport <-> inport;
810 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
811
812reg0[0] <-> vlan.present;
813 Predicate symbol vlan.present used where lvalue required.
814reg0 <-> reg1[0..10];
815 Can't exchange 32-bit field with 11-bit field.
816inport <-> reg0;
817 Can't exchange string field (inport) with integer field (reg0).
818inport <-> big_string;
819 String fields inport and big_string are incompatible for exchange.
820ip.proto <-> reg0[0..7];
821 Field ip.proto is not modifiable.
822reg0[0..7] <-> ip.proto;
823 Field ip.proto is not modifiable.
5f822129
BP
824
825# TTL decrement.
d5a76da4
BP
826ip.ttl--;
827 encodes as dec_ttl
828 has prereqs ip
829ip.ttl
830 Syntax error at end of input expecting `--'.
5f822129 831
467085fd 832# load balancing.
d5a76da4 833ct_lb;
00c875d0 834 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
835 has prereqs ip
836ct_lb();
837 formats as ct_lb;
00c875d0 838 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
839 has prereqs ip
840ct_lb(192.168.1.2:80, 192.168.1.3:80);
841 encodes as group:1
842 has prereqs ip
843ct_lb(192.168.1.2, 192.168.1.3, );
844 formats as ct_lb(192.168.1.2, 192.168.1.3);
845 encodes as group:2
846 has prereqs ip
9d236afa
MM
847ct_lb(fd0f::2, fd0f::3, );
848 formats as ct_lb(fd0f::2, fd0f::3);
849 encodes as group:3
850 has prereqs ip
d5a76da4
BP
851
852ct_lb(192.168.1.2:);
853 Syntax error at `)' expecting port number.
854ct_lb(192.168.1.2:123456);
855 Syntax error at `123456' expecting port number.
856ct_lb(foo);
9d236afa
MM
857 Syntax error at `foo' expecting IP address.
858ct_lb([192.168.1.2]);
859 Syntax error at `192.168.1.2' expecting IPv6 address.
d5a76da4
BP
860
861# ct_next
862ct_next;
00c875d0 863 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
d5a76da4
BP
864 has prereqs ip
865
866# ct_commit
867ct_commit;
868 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
869 has prereqs ip
870ct_commit();
871 formats as ct_commit;
872 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
873 has prereqs ip
874ct_commit(ct_mark=1);
875 formats as ct_commit(ct_mark=0x1);
876 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
877 has prereqs ip
878ct_commit(ct_mark=1/1);
879 formats as ct_commit(ct_mark=0x1/0x1);
880 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
881 has prereqs ip
882ct_commit(ct_label=1);
883 formats as ct_commit(ct_label=0x1);
884 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
885 has prereqs ip
886ct_commit(ct_label=1/1);
887 formats as ct_commit(ct_label=0x1/0x1);
888 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
889 has prereqs ip
890ct_commit(ct_mark=1, ct_label=2);
891 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
892 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
893 has prereqs ip
894
895ct_commit(ct_label=0x01020304050607080910111213141516);
896 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
897 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
898 has prereqs ip
899ct_commit(ct_label=0x181716151413121110090807060504030201);
900 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
901 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
902 has prereqs ip
903ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
904 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
905 has prereqs ip
906ct_commit(ct_label=18446744073709551615);
907 formats as ct_commit(ct_label=0xffffffffffffffff);
908 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
909 has prereqs ip
910ct_commit(ct_label=18446744073709551616);
911 Decimal constants must be less than 2**64.
912
913# ct_dnat
914ct_dnat;
00c875d0 915 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
d5a76da4
BP
916 has prereqs ip
917ct_dnat(192.168.1.2);
00c875d0 918 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
d5a76da4
BP
919 has prereqs ip
920
921ct_dnat(192.168.1.2, 192.168.1.3);
922 Syntax error at `,' expecting `)'.
923ct_dnat(foo);
924 Syntax error at `foo' expecting IPv4 address.
925ct_dnat(foo, bar);
926 Syntax error at `foo' expecting IPv4 address.
927ct_dnat();
928 Syntax error at `)' expecting IPv4 address.
929
930# ct_snat
931ct_snat;
00c875d0 932 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
d5a76da4
BP
933 has prereqs ip
934ct_snat(192.168.1.2);
00c875d0 935 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
d5a76da4
BP
936 has prereqs ip
937
938ct_snat(192.168.1.2, 192.168.1.3);
939 Syntax error at `,' expecting `)'.
940ct_snat(foo);
941 Syntax error at `foo' expecting IPv4 address.
942ct_snat(foo, bar);
943 Syntax error at `foo' expecting IPv4 address.
944ct_snat();
945 Syntax error at `)' expecting IPv4 address.
de297547 946
db0e819b
BP
947# ct_clear
948ct_clear;
949 encodes as ct_clear
950
b3bd2c33 951# clone
8f5de083 952clone { ip4.dst = 255.255.255.255; output; }; next;
00c875d0 953 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
b3bd2c33
BP
954 has prereqs eth.type == 0x800
955
6335d074 956# arp
8a41ad8e
BP
957arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
958 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 959 has prereqs ip4
bac29564
BP
960arp { };
961 formats as arp { drop; };
962 encodes as controller(userdata=00.00.00.00.00.00.00.00)
963 has prereqs ip4
6335d074 964
0bac7164 965# get_arp
d5a76da4
BP
966get_arp(outport, ip4.dst);
967 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[]
968 has prereqs eth.type == 0x800
969get_arp(inport, reg0);
970 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[]
971
972get_arp;
973 Syntax error at `;' expecting `('.
974get_arp();
975 Syntax error at `)' expecting field name.
976get_arp(inport);
977 Syntax error at `)' expecting `,'.
978get_arp(inport ip4.dst);
979 Syntax error at `ip4.dst' expecting `,'.
980get_arp(inport, ip4.dst;
981 Syntax error at `;' expecting `)'.
982get_arp(inport, eth.dst);
983 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
984get_arp(inport, outport);
985 Cannot use string field outport where numeric field is required.
986get_arp(reg0, ip4.dst);
987 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
988
989# put_arp
d5a76da4
BP
990put_arp(inport, arp.spa, arp.sha);
991 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[]
992 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 993
42814145 994# put_dhcp_opts
d5a76da4
BP
995reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
996 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)
997reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
998 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");
999 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67,pause)
1000reg0[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);
1001 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);
1002 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)
1003
1004reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1005 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1006reg1[0] = put_dhcp_opts();
1007 put_dhcp_opts requires offerip to be specified.
1008reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1009 Syntax error at `x' expecting DHCPv4 option name.
1010reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1011 put_dhcp_opts requires offerip to be specified.
1012reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1013 Syntax error at `"hi"'.
1014reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1015 Syntax error at `xyzzy' expecting DHCPv4 option name.
1016reg1[0] = put_dhcp_opts(offerip="xyzzy");
1017 DHCPv4 option offerip requires numeric value.
1018reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1019 DHCPv4 option domain requires string value.
42814145 1020
b1a3a6a4
NS
1021# nd_ns
1022nd_ns { nd.target = xxreg0; output; };
1023 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)
1024 has prereqs ip6
1025
1026nd_ns { };
1027 formats as nd_ns { drop; };
1028 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1029 has prereqs ip6
1030
f8a8db39 1031# nd_na
d5a76da4
BP
1032nd_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; };
1033 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1034 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)
1035 has prereqs nd_ns
e75451fe 1036
c34a87b6 1037# get_nd
d5a76da4
BP
1038get_nd(outport, ip6.dst);
1039 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[]
1040 has prereqs eth.type == 0x86dd
1041get_nd(inport, xxreg0);
1042 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[]
1043get_nd;
1044 Syntax error at `;' expecting `('.
1045get_nd();
1046 Syntax error at `)' expecting field name.
1047get_nd(inport);
1048 Syntax error at `)' expecting `,'.
1049get_nd(inport ip6.dst);
1050 Syntax error at `ip6.dst' expecting `,'.
1051get_nd(inport, ip6.dst;
1052 Syntax error at `;' expecting `)'.
1053get_nd(inport, eth.dst);
1054 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1055get_nd(inport, outport);
1056 Cannot use string field outport where numeric field is required.
1057get_nd(xxreg0, ip6.dst);
1058 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
1059
1060# put_nd
d5a76da4
BP
1061put_nd(inport, nd.target, nd.sll);
1062 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[]
1063 has prereqs ((icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd)) || (icmp6.type == 0x88 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd))) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
c34a87b6 1064
01cfdb2f 1065# put_dhcpv6_opts
d5a76da4 1066reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
a55dacac 1067 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
1068reg1[0] = put_dhcpv6_opts();
1069 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1070reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1071 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
a55dacac 1072 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
1073reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1074 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
a55dacac 1075 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 1076reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
a55dacac 1077 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
1078reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1079 Syntax error at `x' expecting DHCPv6 option name.
1080reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1081 Syntax error at `"hi"'.
1082reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1083 Syntax error at `xyzzy' expecting DHCPv6 option name.
1084reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1085 DHCPv6 option ia_addr requires numeric value.
1086reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1087 DHCPv6 option domain_search requires string value.
01cfdb2f 1088
a6095f81
BS
1089# set_queue
1090set_queue(0);
1091 encodes as set_queue:0
1092set_queue(61440);
1093 encodes as set_queue:61440
1094set_queue(65535);
1095 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1096
ea991ad2
NS
1097# dns_lookup
1098reg1[0] = dns_lookup();
1099 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1100 has prereqs udp
1101reg1[0] = dns_lookup("foo");
1102 dns_lookup doesn't take any parameters
1103
66d89287
GL
1104# set_meter
1105set_meter(0);
1106 Rate 0 for set_meter is not in valid.
1107set_meter(1);
1108 encodes as meter:1
1109set_meter(100, 1000);
1110 encodes as meter:2
1111set_meter(100, 1000, );
1112 Syntax error at `,' expecting `)'.
1113set_meter(4294967295, 4294967295);
1114 encodes as meter:3
1115
52ed5fcc
NS
1116# put_nd_ra_opts
1117reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1118 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)
1119 has prereqs ip6
1120reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1121 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)
1122 has prereqs ip6
1123reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1124 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)
1125 has prereqs ip6
1126reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1127 slla option not present
1128reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1129 prefix option can't be set when address mode is dhcpv6_stateful.
1130reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1131 prefix option can't be set when address mode is dhcpv6_stateful.
1132reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1133 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1134reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1135 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1136reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1137 Syntax error at `dhcpv6_stateless' expecting constant.
1138reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1139 Invalid value for "prefix" option
1140reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1141 Invalid value for "addr_mode" option
1142reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1143 IPv6 ND RA option mtu requires numeric value.
1144reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1145 Invalid value for "mtu" option
1146
bc3d6a63
LB
1147# icmp4
1148icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1149 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)
1150 has prereqs ip4
1151
1152icmp4 { };
1153 formats as icmp4 { drop; };
1154 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1155 has prereqs ip4
1156
3e7fa1e3
LB
1157# icmp6
1158icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1159 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)
1160 has prereqs ip6
1161
1162icmp6 { };
1163 formats as icmp6 { drop; };
1164 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1165 has prereqs ip6
1166
22b65e4d
LB
1167# tcp_reset
1168tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1169 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)
1170 has prereqs tcp
1171
1172tcp_reset { };
1173 formats as tcp_reset { drop; };
1174 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1175 has prereqs tcp
1176
5f822129 1177# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
1178ip4.src = ip6.src[0..31];
1179 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1180 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1181ip4.src <-> ip6.src[0..31];
1182 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[]
1183 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1184
1185# Miscellaneous negative tests.
1186;
1187 Syntax error at `;'.
1188xyzzy;
1189 Syntax error at `xyzzy' expecting action.
1190next; 123;
1191 Syntax error at `123'.
1192next; xyzzy;
1193 Syntax error at `xyzzy' expecting action.
1194next
9aef3c1b 1195 Syntax error at end of input expecting `;'.
3b7cb7e1 1196]])
d5a76da4
BP
1197sed '/^[[ ]]/d' test-cases.txt > input.txt
1198cp test-cases.txt expout
3b7cb7e1
BP
1199AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1200AT_CLEANUP
f295c17b
BP
1201
1202AT_BANNER([OVN end-to-end tests])
1203
9975d7be
BP
1204# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1205AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1206AT_KEYWORDS([ovnarp])
f295c17b
BP
1207AT_SKIP_IF([test $HAVE_PYTHON = no])
1208ovn_start
1209
1210# Create hypervisors hv[123].
9975d7be 1211# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1212# Add all of the vifs to a single logical switch lsw0.
1213# Turn on port security on all the vifs except vif[123]1.
1214# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1215# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1216ovn-nbctl ls-add lsw0
f295c17b
BP
1217net_add n1
1218for i in 1 2 3; do
1219 sim_add hv$i
1220 as hv$i
1221 ovs-vsctl add-br br-phys
1222 ovn_attach n1 br-phys 192.168.0.$i
1223
1224 for j in 1 2 3; do
1225 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 1226 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1227 if test $j = 1; then
31ed1192 1228 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1229 else
7dc88496
NS
1230 if test $j = 3; then
1231 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1232 else
1233 ip_addrs="192.168.0.$i$j"
1234 fi
31ed1192
JP
1235 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1236 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1237 fi
1238 done
1239done
1240ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1241ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1242ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1243ovn-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\"
1244ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b 1245
3d2848ba
HZ
1246get_lsp_uuid () {
1247 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1248}
1249
1250ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1251ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1252
f295c17b
BP
1253# Pre-populate the hypervisors' ARP tables so that we don't lose any
1254# packets for ARP resolution (native tunneling doesn't queue packets
1255# for ARP resolution).
74868f2c 1256OVN_POPULATE_ARP
f295c17b
BP
1257
1258# Allow some time for ovn-northd and ovn-controller to catch up.
1259# XXX This should be more systematic.
1260sleep 1
611099dc 1261
fc6f9978
HZ
1262# Make sure there is no attempt to adding duplicated flows by ovn-controller
1263AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1264AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1265AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1266
57d143eb
HZ
1267# Given the name of a logical port, prints the name of the hypervisor
1268# on which it is located.
1269vif_to_hv() {
1270 echo hv${1%?}
1271}
1272
f295c17b
BP
1273# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1274#
1275# This shell function causes a packet to be received on INPORT. The packet's
1276# content has Ethernet destination DST and source SRC (each exactly 12 hex
1277# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1278# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1279# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1280for i in 1 2 3; do
1281 for j in 1 2 3; do
1282 : > $i$j.expected
1283 done
1284done
1285test_packet() {
1286 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1287 hv=`vif_to_hv $inport`
f295c17b
BP
1288 vif=vif$inport
1289 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1290 for outport; do
e4543cfe 1291 echo $packet >> $outport.expected
f295c17b
BP
1292 done
1293}
1294
57d143eb
HZ
1295# test_arp INPORT SHA SPA TPA [REPLY_HA]
1296#
1297# Causes a packet to be received on INPORT. The packet is an ARP
1298# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1299# it should be the hardware address of the target to expect to receive in an
1300# ARP reply; otherwise no reply is expected.
1301#
31ed1192 1302# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1303# SHA and REPLY_HA are each 12 hex digits.
1304# SPA and TPA are each 8 hex digits.
1305test_arp() {
1306 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1307 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1308 hv=`vif_to_hv $inport`
1309 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1310
92f9822b 1311 if test X$reply_ha = X; then
57d143eb
HZ
1312 # Expect to receive the broadcast ARP on the other logical switch ports
1313 # if no reply is expected.
1314 local i j
1315 for i in 1 2 3; do
1316 for j in 1 2 3; do
1317 if test $i$j != $inport; then
1318 echo $request >> $i$j.expected
1319 fi
1320 done
1321 done
1322 else
1323 # Expect to receive the reply, if any.
1324 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1325 echo $reply >> $inport.expected
1326 fi
1327}
1328
1329ip_to_hex() {
1330 printf "%02x%02x%02x%02x" "$@"
1331}
1332
f295c17b
BP
1333# Send packets between all pairs of source and destination ports:
1334#
31ed1192
JP
1335# 1. Unicast packets are delivered to exactly one logical switch port
1336# (except that packets destined to their input ports are dropped).
f295c17b 1337#
31ed1192
JP
1338# 2. Broadcast and multicast are delivered to all logical switch ports
1339# except the input port.
f295c17b 1340#
ea46a4e9 1341# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1342# MAC address.
1343#
ea46a4e9 1344# 4. The switch drops all packets with a VLAN tag.
f295c17b 1345#
ea46a4e9 1346# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1347# affects behavior when port security is turned off, since otherwise port
1348# security would drop the packet anyway.)
1349#
ea46a4e9 1350# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1351# switch ports with "unknown" among their MAC addresses (and port
1352# security disabled).
f295c17b 1353#
ea46a4e9 1354# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1355#
ea46a4e9 1356# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1357#
9fcb6a18
BP
1358# 9. OVN generates responses to ARP requests for known IPs, except for
1359# requests from a port for the port's own IP.
57d143eb
HZ
1360#
1361# 10. No response to ARP requests for unknown IPs.
4acd1e87 1362
f295c17b
BP
1363for is in 1 2 3; do
1364 for js in 1 2 3; do
1365 s=$is$js
1366 bcast=
4d5c43d5
JP
1367 unknown=
1368 bacl2=
1369 bacl3=
f295c17b
BP
1370 for id in 1 2 3; do
1371 for jd in 1 2 3; do
1372 d=$id$jd
1373
1374 if test $d != $s; then unicast=$d; else unicast=; fi
1375 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1376
1377 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1378 impersonate=$d
1379 else
1380 impersonate=
1381 fi
f295c17b
BP
1382 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1383
4d5c43d5
JP
1384 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1385 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1386 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1387 # Source of 11, 21, or 31 and dest of 33 should be dropped
1388 # due to the 4th ACL that uses address_set(set1).
1389 acl4=
1390 else
1391 acl4=$d
1392 fi
3d2848ba
HZ
1393 if test $d = $s || test $d = 22 || test $d = 33; then
1394 # dest of 22 and 33 should be dropped
1395 # due to the 5th ACL that uses port_group(pg1).
1396 acl5=
1397 else
1398 acl5=$d
1399 fi
f295c17b
BP
1400 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1401 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1402 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1403 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
3d2848ba 1404 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
f295c17b
BP
1405
1406 test_packet $s f000000000$d f00000000055 810000091234 #4
1407 test_packet $s f000000000$d 0100000000$s $s$d #5
1408
4d5c43d5
JP
1409 if test $d != $s && test $jd = 1; then
1410 unknown="$unknown $d"
1411 fi
f295c17b
BP
1412 bcast="$bcast $unicast"
1413 bacl2="$bacl2 $acl2"
1414 bacl3="$bacl3 $acl3"
57d143eb 1415
db02f370 1416 sip=`ip_to_hex 192 168 0 $is$js`
57d143eb
HZ
1417 tip=`ip_to_hex 192 168 0 $id$jd`
1418 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1419 if test $d != $s; then
1420 reply_ha=f000000000$d
1421 else
1422 reply_ha=
1423 fi
1424 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1425 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1426
1427 if test $jd = 3; then
31ed1192 1428 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1429 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1430 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1431 fi
f295c17b
BP
1432 done
1433 done
1434
4d5c43d5 1435 # Broadcast and multicast.
f295c17b
BP
1436 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1437 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1438 if test $js = 1; then
f295c17b
BP
1439 bcast_impersonate=$bcast
1440 else
4d5c43d5
JP
1441 bcast_impersonate=
1442 fi
f295c17b
BP
1443 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1444
1445 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1446
1447 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1448 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1449 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1450 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1451 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1452 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1453 done
1454done
1455
7dc88496
NS
1456# set address for lp13 with invalid characters.
1457# lp13 should be configured with only 192.168.0.13.
31ed1192 1458ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1459
1460# Allow some time for ovn-northd and ovn-controller to catch up.
1461# XXX This should be more systematic.
1462sleep 1
1463
7dc88496
NS
1464sip=`ip_to_hex 192 168 0 11`
1465tip=`ip_to_hex 192 168 0 13`
1466test_arp 11 f00000000011 $sip $tip f00000000013
1467
1468tip=`ip_to_hex 192 169 0 13`
1469#arp request for 192.169.0.13 should be flooded
1470test_arp 11 f00000000011 $sip $tip
1471
91125642 1472# dump information and flows with counters
bb0c41d3
RM
1473ovn-sbctl dump-flows -- list multicast_group
1474
1475echo "------ hv1 dump ------"
1476as hv1 ovs-vsctl show
1477as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1478
1479echo "------ hv2 dump ------"
1480as hv2 ovs-vsctl show
1481as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1482
1483echo "------ hv3 dump ------"
1484as hv3 ovs-vsctl show
1485as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1486
f295c17b
BP
1487# Now check the packets actually received against the ones expected.
1488for i in 1 2 3; do
1489 for j in 1 2 3; do
49d7c759 1490 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1491 done
1492done
fcde56f5 1493
7a8f15e0 1494OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1495
f295c17b 1496AT_CLEANUP
eb6b08eb 1497
4acd1e87
BP
1498AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1499AT_SKIP_IF([test $HAVE_PYTHON = no])
1500ovn_start
1501
1502# Create a logical switch and some logical ports.
1503# Turn on port security on all lports except ls1.
1504# Make ls1 a destination for unknown MACs.
1505# Add some ACLs for Ethertypes 1234, 1235, 1236.
1506ovn-nbctl ls-add lsw0
1507ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1508for i in 1 2 3; do
1509 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1510done
1511ovn-nbctl --wait=sb sync
1512for i in 1 2 3; do
4acd1e87
BP
1513 ovn-sbctl lsp-bind lp$i hv0
1514 if test $i = 1; then
abb37b6b 1515 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1516 else
abb37b6b
FF
1517 if test $i = 3; then
1518 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1519 else
1520 ip_addrs="192.168.0.$i"
1521 fi
a8e2addc
LR
1522 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1523 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
4acd1e87
BP
1524 fi
1525done
1526ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1527ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1528ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1529ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1530ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1531
1532ovn-nbctl --wait=sb sync
1533on_exit 'kill `cat ovn-trace.pid`'
1534ovn-trace --detach --pidfile --no-chdir
1535
1536# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1537#
1538# This shell function causes a packet to be received on INPORT. The packet's
1539# content has Ethernet destination DST and source SRC (each exactly 12 hex
1540# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1541# more) list the VIFs on which the packet should be received. INPORT and the
1542# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1543test_packet() {
1544 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1545 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1546 while :; do
abb37b6b
FF
1547 case $1 in # (
1548 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1549 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1550 *) break ;;
1551 esac
4acd1e87
BP
1552 done
1553 for outport; do
abb37b6b 1554 echo "output(\"lp$outport\");"
4acd1e87
BP
1555 done > expout
1556
1557 AT_CAPTURE_FILE([trace])
1558 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1559}
1560
1561# test_arp INPORT SHA SPA TPA [REPLY_HA]
1562#
1563# Causes a packet to be received on INPORT. The packet is an ARP
1564# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1565# it should be the hardware address of the target to expect to receive in an
1566# ARP reply; otherwise no reply is expected.
1567#
1568# INPORT is an logical switch port number, e.g. 11 for vif11.
1569# SHA and REPLY_HA are each 12 hex digits.
1570# SPA and TPA are each 8 hex digits.
1571test_arp() {
1572 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1573
1574 local request="inport == \"lp$inport\"
1575 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1576 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1577 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1578
1579 if test -z "$reply_ha"; then
1580 reply=
abb37b6b
FF
1581 local i
1582 for i in 1 2 3; do
1583 if test $i != $inport; then
1584 reply="${reply}output(\"lp$i\");
4acd1e87 1585"
abb37b6b
FF
1586 fi
1587 done
4acd1e87
BP
1588 else
1589 reply="\
1590eth.dst = $sha;
1591eth.src = $reply_ha;
1592arp.op = 2;
1593arp.tha = $sha;
1594arp.sha = $reply_ha;
1595arp.tpa = $spa;
1596arp.spa = $tpa;
1597output(\"lp$inport\");
1598"
1599 fi
1600
1601 AT_CAPTURE_FILE([trace])
1602 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1603}
1604
1605# Send packets between all pairs of source and destination ports:
1606#
1607# 1. Unicast packets are delivered to exactly one logical switch port
1608# (except that packets destined to their input ports are dropped).
1609#
1610# 2. Broadcast and multicast are delivered to all logical switch ports
1611# except the input port.
1612#
1613# 3. When port security is turned on, the switch drops packets from the wrong
1614# MAC address.
1615#
1616# 4. The switch drops all packets with a VLAN tag.
1617#
1618# 5. The switch drops all packets with a multicast source address. (This only
1619# affects behavior when port security is turned off, since otherwise port
1620# security would drop the packet anyway.)
1621#
1622# 6. The switch delivers packets with an unknown destination to logical
1623# switch ports with "unknown" among their MAC addresses (and port
1624# security disabled).
1625#
1626# 7. The switch drops unicast packets that violate an ACL.
1627#
1628# 8. The switch drops multicast and broadcast packets that violate an ACL.
1629#
9fcb6a18
BP
1630# 9. OVN generates responses to ARP requests for known IPs, except for
1631# requests from a port for the port's own IP.
4acd1e87
BP
1632#
1633# 10. No response to ARP requests for unknown IPs.
1634
1635for s in 1 2 3; do
1636 bcast=
1637 unknown=
1638 bacl2=
1639 bacl3=
1640 for d in 1 2 3; do
abb37b6b
FF
1641 echo
1642 echo "lp$s -> lp$d"
1643 if test $d != $s; then unicast=$d; else unicast=; fi
1644 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1645
1646 if test $d != $s && test $s = 1; then
1647 impersonate=$d
1648 else
1649 impersonate=
1650 fi
1651 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1652
1653 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1654 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1655 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1656 # Source of 1 or 2 and dest of 3 should be dropped
1657 # due to the 4th ACL that uses address_set(set1).
1658 acl4=
1659 else
1660 acl4=$d
1661 fi
1662
1663 #7, acl1 to acl4:
1664 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1665 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1666 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1667 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1668
1669 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1670 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1671
1672 if test $d != $s && test $d = 1; then
1673 unknown="$unknown $d"
1674 fi
1675 bcast="$bcast $unicast"
1676 bacl2="$bacl2 $acl2"
1677 bacl3="$bacl3 $acl3"
1678
1679 sip=192.168.0.$s
1680 tip=192.168.0.$d
1681 tip_unknown=11.11.11.11
9fcb6a18
BP
1682 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1683 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1684 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1685
1686 if test $d = 3; then
1687 # lp3 has an additional ip 192.169.0.[123]3.
1688 tip=192.169.0.$d
9fcb6a18 1689 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1690 fi
4acd1e87
BP
1691 done
1692
1693 # Broadcast and multicast.
1694 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1695 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1696 if test $s = 1; then
abb37b6b 1697 bcast_impersonate=$bcast
4acd1e87 1698 else
abb37b6b 1699 bcast_impersonate=
4acd1e87
BP
1700 fi
1701 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1702
1703 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1704
1705 #8, acl1 to acl3:
1706 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1707 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1708 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1709
1710 #8, acl1 to acl3:
1711 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1712 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1713 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1714done
1715
1716AT_CLEANUP
1717
7277bc83
RB
1718# 2 hypervisors, 4 logical ports per HV
1719# 2 locally attached networks (one flat, one vlan tagged over same device)
1720# 2 ports per HV on each network
e90aeb57 1721AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1722AT_SKIP_IF([test $HAVE_PYTHON = no])
1723ovn_start
1724
ea46a4e9
JP
1725# In this test cases we create 3 switches, all connected to same
1726# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1727# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1728# of VIF port name indicates the hypervisor it is bound to, e.g.
1729# lp23 means VIF 3 on hv2.
1730#
ea46a4e9 1731# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1732# - ls1:
1733# - untagged
ea46a4e9 1734# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1735#
1736# - ls2:
1737# - tagged with VLAN 101
ea46a4e9 1738# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1739# - ls3:
1740# - untagged
ea46a4e9 1741# - ports: lp15, lp25
0ee7f7f1 1742#
ea46a4e9 1743# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1744# physical network.
1745
1746for i in 1 2 3; do
ea46a4e9
JP
1747 ls_name=ls$i
1748 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1749 ln_port_name=ln$i
1750 if test $i -eq 2; then
ea46a4e9 1751 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1752 else
ea46a4e9 1753 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1754 fi
31ed1192
JP
1755 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1756 ovn-nbctl lsp-set-type $ln_port_name localnet
1757 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1758done
d79fc5f4 1759
69b72264
BP
1760# lsp_to_ls LSP
1761#
1762# Prints the name of the logical switch that contains LSP.
1763lsp_to_ls () {
1764 case $1 in dnl (
1765 lp?[[12]]) echo ls1 ;; dnl (
1766 lp?[[34]]) echo ls2 ;; dnl (
1767 lp?5) echo ls3 ;; dnl (
1768 *) AT_FAIL_IF([:]) ;;
1769 esac
1770}
1771
d79fc5f4
RB
1772net_add n1
1773for i in 1 2; do
1774 sim_add hv$i
1775 as hv$i
1776 ovs-vsctl add-br br-phys
1777 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1778 ovn_attach n1 br-phys 192.168.0.$i
1779
0ee7f7f1 1780 for j in 1 2 3 4 5; do
d79fc5f4
RB
1781 ovs-vsctl add-port br-int vif$i$j -- \
1782 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1783 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1784 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1785 ofport-request=$i$j
1786
31ed1192 1787 lsp_name=lp$i$j
69b72264 1788 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 1789
ea46a4e9 1790 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1791 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1792 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1793
31ed1192 1794 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1795 done
1796done
69b72264
BP
1797ovn-nbctl --wait=sb sync
1798ovn-sbctl dump-flows
d79fc5f4 1799
74868f2c 1800OVN_POPULATE_ARP
d79fc5f4
RB
1801
1802# XXX This is now the 3rd copy of these functions in this file ...
1803
1804# Given the name of a logical port, prints the name of the hypervisor
1805# on which it is located.
1806vif_to_hv() {
1807 echo hv${1%?}
1808}
1809#
69b72264 1810# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
1811#
1812# This shell function causes a packet to be received on INPORT. The packet's
1813# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
1814# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1815# logical switch port numbers, e.g. 11 for vif11.
1816#
1817# EOUT is the end-to-end output port, that is, where the packet will end up
1818# after possibly bouncing through one or more localnet ports. LOUT is the
1819# logical output port, which might be a localnet port, as seen by ovn-trace
1820# (which doesn't know what localnet ports are connected to and therefore can't
1821# figure out the end-to-end answer).
d79fc5f4 1822for i in 1 2; do
0ee7f7f1 1823 for j in 1 2 3 4 5; do
d79fc5f4
RB
1824 : > $i$j.expected
1825 done
1826done
1827test_packet() {
69b72264
BP
1828 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1829 echo "$@"
1830
1831 # First try tracing the packet.
1832 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1833 if test $lout != drop; then
1834 echo "output(\"$lout\");"
1835 fi > expout
1836 AT_CAPTURE_FILE([trace])
1837 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1838
1839 # Then actually send a packet, for an end-to-end test.
1840 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
1841 hv=`vif_to_hv $inport`
1842 vif=vif$inport
1843 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
1844 if test $eout != drop; then
1845 echo $packet >> ${eout#lp}.expected
1846 fi
d79fc5f4
RB
1847}
1848
7277bc83
RB
1849# lp11 and lp21 are on the same network (phys, untagged)
1850# and on different hypervisors
69b72264
BP
1851test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1852test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 1853
7277bc83
RB
1854# lp11 and lp12 are on the same network (phys, untagged)
1855# and on the same hypervisor
69b72264
BP
1856test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1857test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
1858
1859# lp13 and lp23 are on the same network (phys, VLAN 101)
1860# and on different hypervisors
69b72264
BP
1861test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1862test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
1863
1864# lp13 and lp14 are on the same network (phys, VLAN 101)
1865# and on the same hypervisor
69b72264
BP
1866test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1867test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 1868
0ee7f7f1 1869# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 1870# same hypervisor, and on different switches
69b72264
BP
1871test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1872test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
1873
1874# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 1875# different hypervisors, and on different switches
69b72264
BP
1876test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1877test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 1878
d79fc5f4 1879# Ports that should not be able to communicate
69b72264
BP
1880test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1881test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1882test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1883test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1884test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1885test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1886test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1887test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 1888
d79fc5f4
RB
1889# Dump a bunch of info helpful for debugging if there's a failure.
1890
1891echo "------ OVN dump ------"
1892ovn-nbctl show
1893ovn-sbctl show
1894
1895echo "------ hv1 dump ------"
1896as hv1 ovs-vsctl show
1897as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1898
1899echo "------ hv2 dump ------"
1900as hv2 ovs-vsctl show
1901as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1902
1903# Now check the packets actually received against the ones expected.
1904for i in 1 2; do
0ee7f7f1 1905 for j in 1 2 3 4 5; do
49d7c759 1906 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
1907 done
1908done
1909
7a8f15e0 1910OVN_CLEANUP([hv1],[hv2])
d9c8c57c 1911
d79fc5f4
RB
1912AT_CLEANUP
1913
91125642
FF
1914AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1915AT_KEYWORDS([vtep])
eb6b08eb
JP
1916AT_SKIP_IF([test $HAVE_PYTHON = no])
1917ovn_start
1918
1919# Configure the Northbound database
ea46a4e9 1920ovn-nbctl ls-add lsw0
eb6b08eb 1921
31ed1192
JP
1922ovn-nbctl lsp-add lsw0 lp1
1923ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 1924
31ed1192
JP
1925ovn-nbctl lsp-add lsw0 lp2
1926ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 1927
31ed1192
JP
1928ovn-nbctl lsp-add lsw0 lp-vtep
1929ovn-nbctl lsp-set-type lp-vtep vtep
1930ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1931ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 1932
77adbb62
DB
1933# lpr, lr and lrp1 are used for the ARP request handling test only.
1934ovn-nbctl lsp-add lsw0 lpr
1935ovn-nbctl lr-add lr
1936ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1937ovn-nbctl set Logical_Switch_Port lpr type=router \
1938 options:router-port=lrp1 \
1939 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1940
1941
eb6b08eb
JP
1942net_add n1 # Network to connect hv1, hv2, and vtep
1943net_add n2 # Network to connect vtep and hv3
1944
1945# Create hypervisor hv1 connected to n1
1946sim_add hv1
1947as hv1
1948ovs-vsctl add-br br-phys
1949ovn_attach n1 br-phys 192.168.0.1
1950ovs-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
1951
1952# Create hypervisor hv2 connected to n1
1953sim_add hv2
1954as hv2
1955ovs-vsctl add-br br-phys
1956ovn_attach n1 br-phys 192.168.0.2
1957ovs-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
1958
1959
1960# Start the vtep emulator with a leg in both networks
1961sim_add vtep
1962as vtep
1963
1964ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1965ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1966
1967ovs-vsctl add-br br-phys
1968net_attach n1 br-phys
1969
1970mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1971arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1972ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1973ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1974
1975ovs-vsctl add-br br-vtep
1976net_attach n2 br-vtep
1977
1978vtep-ctl add-ps br-vtep
1979vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1980vtep-ctl add-ls lsw0
1981
1982start_daemon ovs-vtep br-vtep
1983start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1984
8cdc4312 1985OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 1986
475f0a2c
DB
1987OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1988 grep -- source`"])
1989# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
1990sleep 1
1991
1992# Add hv3 on the other side of the vtep
1993sim_add hv3
1994as hv3
1995ovs-vsctl add-br br-phys
1996net_attach n2 br-phys
1997
1998ovs-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
1999
2000# Pre-populate the hypervisors' ARP tables so that we don't lose any
2001# packets for ARP resolution (native tunneling doesn't queue packets
2002# for ARP resolution).
74868f2c 2003OVN_POPULATE_ARP
eb6b08eb
JP
2004
2005# Allow some time for ovn-northd and ovn-controller to catch up.
2006# XXX This should be more systematic.
2007sleep 1
6977df72 2008
eb6b08eb
JP
2009# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2010#
2011# This shell function causes a packet to be received on INPORT. The packet's
2012# content has Ethernet destination DST and source SRC (each exactly 12 hex
2013# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2014# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2015# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
2016for i in 1 2 3; do
2017 : > $i.expected
2018done
2019test_packet() {
2020 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2021 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2022 hv=hv$inport
2023 vif=vif$inport
2024 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2025 for outport; do
e4543cfe 2026 echo $packet >> $outport.expected
eb6b08eb
JP
2027 done
2028}
2029
2030# Send packets between all pairs of source and destination ports:
2031#
31ed1192
JP
2032# 1. Unicast packets are delivered to exactly one logical switch port
2033# (except that packets destined to their input ports are dropped).
eb6b08eb 2034#
31ed1192
JP
2035# 2. Broadcast and multicast are delivered to all logical switch ports
2036# except the input port.
eb6b08eb 2037#
ea46a4e9 2038# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
2039# switch ports with "unknown" among their MAC addresses (and port
2040# security disabled).
eb6b08eb
JP
2041for s in 1 2 3; do
2042 bcast=
2043 unknown=
2044 for d in 1 2 3; do
2045 if test $d != $s; then unicast=$d; else unicast=; fi
2046 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2047
2048 # The vtep (vif3) is the only one configured for "unknown"
2049 if test $d != $s && test $d = 3; then
2050 unknown="$unknown $d"
2051 fi
2052 bcast="$bcast $unicast"
2053 done
2054
2055 # Broadcast and multicast.
46ed1382
DB
2056 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2057 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
2058
2059 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2060done
2061
77adbb62
DB
2062# ARP request should not be responded to by logical switch router
2063# type arp responder on HV1 and HV2 and should reach directly to
2064# vif1 and vif2
2065ip_to_hex() {
2066 printf "%02x%02x%02x%02x" "$@"
2067}
2068sha=f00000000003
2069spa=`ip_to_hex 192 168 1 2`
2070tpa=`ip_to_hex 192 168 1 1`
2071request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2072as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2073echo $request >> 1.expected
2074echo $request >> 2.expected
2075
bb0c41d3
RM
2076# dump information with counters
2077echo "------ OVN dump ------"
2078ovn-nbctl show
2079ovn-sbctl show
2080
77adbb62
DB
2081echo "---------SB dump-----"
2082ovn-sbctl list datapath_binding
2083echo "---------------------"
2084ovn-sbctl list port_binding
2085echo "---------------------"
2086ovn-sbctl dump-flows
2087
bb0c41d3
RM
2088echo "------ hv1 dump ------"
2089as hv1 ovs-vsctl show
6195e2e7 2090as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2091as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2092
2093echo "------ hv2 dump ------"
2094as hv2 ovs-vsctl show
6195e2e7 2095as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2096as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2097
2098echo "------ hv3 dump ------"
2099as hv3 ovs-vsctl show
6754e92d
FF
2100# note: hv3 has no logical port bind, thus it should not have br-int
2101AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2102[ovs-ofctl: br-int is not a bridge or a socket
2103])
bb0c41d3 2104
eb6b08eb
JP
2105# Now check the packets actually received against the ones expected.
2106for i in 1 2 3; do
49d7c759 2107 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 2108done
fcde56f5
LR
2109
2110# Gracefully terminate daemons
7a8f15e0
LR
2111OVN_CLEANUP([hv1],[hv2],[vtep])
2112OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 2113
eb6b08eb 2114AT_CLEANUP
9975d7be 2115
184bc3ca
RB
2116# Similar test to "hardware GW"
2117AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2118AT_SKIP_IF([test $HAVE_PYTHON = no])
2119ovn_start
2120
2121# Configure the Northbound database
2122ovn-nbctl ls-add lsw0
2123
2124ovn-nbctl lsp-add lsw0 lp1
2125ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2126
2127ovn-nbctl lsp-add lsw0 lp2
2128ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2129
2130ovn-nbctl lsp-add lsw0 lp-gw
2131ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 2132ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
2133ovn-nbctl lsp-set-addresses lp-gw unknown
2134
2135net_add n1 # Network to connect hv1, hv2, and gw
2136net_add n2 # Network to connect gw and hv3
2137
2138# Create hypervisor hv1 connected to n1
2139sim_add hv1
2140as hv1
2141ovs-vsctl add-br br-phys
2142ovn_attach n1 br-phys 192.168.0.1
2143ovs-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
2144
2145# Create hypervisor hv2 connected to n1
2146sim_add hv2
2147as hv2
2148ovs-vsctl add-br br-phys
2149ovn_attach n1 br-phys 192.168.0.2
2150ovs-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
2151
2152# Create hypervisor hv_gw connected to n1 and n2
2153# connect br-phys bridge to n1; connect hv-gw bridge to n2
2154sim_add hv_gw
2155as hv_gw
2156ovs-vsctl add-br br-phys
2157ovn_attach n1 br-phys 192.168.0.3
2158ovs-vsctl add-br br-phys2
2159net_attach n2 br-phys2
2160ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2161
184bc3ca
RB
2162# Add hv3 on the other side of the GW
2163sim_add hv3
2164as hv3
2165ovs-vsctl add-br br-phys
2166net_attach n2 br-phys
2167ovs-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
2168
2169
2170# Pre-populate the hypervisors' ARP tables so that we don't lose any
2171# packets for ARP resolution (native tunneling doesn't queue packets
2172# for ARP resolution).
74868f2c 2173OVN_POPULATE_ARP
184bc3ca
RB
2174
2175# Allow some time for ovn-northd and ovn-controller to catch up.
2176# XXX This should be more systematic.
2177sleep 1
2178
2179# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2180#
2181# This shell function causes a packet to be received on INPORT. The packet's
2182# content has Ethernet destination DST and source SRC (each exactly 12 hex
2183# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2184# more) list the VIFs on which the packet should be received. INPORT and the
2185# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
2186for i in 1 2 3; do
2187 : > $i.expected
2188done
2189test_packet() {
2190 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2191 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2192 hv=hv$inport
2193 vif=vif$inport
2194 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2195 for outport; do
e4543cfe 2196 echo $packet >> $outport.expected
184bc3ca
RB
2197 done
2198}
2199
2200# Send packets between all pairs of source and destination ports:
2201#
2202# 1. Unicast packets are delivered to exactly one lport (except that packets
2203# destined to their input ports are dropped).
2204#
2205# 2. Broadcast and multicast are delivered to all lports except the input port.
2206#
2207# 3. The lswitch delivers packets with an unknown destination to lports with
2208# "unknown" among their MAC addresses (and port security disabled).
2209for s in 1 2 3 ; do
2210 bcast=
2211 unknown=
2212 for d in 1 2 3 ; do
2213 if test $d != $s; then unicast=$d; else unicast=; fi
2214 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2215
2216 # The vtep (vif3) is the only one configured for "unknown"
2217 if test $d != $s && test $d = 3; then
2218 unknown="$unknown $d"
2219 fi
2220 bcast="$bcast $unicast"
2221 done
2222
2223 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2224 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2225 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2226done
2227
184bc3ca
RB
2228echo "------ ovn-nbctl show ------"
2229ovn-nbctl show
2230echo "------ ovn-sbctl show ------"
2231ovn-sbctl show
2232
2233echo "------ hv1 ------"
2234as hv1 ovs-vsctl show
2235echo "------ hv1 br-int ------"
2236as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2237echo "------ hv1 br-phys ------"
2238as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2239
2240echo "------ hv2 ------"
2241as hv2 ovs-vsctl show
2242echo "------ hv2 br-int ------"
2243as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2244echo "------ hv2 br-phys ------"
2245as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2246
2247echo "------ hv_gw ------"
2248as hv_gw ovs-vsctl show
2249echo "------ hv_gw br-phys ------"
2250as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2251echo "------ hv_gw br-phys2 ------"
2252as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2253
2254echo "------ hv3 ------"
2255as hv3 ovs-vsctl show
2256echo "------ hv3 br-phys ------"
2257as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2258
2259# Now check the packets actually received against the ones expected.
2260for i in 1 2 3; do
49d7c759 2261 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2262done
2263AT_CLEANUP
2264
9975d7be
BP
2265# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2266AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2267AT_SKIP_IF([test $HAVE_PYTHON = no])
2268ovn_start
2269
2270# Logical network:
2271#
2272# Three logical switches ls1, ls2, ls3.
86e98048
BP
2273# One logical router lr0 connected to ls[123],
2274# with nine subnets, three per logical switch:
2275#
2276# lrp11 on ls1 for subnet 192.168.11.0/24
2277# lrp12 on ls1 for subnet 192.168.12.0/24
2278# lrp13 on ls1 for subnet 192.168.13.0/24
2279# ...
2280# lrp33 on ls3 for subnet 192.168.33.0/24
2281#
2282# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2283# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2284for i in 1 2 3; do
ea46a4e9 2285 ovn-nbctl ls-add ls$i
9975d7be 2286 for j in 1 2 3; do
86e98048 2287 for k in 1 2 3; do
31ed1192
JP
2288 # Add "unknown" to MAC addresses for lp?11, so packets for
2289 # MAC-IP bindings discovered via ARP later have somewhere to go.
2290 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2291
2292 ovn-nbctl \
2293 -- lsp-add ls$i lp$i$j$k \
2294 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2295 192.168.$i$j.$k" $unknown
86e98048
BP
2296 done
2297 done
2298done
2299
fa2a27b2 2300ovn-nbctl lr-add lr0
86e98048
BP
2301for i in 1 2 3; do
2302 for j in 1 2 3; do
bf44c2cd 2303 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2304 ovn-nbctl \
31ed1192 2305 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2306 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2307 options:router-port=lrp$i$j \
86e98048 2308 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2309 done
2310done
2311
80f408f4 2312ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2313 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2314
9975d7be
BP
2315# Physical network:
2316#
2317# Three hypervisors hv[123].
86e98048
BP
2318# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2319# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2320# lp?3[123] all on hv3.
2321
9975d7be
BP
2322
2323# Given the name of a logical port, prints the name of the hypervisor
2324# on which it is located.
2325vif_to_hv() {
2326 case $1 in dnl (
86e98048
BP
2327 ?11) echo 1 ;; dnl (
2328 ?12 | ?21 | ?22) echo 2 ;; dnl (
2329 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2330 esac
2331}
2332
86e98048
BP
2333# Given the name of a logical port, prints the name of its logical router
2334# port, e.g. "vif_to_lrp 123" yields 12.
2335vif_to_lrp() {
2336 echo ${1%?}
2337}
2338
2339# Given the name of a logical port, prints the name of its logical
2340# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2341vif_to_ls() {
86e98048 2342 echo ${1%??}
e3393e3f
BP
2343}
2344
9975d7be
BP
2345net_add n1
2346for i in 1 2 3; do
2347 sim_add hv$i
2348 as hv$i
2349 ovs-vsctl add-br br-phys
2350 ovn_attach n1 br-phys 192.168.0.$i
2351done
2352for i in 1 2 3; do
2353 for j in 1 2 3; do
86e98048 2354 for k in 1 2 3; do
269ecccc
JP
2355 hv=`vif_to_hv $i$j$k`
2356 as hv$hv ovs-vsctl \
2357 -- add-port br-int vif$i$j$k \
2358 -- set Interface vif$i$j$k \
2359 external-ids:iface-id=lp$i$j$k \
2360 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2361 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2362 ofport-request=$i$j$k
86e98048 2363 done
9975d7be
BP
2364 done
2365done
2366
2367# Pre-populate the hypervisors' ARP tables so that we don't lose any
2368# packets for ARP resolution (native tunneling doesn't queue packets
2369# for ARP resolution).
74868f2c 2370OVN_POPULATE_ARP
9975d7be
BP
2371
2372# Allow some time for ovn-northd and ovn-controller to catch up.
2373# XXX This should be more systematic.
2374sleep 1
2375
e3393e3f 2376# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2377#
2378# This shell function causes a packet to be received on INPORT. The packet's
2379# content has Ethernet destination DST and source SRC (each exactly 12 hex
2380# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2381# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2382# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2383for i in 1 2 3; do
2384 for j in 1 2 3; do
86e98048
BP
2385 for k in 1 2 3; do
2386 : > $i$j$k.expected
269ecccc 2387 done
9975d7be
BP
2388 done
2389done
e3393e3f 2390test_ip() {
9975d7be
BP
2391 # This packet has bad checksums but logical L3 routing doesn't check.
2392 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2393 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2394 shift; shift; shift; shift; shift
2395 hv=hv`vif_to_hv $inport`
2396 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2397 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2398 in_ls=`vif_to_ls $inport`
2399 in_lrp=`vif_to_lrp $inport`
9975d7be 2400 for outport; do
269ecccc 2401 out_ls=`vif_to_ls $outport`
86e98048 2402 if test $in_ls = $out_ls; then
9975d7be
BP
2403 # Ports on the same logical switch receive exactly the same packet.
2404 echo $packet
2405 else
2406 # Routing decrements TTL and updates source and dest MAC
2407 # (and checksum).
269ecccc 2408 out_lrp=`vif_to_lrp $outport`
86e98048 2409 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2410 fi >> $outport.expected
9975d7be
BP
2411 done
2412}
2413
e3393e3f 2414as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2415as hv1 ovn-sbctl list port_binding
2416as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2417as hv1 ovn-sbctl dump-flows
2418as hv1 ovs-ofctl dump-flows br-int
2419
e3393e3f 2420# Send IP packets between all pairs of source and destination ports:
9975d7be 2421#
31ed1192
JP
2422# 1. Unicast IP packets are delivered to exactly one logical switch port
2423# (except that packets destined to their input ports are dropped).
9975d7be 2424#
31ed1192
JP
2425# 2. Broadcast IP packets are delivered to all logical switch ports
2426# except the input port.
86e98048
BP
2427ip_to_hex() {
2428 printf "%02x%02x%02x%02x" "$@"
2429}
9975d7be 2430for is in 1 2 3; do
269ecccc
JP
2431 for js in 1 2 3; do
2432 for ks in 1 2 3; do
2433 bcast=
2434 s=$is$js$ks
2435 smac=f00000000$s
2436 sip=`ip_to_hex 192 168 $is$js $ks`
2437 for id in 1 2 3; do
2438 for jd in 1 2 3; do
2439 for kd in 1 2 3; do
2440 d=$id$jd$kd
2441 dip=`ip_to_hex 192 168 $id$jd $kd`
2442 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2443 if test $d != $s; then unicast=$d; else unicast=; fi
2444
2445 test_ip $s $smac $dmac $sip $dip $unicast #1
2446
2447 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2448 done
2449 done
9975d7be 2450 done
269ecccc
JP
2451 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2452 done
2453 done
e3393e3f
BP
2454done
2455
0bac7164
BP
2456# 3. Send an IP packet from every logical port to every other subnet,
2457# to an IP address that does not have a static IP-MAC binding.
2458# This should generate a broadcast ARP request for the destination
2459# IP address in the destination subnet.
2460for is in 1 2 3; do
269ecccc
JP
2461 for js in 1 2 3; do
2462 for ks in 1 2 3; do
2463 s=$is$js$ks
2464 smac=f00000000$s
2465 sip=`ip_to_hex 192 168 $is$js $ks`
2466 for id in 1 2 3; do
2467 for jd in 1 2 3; do
2468 if test $is$js = $id$jd; then
2469 continue
2470 fi
2471
2472 # Send the packet.
2473 dmac=00000000ff$is$js
2474 # Calculate a 4th octet for the destination that is
2475 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2476 # that have static MAC bindings, and fits in the range
2477 # 0-255.
2478 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2479 dip=`ip_to_hex 192 168 $id$jd $o4`
2480 test_ip $s $smac $dmac $sip $dip
2481
2482 # Every LP on the destination subnet's lswitch should
2483 # receive the ARP request.
2484 lrmac=00000000ff$id$jd
2485 lrip=`ip_to_hex 192 168 $id$jd 254`
2486 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2487 for jd2 in 1 2 3; do
2488 for kd in 1 2 3; do
e4543cfe 2489 echo $arp >> $id$jd2$kd.expected
0bac7164 2490 done
269ecccc 2491 done
0bac7164 2492 done
269ecccc 2493 done
0bac7164 2494 done
269ecccc 2495 done
0bac7164
BP
2496done
2497
e3393e3f
BP
2498# test_arp INPORT SHA SPA TPA [REPLY_HA]
2499#
2500# Causes a packet to be received on INPORT. The packet is an ARP
2501# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2502# it should be the hardware address of the target to expect to receive in an
2503# ARP reply; otherwise no reply is expected.
2504#
31ed1192 2505# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2506# SHA and REPLY_HA are each 12 hex digits.
2507# SPA and TPA are each 8 hex digits.
2508test_arp() {
2509 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2510 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2511 hv=hv`vif_to_hv $inport`
2512 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2d9b49dd 2513 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
e3393e3f 2514
57d143eb 2515 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2516 # IP address is not configured to the switch patch port.
e3393e3f 2517 local i=`vif_to_ls $inport`
86e98048 2518 local j k
e3393e3f 2519 for j in 1 2 3; do
86e98048 2520 for k in 1 2 3; do
ea46a4e9 2521 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2522 # so no ARP flooding expected for it.
2523 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2524 echo $request >> $i$j$k.expected
2525 fi
2526 done
e3393e3f
BP
2527 done
2528
2529 # Expect to receive the reply, if any.
2530 if test X$reply_ha != X; then
86e98048
BP
2531 lrp=`vif_to_lrp $inport`
2532 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2533 echo $reply >> $inport.expected
2534 fi
2535}
2536
2537# Test router replies to ARP requests from all source ports:
2538#
0bac7164 2539# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2540#
0bac7164 2541# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2542# in its subnet.
2543#
0bac7164 2544# 6. Router replies to query for its MAC address from another subnet.
e3393e3f 2545#
0bac7164 2546# 7. No reply to query for IP address other than router IP.
e3393e3f 2547for i in 1 2 3; do
269ecccc
JP
2548 for j in 1 2 3; do
2549 for k in 1 2 3; do
2550 smac=f00000000$i$j$k # Source MAC
2551 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2552 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2553 rmac=00000000ff$i$j # Router MAC
2554 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2555 test_arp $i$j$k $smac $sip $rip $rmac #4
2556 test_arp $i$j$k $smac $otherip $rip $rmac #5
2557 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2558 test_arp $i$j$k $smac $sip $otherip #7
0bac7164 2559 done
269ecccc 2560 done
0bac7164
BP
2561done
2562
2563# Allow some time for packet forwarding.
2564# XXX This can be improved.
2565sleep 1
2566
2567# 8. Generate an ARP reply for each of the IP addresses ARPed for
2568# earlier as #3.
2569#
2570# Here, the $s is the VIF that originated the ARP request and $d is
2571# the VIF that sends the ARP reply, which is somewhat backward but
2572# it means that $s and $d are the same as #3.
2573: > mac_bindings.expected
2574for is in 1 2 3; do
269ecccc
JP
2575 for js in 1 2 3; do
2576 for ks in 1 2 3; do
2577 s=$is$js$ks
2578 for id in 1 2 3; do
2579 for jd in 1 2 3; do
2580 if test $is$js = $id$jd; then
2581 continue
2582 fi
2583
2584 kd=1
2585 d=$id$jd$kd
2586
2587 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2588 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2589 host_mac=8000000000$o4
2590
2591 lrmac=00000000ff$id$jd
2592 lrip=`ip_to_hex 192 168 $id$jd 254`
2593
2594 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2595
2596 echo
2597 echo
2598 echo
2599 hv=hv`vif_to_hv $d`
2600 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2601 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2602 #as $hv ovs-ofctl dump-flows br-int table=19
2603
2604 host_ip_pretty=192.168.$id$jd.$o4
2605 host_mac_pretty=80:00:00:00:00:$o4
2606 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2607 done
269ecccc 2608 done
9975d7be 2609 done
269ecccc 2610 done
9975d7be 2611done
0bac7164 2612
9975d7be
BP
2613# Allow some time for packet forwarding.
2614# XXX This can be improved.
2615sleep 1
2616
0bac7164
BP
2617# 9. Send an IP packet from every logical port to every other subnet. These
2618# are the same packets already sent as #3, but now the destinations' IP-MAC
2619# bindings have been discovered via ARP, so instead of provoking an ARP
2620# request, these packets now get routed to their destinations (which don't
2621# have static MAC bindings, so they go to the port we've designated as
2622# accepting "unknown" MACs.)
2623for is in 1 2 3; do
269ecccc
JP
2624 for js in 1 2 3; do
2625 for ks in 1 2 3; do
2626 s=$is$js$ks
2627 smac=f00000000$s
2628 sip=`ip_to_hex 192 168 $is$js $ks`
2629 for id in 1 2 3; do
2630 for jd in 1 2 3; do
2631 if test $is$js = $id$jd; then
2632 continue
2633 fi
2634
2635 # Send the packet.
2636 dmac=00000000ff$is$js
2637 # Calculate a 4th octet for the destination that is
2638 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2639 # that have static MAC bindings, and fits in the range
2640 # 0-255.
2641 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2642 dip=`ip_to_hex 192 168 $id$jd $o4`
2643 test_ip $s $smac $dmac $sip $dip
2644
2645 # Expect the packet egress.
2646 host_mac=8000000000$o4
2647 outport=${id}11
2648 out_lrp=$id$jd
e4543cfe 2649 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2650 done
269ecccc 2651 done
0bac7164 2652 done
269ecccc 2653 done
0bac7164
BP
2654done
2655
0bac7164
BP
2656ovn-sbctl -f csv -d bare --no-heading \
2657 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2658
9975d7be
BP
2659# Now check the packets actually received against the ones expected.
2660for i in 1 2 3; do
2661 for j in 1 2 3; do
86e98048 2662 for k in 1 2 3; do
abb37b6b
FF
2663 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2664 [$i$j$k.expected])
86e98048 2665 done
9975d7be
BP
2666 done
2667done
fcde56f5 2668
0bac7164
BP
2669# Check the MAC bindings against those expected.
2670AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2671])
2672
fcde56f5 2673# Gracefully terminate daemons
7a8f15e0 2674OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2675
9975d7be 2676AT_CLEANUP
685f4dfe
NS
2677
2678# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2679AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
2680AT_SKIP_IF([test $HAVE_PYTHON = no])
2681ovn_start
2682
2683# Create hypervisors hv[123].
2684# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2685# Add all of the vifs to a single logical switch lsw0.
2686# Turn off port security on vifs vif[123]1
2687# Turn on l2 port security on vifs vif[123]2
2688# Turn of l2 and l3 port security on vifs vif[123]3
2689# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 2690ovn-nbctl ls-add lsw0
685f4dfe
NS
2691net_add n1
2692for i in 1 2 3; do
2693 sim_add hv$i
2694 as hv$i
2695 ovs-vsctl add-br br-phys
2696 ovn_attach n1 br-phys 192.168.0.$i
2697
2698 for j in 1 2 3; do
2699 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 2700 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 2701 if test $j = 1; then
31ed1192 2702 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 2703 elif test $j = 2; then
31ed1192
JP
2704 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2705 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
2706 else
2707 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
2708 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2709 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
2710 fi
2711 done
2712done
2713
685f4dfe
NS
2714# Pre-populate the hypervisors' ARP tables so that we don't lose any
2715# packets for ARP resolution (native tunneling doesn't queue packets
2716# for ARP resolution).
74868f2c 2717OVN_POPULATE_ARP
685f4dfe
NS
2718
2719# Allow some time for ovn-northd and ovn-controller to catch up.
2720# XXX This should be more systematic.
2721sleep 1
685f4dfe
NS
2722
2723# Given the name of a logical port, prints the name of the hypervisor
2724# on which it is located.
2725vif_to_hv() {
2726 echo hv${1%?}
2727}
2728
685f4dfe
NS
2729for i in 1 2 3; do
2730 for j in 1 2 3; do
2731 : > $i$j.expected
2732 done
2733done
2734
2735# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2736#
2737# This shell function causes an ip packet to be received on INPORT.
2738# The packet's content has Ethernet destination DST and source SRC
2739# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2740# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2741# be received. INPORT and the OUTPORTs are specified as logical switch
2742# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2743test_ip() {
2744 # This packet has bad checksums but logical L3 routing doesn't check.
2745 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 2746 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
2747 shift; shift; shift; shift; shift
2748 hv=`vif_to_hv $inport`
2749 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2750 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2751 for outport; do
e4543cfe 2752 echo $packet >> $outport.expected
685f4dfe
NS
2753 done
2754}
2755
2756# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2757#
2758# Causes a packet to be received on INPORT. The packet is an ARP
2759# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2760# it should be the hardware address of the target to expect to receive in an
2761# ARP reply; otherwise no reply is expected.
2762#
31ed1192 2763# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2764# SHA and REPLY_HA are each 12 hex digits.
2765# SPA and TPA are each 8 hex digits.
2766test_arp() {
2767 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2768 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2769 hv=`vif_to_hv $inport`
2770 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2771 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2772 if test $drop != 1; then
e137131a 2773 if test X$reply_ha = X; then
685f4dfe
NS
2774 # Expect to receive the broadcast ARP on the other logical switch ports
2775 # if no reply is expected.
2776 local i j
2777 for i in 1 2 3; do
2778 for j in 1 2 3; do
2779 if test $i$j != $inport; then
2780 echo $request >> $i$j.expected
2781 fi
2782 done
2783 done
2784 else
2785 # Expect to receive the reply, if any.
2786 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2787 echo $reply >> $inport.expected
2788 fi
2789 fi
2790}
2791
2792# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2793# This function is similar to test_ip() except that it sends
2794# ipv6 packet
2795test_ipv6() {
2796 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2797 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2798 shift; shift; shift; shift; shift
2799 hv=`vif_to_hv $inport`
2800 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2801 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2802 for outport; do
e4543cfe 2803 echo $packet >> $outport.expected
685f4dfe
NS
2804 done
2805}
2806
9e687b23
DL
2807# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2808# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2809# of the test packet
2810test_icmpv6() {
2811 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2812 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2813 shift; shift; shift; shift; shift; shift
2814 hv=`vif_to_hv $inport`
2815 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2816 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2817 for outport; do
e4543cfe 2818 echo $packet >> $outport.expected
9e687b23
DL
2819 done
2820}
2821
685f4dfe
NS
2822ip_to_hex() {
2823 printf "%02x%02x%02x%02x" "$@"
2824}
2825
2826# no port security
2827sip=`ip_to_hex 192 168 0 12`
2828tip=`ip_to_hex 192 168 0 13`
2829# the arp packet should be allowed even if lp[123]1 is
2830# not configured with mac f00000000023 and ip 192.168.0.12
2831for i in 1 2 3; do
2832 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2833 for j in 1 2 3; do
2834 if test $i != $j; then
2835 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2836 fi
2837 done
2838done
2839
2840# l2 port security
2841sip=`ip_to_hex 192 168 0 12`
2842tip=`ip_to_hex 192 168 0 13`
2843
2844# arp packet should be allowed since lp22 is configured with
2845# mac f00000000022
2846test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2847
2848# arp packet should not be allowed since lp32 is not configured with
2849# mac f00000000021
2850test_arp 32 f00000000021 f00000000021 $sip $tip 1
2851
2852# arp packet with sha set to f00000000021 should not be allowed
2853# for lp12
2854test_arp 12 f00000000012 f00000000021 $sip $tip 1
2855
2856# ip packets should be allowed and received since lp[123]2 do not
2857# have l3 port security
2858sip=`ip_to_hex 192 168 0 55`
2859tip=`ip_to_hex 192 168 0 66`
2860for i in 1 2 3; do
2861 for j in 1 2 3; do
2862 if test $i != $j; then
2863 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2864 fi
2865 done
2866done
2867
2868# ipv6 packets should be received by lp[123]2
2869# lp[123]1 can send ipv6 traffic as there is no port security
2870sip=fe800000000000000000000000000000
2871tip=ff020000000000000000000000000000
2872
2873for i in 1 2 3; do
2874 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2875done
2876
2877
2878# l2 and l3 port security
2879sip=`ip_to_hex 192 168 0 13`
2880tip=`ip_to_hex 192 168 0 22`
2881# arp packet should be allowed since lp13 is configured with
2882# f00000000013 and 192.168.0.13
2883test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2884
2885# the arp packet should be dropped because lp23 is not configured
2886# with mac f00000000022
2887sip=`ip_to_hex 192 168 0 13`
2888tip=`ip_to_hex 192 168 0 22`
2889test_arp 23 f00000000022 f00000000022 $sip $tip 1
2890
2891# the arp packet should be dropped because lp33 is not configured
2892# with ip 192.168.0.55
2893spa=`ip_to_hex 192 168 0 55`
2894tpa=`ip_to_hex 192 168 0 22`
2895test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2896
2897# ip packets should not be received by lp[123]3 since
2898# l3 port security is enabled
2899sip=`ip_to_hex 192 168 0 55`
2900tip=`ip_to_hex 192 168 0 66`
2901for i in 1 2 3; do
2902 for j in 1 2 3; do
2903 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2904 done
2905done
2906
2907# ipv6 packets should be dropped for lp[123]3 since
2908# it is configured with only ipv4 address
2909sip=fe800000000000000000000000000000
2910tip=ff020000000000000000000000000000
2911
2912for i in 1 2 3; do
2913 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2914done
2915
2916# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2917# lp[123]1 can send ipv6 traffic as there is no port security
2918for i in 1 2 3; do
2919 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2920done
2921
2922# lp13 has extra port security with mac f0000000113 and ipv6 addr
2923# fe80::ea2a:eaff:fe28:0012
2924
2925# ipv4 packet should be dropped for lp13 with mac f0000000113
2926sip=`ip_to_hex 192 168 0 13`
2927tip=`ip_to_hex 192 168 0 23`
2928test_ip 13 f00000000113 f00000000023 $sip $tip
2929
6d53e8a9
BP
2930# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2931# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
2932# lp11 can send ipv6 traffic as there is no port security
2933sip=ee800000000000000000000000000000
2934for i in 1 2 3; do
6d53e8a9
BP
2935 tip=fe80000000000000ea2aeafffe2800${i}3
2936 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
2937done
2938
2939
2940# ipv6 packet should not be received by lp33 with mac f0000000333
2941# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2942# configured with fe80::ea2a:eaff:fe28:0033
2943# lp11 can send ipv6 traffic as there is no port security
2944
2945sip=ee800000000000000000000000000000
2946tip=fe80000000000000ea2aeafffe280023
2947test_ipv6 11 f00000000011 f00000000333 $sip $tip
2948
6d53e8a9
BP
2949# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2950# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
2951# and should be dropped for any other ip6.src
2952# lp21 can receive ipv6 traffic as there is no port security
2953
2954tip=ee800000000000000000000000000000
2955for i in 1 2 3; do
2956 sip=fe80000000000000ea2aeafffe2800${i}3
2957 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2958
9e687b23 2959 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 2960 sip=00000000000000000000000000000000
9e687b23
DL
2961 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2962 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2963 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2964 # Traffic to non-multicast traffic should be dropped
2965 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2966 # Traffic of other ICMPv6 types should be dropped
2967 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
2968
2969 # should be dropped
2970 sip=ae80000000000000ea2aeafffe2800aa
2971 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2972done
2973
31ed1192
JP
2974# configure lsp13 to send and received IPv4 packets with an address range
2975ovn-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 2976
8ff5a966
NS
2977sleep 2
2978
7d9d86ad
NS
2979sip=`ip_to_hex 10 0 0 13`
2980tip=`ip_to_hex 192 168 0 22`
31ed1192 2981# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
2982test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2983
2984sip=`ip_to_hex 10 0 0 14`
2985tip=`ip_to_hex 192 168 0 23`
31ed1192 2986# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
2987# with dst ip 192.168.0.23 should be allowed
2988test_ip 13 f00000000013 f00000000023 $sip $tip 23
2989
2990sip=`ip_to_hex 192 168 0 33`
2991tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
2992# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2993# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
2994test_ip 33 f00000000033 f00000000013 $sip $tip 13
2995
2996sip=`ip_to_hex 192 168 0 33`
2997tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
2998# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2999# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
3000test_ip 33 f00000000033 f00000000013 $sip $tip 13
3001
3002sip=`ip_to_hex 192 168 0 33`
3003tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
3004# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3005# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
3006test_ip 33 f00000000033 f00000000013 $sip $tip
3007
3008sip=`ip_to_hex 192 168 0 33`
3009tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
3010# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3011# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
3012test_ip 33 f00000000033 f00000000013 $sip $tip 13
3013
3014sip=`ip_to_hex 192 168 0 33`
3015tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
3016# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3017# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
3018test_ip 33 f00000000033 f00000000013 $sip $tip
3019
3020sip=`ip_to_hex 192 168 0 33`
3021tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
3022# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3023# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 3024test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 3025
bb0c41d3
RM
3026#dump information including flow counters
3027ovn-nbctl show
3028ovn-sbctl dump-flows -- list multicast_group
3029
3030echo "------ hv1 dump ------"
3031as hv1 ovs-vsctl show
6195e2e7 3032as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3033as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3034
3035echo "------ hv2 dump ------"
3036as hv2 ovs-vsctl show
6195e2e7 3037as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3038as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3039
3040echo "------ hv3 dump ------"
3041as hv3 ovs-vsctl show
6195e2e7 3042as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3043as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3044
685f4dfe
NS
3045# Now check the packets actually received against the ones expected.
3046for i in 1 2 3; do
3047 for j in 1 2 3; do
49d7c759 3048 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
3049 done
3050done
3051
7a8f15e0 3052OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 3053
685f4dfe 3054AT_CLEANUP
509afdc3
GS
3055
3056AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
3057AT_SKIP_IF([test $HAVE_PYTHON = no])
3058ovn_start
3059
3060# Logical network:
3061# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3062# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3063# R2 has ls2 (172.16.1.0/24) connected to it.
3064
3c1ae70a
JP
3065ls1_lp1_mac="f0:00:00:01:02:03"
3066rp_ls1_mac="00:00:00:01:02:03"
3067rp_ls2_mac="00:00:00:01:02:04"
3068ls2_lp1_mac="f0:00:00:01:02:04"
3069
3070ls1_lp1_ip="192.168.1.2"
3071ls2_lp1_ip="172.16.1.2"
3072
fa2a27b2
JP
3073ovn-nbctl lr-add R1
3074ovn-nbctl lr-add R2
509afdc3 3075
ea46a4e9
JP
3076ovn-nbctl ls-add ls1
3077ovn-nbctl ls-add ls2
509afdc3
GS
3078
3079# Connect ls1 to R1
3c1ae70a 3080ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
509afdc3 3081
31ed1192 3082ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3c1ae70a 3083 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
509afdc3
GS
3084
3085# Connect ls2 to R2
3c1ae70a 3086ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
509afdc3 3087
31ed1192 3088ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3c1ae70a 3089 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
509afdc3
GS
3090
3091# Connect R1 to R2
4685e523
JP
3092ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3093ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 3094
6d9ecfa9
JP
3095ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3096ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
3097
3098# Create logical port ls1-lp1 in ls1
31ed1192 3099ovn-nbctl lsp-add ls1 ls1-lp1 \
3c1ae70a 3100-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
509afdc3
GS
3101
3102# Create logical port ls2-lp1 in ls2
31ed1192 3103ovn-nbctl lsp-add ls2 ls2-lp1 \
3c1ae70a 3104-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
509afdc3
GS
3105
3106# Create two hypervisor and create OVS ports corresponding to logical ports.
3107net_add n1
3108
3109sim_add hv1
3110as hv1
3111ovs-vsctl add-br br-phys
3112ovn_attach n1 br-phys 192.168.0.1
3113ovs-vsctl -- add-port br-int hv1-vif1 -- \
3114 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3115 options:tx_pcap=hv1/vif1-tx.pcap \
3116 options:rxq_pcap=hv1/vif1-rx.pcap \
3117 ofport-request=1
3118
3119sim_add hv2
3120as hv2
3121ovs-vsctl add-br br-phys
3122ovn_attach n1 br-phys 192.168.0.2
3123ovs-vsctl -- add-port br-int hv2-vif1 -- \
3124 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3125 options:tx_pcap=hv2/vif1-tx.pcap \
3126 options:rxq_pcap=hv2/vif1-rx.pcap \
3127 ofport-request=1
3128
3129
3130# Pre-populate the hypervisors' ARP tables so that we don't lose any
3131# packets for ARP resolution (native tunneling doesn't queue packets
3132# for ARP resolution).
74868f2c 3133OVN_POPULATE_ARP
509afdc3
GS
3134
3135# Allow some time for ovn-northd and ovn-controller to catch up.
3136# XXX This should be more systematic.
3137sleep 1
3138
509afdc3 3139# Packet to send.
3c1ae70a
JP
3140packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3141 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3142 udp && udp.src==53 && udp.dst==4369"
3143as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
509afdc3
GS
3144
3145
3146echo "---------NB dump-----"
3147ovn-nbctl show
3148echo "---------------------"
3149ovn-nbctl list logical_router
3150echo "---------------------"
3151ovn-nbctl list logical_router_port
3152echo "---------------------"
3153
3154echo "---------SB dump-----"
3155ovn-sbctl list datapath_binding
3156echo "---------------------"
3157ovn-sbctl list port_binding
3158echo "---------------------"
3159
3160echo "------ hv1 dump ----------"
8dab1022 3161as hv1 ovs-ofctl show br-int
509afdc3
GS
3162as hv1 ovs-ofctl dump-flows br-int
3163echo "------ hv2 dump ----------"
8dab1022 3164as hv2 ovs-ofctl show br-int
509afdc3
GS
3165as hv2 ovs-ofctl dump-flows br-int
3166
3167# Packet to Expect
3c1ae70a
JP
3168# The TTL should be decremented by 2.
3169packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3170 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3171 udp && udp.src==53 && udp.dst==4369"
3172echo $packet | ovstest test-ovn expr-to-packets > expected
509afdc3 3173
49d7c759 3174OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 3175
7ebfcd3d
NS
3176AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3177grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3178])
3179
3180# Disable the ls2-lp1 port.
3181ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3182
3183AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3184grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3185])
3186
3187# Generate the packet destined for ls2-lp1 and it should not be delivered.
3188# Packet to send.
3189packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3190 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3191 udp && udp.src==53 && udp.dst==4369"
3192
3193as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3194# The 2nd packet sent shound not be received.
3195OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3196
7a8f15e0 3197OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
3198
3199AT_CLEANUP
5412db30
J
3200
3201
4685e523
JP
3202AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3203AT_KEYWORDS([router-admin-state])
3204AT_SKIP_IF([test $HAVE_PYTHON = no])
3205ovn_start
3206
3207# Logical network:
3208# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3209# and 172.16.1.0/24) connected to it.
3210
3211ovn-nbctl lr-add R1
3212
3213ovn-nbctl ls-add ls1
3214
3215# Connect ls1 to R1
bf44c2cd 3216ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
3217ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3218 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3219
3220# Create logical port ls1-lp1 in ls1
3221ovn-nbctl lsp-add ls1 ls1-lp1 \
3222 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3223
3224# Create logical port ls1-lp2 in ls1
3225ovn-nbctl lsp-add ls1 ls1-lp2 \
3226 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3227
3228# Create one hypervisor and create OVS ports corresponding to logical ports.
3229net_add n1
3230
3231sim_add hv1
3232as hv1
3233ovs-vsctl add-br br-phys
3234ovn_attach n1 br-phys 192.168.0.1
3235ovs-vsctl -- add-port br-int vif1 -- \
3236 set interface vif1 external-ids:iface-id=ls1-lp1 \
3237 options:tx_pcap=hv1/vif1-tx.pcap \
3238 options:rxq_pcap=hv1/vif1-rx.pcap \
3239 ofport-request=1
3240
3241ovs-vsctl -- add-port br-int vif2 -- \
3242 set interface vif2 external-ids:iface-id=ls1-lp2 \
3243 options:tx_pcap=hv1/vif2-tx.pcap \
3244 options:rxq_pcap=hv1/vif2-rx.pcap \
3245 ofport-request=1
3246
3247
3248# Allow some time for ovn-northd and ovn-controller to catch up.
3249# XXX This should be more systematic.
3250sleep 1
3251
3252# Send ip packets between the two ports.
3253ip_to_hex() {
3254 printf "%02x%02x%02x%02x" "$@"
3255}
4685e523
JP
3256
3257# Packet to send.
3258src_mac="f00000010203"
3259dst_mac="000000010203"
3260src_ip=`ip_to_hex 192 168 1 2`
3261dst_ip=`ip_to_hex 172 16 1 2`
3262packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3263as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3264
3265
3266echo "---------NB dump-----"
3267ovn-nbctl show
3268echo "---------------------"
3269ovn-nbctl list logical_router
3270echo "---------------------"
3271ovn-nbctl list logical_router_port
3272echo "---------------------"
3273
3274echo "---------SB dump-----"
3275ovn-sbctl list datapath_binding
3276echo "---------------------"
3277ovn-sbctl list logical_flow
3278echo "---------------------"
3279
3280echo "------ hv1 dump ----------"
3281as hv1 ovs-ofctl dump-flows br-int
3282
3283
3284#Disable router R1
3285ovn-nbctl set Logical_Router R1 enabled=false
3286
3b8cd0ea
BP
3287# Allow some time for ovn-northd and ovn-controller to catch up.
3288# XXX This should be more systematic.
3289sleep 1
3290
4685e523
JP
3291echo "---------SB dump-----"
3292ovn-sbctl list datapath_binding
3293echo "---------------------"
3294ovn-sbctl list logical_flow
3295echo "---------------------"
3296
3297echo "------ hv1 dump ----------"
3298as hv1 ovs-ofctl dump-flows br-int
3299
3300as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3301
3302# Packet to Expect
3303expect_src_mac="000000010203"
3304expect_dst_mac="f00000010204"
49d7c759 3305echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3306
49d7c759 3307OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
3308
3309
3310as hv1
3311OVS_APP_EXIT_AND_WAIT([ovn-controller])
3312OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3313OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3314
3315as ovn-sb
3316OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3317
3318as ovn-nb
3319OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3320
3321as northd
3322OVS_APP_EXIT_AND_WAIT([ovn-northd])
3323
3324as main
3325OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3326OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3327
3328AT_CLEANUP
3329
3330
3331AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3332AT_KEYWORDS([router-admin-state])
3333AT_SKIP_IF([test $HAVE_PYTHON = no])
3334ovn_start
3335
3336# Logical network:
3337# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3338# and has switch ls2 (172.16.1.0/24) connected to it.
3339
fa2a27b2 3340ovn-nbctl lr-add R1
5412db30 3341
ea46a4e9
JP
3342ovn-nbctl ls-add ls1
3343ovn-nbctl ls-add ls2
5412db30
J
3344
3345# Connect ls1 to R1
bf44c2cd 3346ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3347ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3348 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3349
3350# Connect ls2 to R1
bf44c2cd 3351ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3352ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3353 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3354
3355# Create logical port ls1-lp1 in ls1
31ed1192
JP
3356ovn-nbctl lsp-add ls1 ls1-lp1 \
3357-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3358
3359# Create logical port ls2-lp1 in ls2
31ed1192
JP
3360ovn-nbctl lsp-add ls2 ls2-lp1 \
3361-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3362
3363# Create one hypervisor and create OVS ports corresponding to logical ports.
3364net_add n1
3365
3366sim_add hv1
3367as hv1
3368ovs-vsctl add-br br-phys
3369ovn_attach n1 br-phys 192.168.0.1
3370ovs-vsctl -- add-port br-int vif1 -- \
3371 set interface vif1 external-ids:iface-id=ls1-lp1 \
3372 options:tx_pcap=hv1/vif1-tx.pcap \
3373 options:rxq_pcap=hv1/vif1-rx.pcap \
3374 ofport-request=1
3375
3376ovs-vsctl -- add-port br-int vif2 -- \
3377 set interface vif2 external-ids:iface-id=ls2-lp1 \
3378 options:tx_pcap=hv1/vif2-tx.pcap \
3379 options:rxq_pcap=hv1/vif2-rx.pcap \
3380 ofport-request=1
3381
3382
3383# Allow some time for ovn-northd and ovn-controller to catch up.
3384# XXX This should be more systematic.
3385sleep 1
3386
3387# Send ip packets between the two ports.
3388ip_to_hex() {
3389 printf "%02x%02x%02x%02x" "$@"
3390}
5412db30
J
3391
3392# Packet to send.
3393src_mac="f00000010203"
3394dst_mac="000000010203"
3395src_ip=`ip_to_hex 192 168 1 2`
3396dst_ip=`ip_to_hex 172 16 1 2`
3397packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3398as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3399
3400
3401echo "---------NB dump-----"
3402ovn-nbctl show
3403echo "---------------------"
3404ovn-nbctl list logical_router
3405echo "---------------------"
3406ovn-nbctl list logical_router_port
3407echo "---------------------"
3408
3409echo "---------SB dump-----"
3410ovn-sbctl list datapath_binding
3411echo "---------------------"
3412ovn-sbctl list logical_flow
3413echo "---------------------"
3414
3415echo "------ hv1 dump ----------"
3416as hv1 ovs-ofctl dump-flows br-int
3417
5412db30
J
3418#Disable router R1
3419ovn-nbctl set Logical_Router R1 enabled=false
3420
3421echo "---------SB dump-----"
3422ovn-sbctl list datapath_binding
3423echo "---------------------"
3424ovn-sbctl list logical_flow
3425echo "---------------------"
3426
3427echo "------ hv1 dump ----------"
3428as hv1 ovs-ofctl dump-flows br-int
3429
a1361a6e
LR
3430# Allow some time for the disabling of logical router R1 to propagate.
3431# XXX This should be more systematic.
3432sleep 1
3433
5412db30
J
3434as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3435
3436# Packet to Expect
3437expect_src_mac="000000010204"
3438expect_dst_mac="f00000010204"
49d7c759 3439echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3440
49d7c759 3441OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3442
7a8f15e0 3443OVN_CLEANUP([hv1])
5412db30
J
3444
3445AT_CLEANUP
3446
28dc3fe9 3447AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3448AT_SKIP_IF([test $HAVE_PYTHON = no])
3449ovn_start
3450
3451# Logical network:
3452# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3453# network. R1 has switchess foo (192.168.1.0/24)
3454# connected to it.
3455# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3456
fa2a27b2
JP
3457ovn-nbctl lr-add R1
3458ovn-nbctl lr-add R2
28dc3fe9 3459
ea46a4e9
JP
3460ovn-nbctl ls-add foo
3461ovn-nbctl ls-add alice
3462ovn-nbctl ls-add bob
28dc3fe9
SR
3463
3464# Connect foo to R1
bf44c2cd 3465ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3466ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3467 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3468
3469# Connect alice to R2
bf44c2cd 3470ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3471ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3472 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3473
3474# Connect bob to R2
bf44c2cd 3475ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3476ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3477 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3478
3479# Connect R1 to R2
4685e523
JP
3480ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3481ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3482
3483#install static routes
e48ccf3c
JP
3484ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3485ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3486ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3487
3488# Create logical port foo1 in foo
31ed1192
JP
3489ovn-nbctl lsp-add foo foo1 \
3490-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3491
3492# Create logical port alice1 in alice
31ed1192
JP
3493ovn-nbctl lsp-add alice alice1 \
3494-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3495
3496# Create logical port bob1 in bob
31ed1192
JP
3497ovn-nbctl lsp-add bob bob1 \
3498-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3499
3500# Create two hypervisor and create OVS ports corresponding to logical ports.
3501net_add n1
3502
3503sim_add hv1
3504as hv1
3505ovs-vsctl add-br br-phys
3506ovn_attach n1 br-phys 192.168.0.1
3507ovs-vsctl -- add-port br-int hv1-vif1 -- \
3508 set interface hv1-vif1 external-ids:iface-id=foo1 \
3509 options:tx_pcap=hv1/vif1-tx.pcap \
3510 options:rxq_pcap=hv1/vif1-rx.pcap \
3511 ofport-request=1
3512
3513ovs-vsctl -- add-port br-int hv1-vif2 -- \
3514 set interface hv1-vif2 external-ids:iface-id=alice1 \
3515 options:tx_pcap=hv1/vif2-tx.pcap \
3516 options:rxq_pcap=hv1/vif2-rx.pcap \
3517 ofport-request=2
3518
3519sim_add hv2
3520as hv2
3521ovs-vsctl add-br br-phys
3522ovn_attach n1 br-phys 192.168.0.2
3523ovs-vsctl -- add-port br-int hv2-vif1 -- \
3524 set interface hv2-vif1 external-ids:iface-id=bob1 \
3525 options:tx_pcap=hv2/vif1-tx.pcap \
3526 options:rxq_pcap=hv2/vif1-rx.pcap \
3527 ofport-request=1
3528
3529
3530# Pre-populate the hypervisors' ARP tables so that we don't lose any
3531# packets for ARP resolution (native tunneling doesn't queue packets
3532# for ARP resolution).
74868f2c 3533OVN_POPULATE_ARP
28dc3fe9
SR
3534
3535# Allow some time for ovn-northd and ovn-controller to catch up.
3536# XXX This should be more systematic.
3537sleep 1
3538
3539ip_to_hex() {
3540 printf "%02x%02x%02x%02x" "$@"
3541}
28dc3fe9
SR
3542
3543# Send ip packets between foo1 and alice1
3544src_mac="f00000010203"
3545dst_mac="000000010203"
3546src_ip=`ip_to_hex 192 168 1 2`
3547dst_ip=`ip_to_hex 172 16 1 2`
3548packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3549as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3550
3551# Send ip packets between foo1 and bob1
3552src_mac="f00000010203"
3553dst_mac="000000010203"
3554src_ip=`ip_to_hex 192 168 1 2`
3555dst_ip=`ip_to_hex 172 16 2 2`
3556packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3557as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3558
3559echo "---------NB dump-----"
3560ovn-nbctl show
3561echo "---------------------"
3562ovn-nbctl list logical_router
3563echo "---------------------"
3564ovn-nbctl list logical_router_port
3565echo "---------------------"
3566
3567echo "---------SB dump-----"
3568ovn-sbctl list datapath_binding
3569echo "---------------------"
3570ovn-sbctl list port_binding
3571echo "---------------------"
3572
3573echo "------ hv1 dump ----------"
3574as hv1 ovs-ofctl dump-flows br-int
3575echo "------ hv2 dump ----------"
3576as hv2 ovs-ofctl dump-flows br-int
3577
3578# Packet to Expect at bob1
3579src_mac="000000010205"
3580dst_mac="f00000010205"
3581src_ip=`ip_to_hex 192 168 1 2`
3582dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3583echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3584
49d7c759 3585OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3586
3587# Packet to Expect at alice1
3588src_mac="000000010204"
3589dst_mac="f00000010204"
3590src_ip=`ip_to_hex 192 168 1 2`
3591dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3592echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3593
49d7c759 3594OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3595
7a8f15e0 3596OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3597
3598AT_CLEANUP
5412db30 3599
0ee8aaf6 3600AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3601AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3602ovn_start
ea46a4e9 3603ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3604net_add n1
3605sim_add hv
3606as hv
3607ovs-vsctl \
3608 -- add-br br-phys \
3609 -- add-br br-eth0
3610
3611ovn_attach n1 br-phys 192.168.0.1
3612
3613AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3614AT_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])
3615
3616# Create a vif.
31ed1192
JP
3617AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3618AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3619AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3620
3621# Create a localnet port.
31ed1192
JP
3622AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3623AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3624AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3625AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3626
3627AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3628
3629# Wait for packet to be received.
49d7c759
BP
3630echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3631OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6 3632
5b57e12a
GL
3633# Check GARP packet when restart openflow connection.
3634as hv
3635OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3636
3637OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3638
3639as hv
3640start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3641
3642# Wait for packet to be received.
3643echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3644OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3645
0ee8aaf6
RR
3646# Delete the localnet ports.
3647AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3648AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3649
7a8f15e0 3650OVN_CLEANUP([hv])
0ee8aaf6
RR
3651
3652AT_CLEANUP
75cf9d2b
GS
3653
3654AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
3655AT_SKIP_IF([test $HAVE_PYTHON = no])
3656ovn_start
3657
3658# Logical network:
3659# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3660# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3661# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3662# connected to it.
3663
fa2a27b2
JP
3664ovn-nbctl lr-add R1
3665ovn-nbctl lr-add R2
3666ovn-nbctl lr-add R3
75cf9d2b 3667
ea46a4e9
JP
3668ovn-nbctl ls-add foo
3669ovn-nbctl ls-add alice
3670ovn-nbctl ls-add bob
3671ovn-nbctl ls-add join
75cf9d2b
GS
3672
3673# Connect foo to R1
31114af7 3674ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3675ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3676 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
3677
3678# Connect alice to R2
31114af7 3679ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3680ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3681 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
3682
3683# Connect bob to R3
31114af7 3684ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 3685ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 3686 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
3687
3688# Connect R1 to join
31114af7 3689ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3690ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3691 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
3692
3693# Connect R2 to join
31114af7 3694ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3695ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3696 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
3697
3698# Connect R3 to join
31114af7 3699ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 3700ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 3701 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
3702
3703#install static routes
e48ccf3c
JP
3704ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3705ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 3706
e48ccf3c
JP
3707ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3708ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 3709
e48ccf3c
JP
3710ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3711ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
3712
3713# Create logical port foo1 in foo
31ed1192
JP
3714ovn-nbctl lsp-add foo foo1 \
3715-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
3716
3717# Create logical port alice1 in alice
31ed1192
JP
3718ovn-nbctl lsp-add alice alice1 \
3719-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
3720
3721# Create logical port bob1 in bob
31ed1192
JP
3722ovn-nbctl lsp-add bob bob1 \
3723-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
3724
3725# Create two hypervisor and create OVS ports corresponding to logical ports.
3726net_add n1
3727
3728sim_add hv1
3729as hv1
3730ovs-vsctl add-br br-phys
3731ovn_attach n1 br-phys 192.168.0.1
3732ovs-vsctl -- add-port br-int hv1-vif1 -- \
3733 set interface hv1-vif1 external-ids:iface-id=foo1 \
3734 options:tx_pcap=hv1/vif1-tx.pcap \
3735 options:rxq_pcap=hv1/vif1-rx.pcap \
3736 ofport-request=1
3737
3738ovs-vsctl -- add-port br-int hv1-vif2 -- \
3739 set interface hv1-vif2 external-ids:iface-id=alice1 \
3740 options:tx_pcap=hv1/vif2-tx.pcap \
3741 options:rxq_pcap=hv1/vif2-rx.pcap \
3742 ofport-request=2
3743
3744sim_add hv2
3745as hv2
3746ovs-vsctl add-br br-phys
3747ovn_attach n1 br-phys 192.168.0.2
3748ovs-vsctl -- add-port br-int hv2-vif1 -- \
3749 set interface hv2-vif1 external-ids:iface-id=bob1 \
3750 options:tx_pcap=hv2/vif1-tx.pcap \
3751 options:rxq_pcap=hv2/vif1-rx.pcap \
3752 ofport-request=1
3753
3754
3755# Pre-populate the hypervisors' ARP tables so that we don't lose any
3756# packets for ARP resolution (native tunneling doesn't queue packets
3757# for ARP resolution).
74868f2c 3758OVN_POPULATE_ARP
75cf9d2b
GS
3759
3760# Allow some time for ovn-northd and ovn-controller to catch up.
3761# XXX This should be more systematic.
3762sleep 1
3763
3764ip_to_hex() {
3765 printf "%02x%02x%02x%02x" "$@"
3766}
75cf9d2b
GS
3767
3768# Send ip packets between foo1 and alice1
3769src_mac="f00000010203"
3770dst_mac="000001010203"
3771src_ip=`ip_to_hex 192 168 1 2`
3772dst_ip=`ip_to_hex 172 16 1 2`
3773packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3774as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3775as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3776
3777# Send ip packets between foo1 and bob1
3778src_mac="f00000010203"
3779dst_mac="000001010203"
3780src_ip=`ip_to_hex 192 168 1 2`
3781dst_ip=`ip_to_hex 10 32 1 2`
3782packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3783as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3784
3785echo "---------NB dump-----"
3786ovn-nbctl show
3787echo "---------------------"
3788ovn-nbctl list logical_router
3789echo "---------------------"
3790ovn-nbctl list logical_router_port
3791echo "---------------------"
3792
3793echo "---------SB dump-----"
3794ovn-sbctl list datapath_binding
3795echo "---------------------"
3796ovn-sbctl list port_binding
3797echo "---------------------"
3798ovn-sbctl dump-flows
3799echo "---------------------"
3800
3801echo "------ hv1 dump ----------"
3802as hv1 ovs-ofctl show br-int
3803as hv1 ovs-ofctl dump-flows br-int
3804echo "------ hv2 dump ----------"
3805as hv2 ovs-ofctl show br-int
3806as hv2 ovs-ofctl dump-flows br-int
3807echo "----------------------------"
3808
3809# Packet to Expect at bob1
3810src_mac="000003010203"
3811dst_mac="f00000010205"
3812src_ip=`ip_to_hex 192 168 1 2`
3813dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 3814echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3815
49d7c759 3816OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
3817
3818# Packet to Expect at alice1
3819src_mac="000002010203"
3820dst_mac="f00000010204"
3821src_ip=`ip_to_hex 192 168 1 2`
3822dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3823echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3824
49d7c759 3825OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 3826
7a8f15e0 3827OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
3828
3829AT_CLEANUP
c1645003 3830
281977f7 3831AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
3832AT_SKIP_IF([test $HAVE_PYTHON = no])
3833ovn_start
3834
3835ovn-nbctl ls-add ls1
3836
3837ovn-nbctl lsp-add ls1 ls1-lp1 \
3838-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3839
3840ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3841
3842ovn-nbctl lsp-add ls1 ls1-lp2 \
3843-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3844
3845ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3846
3847ovn-nbctl ls-add ls2
3848ovn-nbctl lsp-add ls2 ls2-lp1 \
3849-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3850ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3851ovn-nbctl lsp-add ls2 ls2-lp2 \
3852-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3853ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3854
9060fc9a 3855d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
281977f7 3856options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
9060fc9a 3857\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
281977f7 3858
9060fc9a
MM
3859ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3860ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3861
3862d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
281977f7 3863options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
9060fc9a
MM
3864\"lease_time\"=\"3600\"")"
3865
3866ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
281977f7
NS
3867
3868net_add n1
3869sim_add hv1
3870
3871as hv1
3872ovs-vsctl add-br br-phys
3873ovn_attach n1 br-phys 192.168.0.1
3874ovs-vsctl -- add-port br-int hv1-vif1 -- \
3875 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3876 options:tx_pcap=hv1/vif1-tx.pcap \
3877 options:rxq_pcap=hv1/vif1-rx.pcap \
3878 ofport-request=1
3879
3880ovs-vsctl -- add-port br-int hv1-vif2 -- \
3881 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3882 options:tx_pcap=hv1/vif2-tx.pcap \
3883 options:rxq_pcap=hv1/vif2-rx.pcap \
3884 ofport-request=2
3885
3886ovs-vsctl -- add-port br-int hv1-vif3 -- \
3887 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3888 options:tx_pcap=hv1/vif3-tx.pcap \
3889 options:rxq_pcap=hv1/vif3-rx.pcap \
3890 ofport-request=3
3891
3892ovs-vsctl -- add-port br-int hv1-vif4 -- \
3893 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3894 options:tx_pcap=hv1/vif4-tx.pcap \
3895 options:rxq_pcap=hv1/vif4-rx.pcap \
3896 ofport-request=4
3897
74868f2c 3898OVN_POPULATE_ARP
281977f7
NS
3899
3900sleep 2
3901
3902as hv1 ovs-vsctl show
3903
281977f7
NS
3904# This shell function sends a DHCP request packet
3905# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3906test_dhcp() {
213615b3
NS
3907 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3908 shift; shift; shift; shift; shift;
3909 if test $use_ip != 0; then
3910 src_ip=$1
3911 dst_ip=$2
3912 shift; shift;
3913 else
3914 src_ip=`ip_to_hex 0 0 0 0`
3915 dst_ip=`ip_to_hex 255 255 255 255`
3916 fi
3917 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
281977f7 3918 # udp header and dhcp header
ab187e7e
BP
3919 request=${request}0044004300fc0000
3920 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 3921 # client hardware padding
ab187e7e 3922 request=${request}00000000000000000000
281977f7 3923 # server hostname
ab187e7e
BP
3924 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3925 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3926 # boot file name
ab187e7e
BP
3927 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3928 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3929 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3930 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3931 # dhcp magic cookie
ab187e7e 3932 request=${request}63825363
281977f7 3933 # dhcp message type
ab187e7e 3934 request=${request}3501${dhcp_type}ff
281977f7
NS
3935
3936 if test $offer_ip != 0; then
213615b3 3937 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
281977f7
NS
3938 # total IP length will be the IP length of the request packet
3939 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3940 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3941 udp_len=`expr $ip_len - 20`
04d60f6e
YT
3942 ip_len=$(printf "%x" $ip_len)
3943 udp_len=$(printf "%x" $udp_len)
281977f7
NS
3944 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3945 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3946 # udp header and dhcp header.
3947 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 3948 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 3949 # your ip address
ab187e7e 3950 reply=${reply}${offer_ip}
281977f7 3951 # next server ip address, relay agent ip address, client mac address
ab187e7e 3952 reply=${reply}0000000000000000${src_mac}
281977f7 3953 # client hardware padding
ab187e7e 3954 reply=${reply}00000000000000000000
281977f7 3955 # server hostname
ab187e7e
BP
3956 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3957 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3958 # boot file name
ab187e7e
BP
3959 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3960 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3961 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3962 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3963 # dhcp magic cookie
ab187e7e 3964 reply=${reply}63825363
281977f7
NS
3965 # dhcp message type
3966 local dhcp_reply_type=02
3967 if test $dhcp_type = 03; then
3968 dhcp_reply_type=05
3969 fi
ab187e7e 3970 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
3971 echo $reply >> $inport.expected
3972 else
281977f7 3973 for outport; do
e4543cfe 3974 echo $request >> $outport.expected
281977f7
NS
3975 done
3976 fi
3977 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3978}
3979
3980reset_pcap_file() {
3981 local iface=$1
3982 local pcap_file=$2
3983 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3984options:rxq_pcap=dummy-rx.pcap
3985 rm -f ${pcap_file}*.pcap
3986 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3987options:rxq_pcap=${pcap_file}-rx.pcap
3988}
3989
3990ip_to_hex() {
3991 printf "%02x%02x%02x%02x" "$@"
3992}
3993
3994AT_CAPTURE_FILE([ofctl_monitor0.log])
3995as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3996--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3997
3998echo "---------NB dump-----"
3999ovn-nbctl show
4000echo "---------------------"
4001echo "---------SB dump-----"
4002ovn-sbctl list datapath_binding
4003echo "---------------------"
4004ovn-sbctl list logical_flow
4005echo "---------------------"
4006
4007echo "---------------------"
4008ovn-sbctl dump-flows
4009echo "---------------------"
4010
4011echo "------ hv1 dump ----------"
4012as hv1 ovs-ofctl dump-flows br-int
4013
4014# Send DHCPDISCOVER.
4015offer_ip=`ip_to_hex 10 0 0 4`
4016server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4017expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4018test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4019
4020# NXT_RESUMEs should be 1.
4021OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4022
4023$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4024cat 1.expected | cut -c -48 > expout
4025AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4026# Skipping the IPv4 checksum.
4027cat 1.expected | cut -c 53- > expout
4028AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4029
4030# ovs-ofctl also resumes the packets and this causes other ports to receive
4031# the DHCP request packet. So reset the pcap files so that its easier to test.
4032reset_pcap_file hv1-vif1 hv1/vif1
4033reset_pcap_file hv1-vif2 hv1/vif2
4034rm -f 1.expected
4035rm -f 2.expected
4036
4037# Send DHCPREQUEST.
4038offer_ip=`ip_to_hex 10 0 0 6`
4039server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4040expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4041test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4042
4043# NXT_RESUMEs should be 2.
4044OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4045
4046$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4047cat 2.expected | cut -c -48 > expout
4048AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4049# Skipping the IPv4 checksum.
4050cat 2.expected | cut -c 53- > expout
4051AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4052
4053reset_pcap_file hv1-vif1 hv1/vif1
4054reset_pcap_file hv1-vif2 hv1/vif2
4055rm -f 1.expected
4056rm -f 2.expected
4057
4058# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4059# but should be resumed without the reply.
4060# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4061# one from ovn-controller and the other from "ovs-ofctl resume."
4062offer_ip=0
213615b3 4063test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
281977f7
NS
4064
4065# NXT_RESUMEs should be 3.
4066OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4067
4068# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 4069OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
4070
4071reset_pcap_file hv1-vif1 hv1/vif1
4072reset_pcap_file hv1-vif2 hv1/vif2
4073rm -f 1.expected
4074rm -f 2.expected
4075
4076# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4077# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4078
213615b3 4079test_dhcp 3 f00000000003 01 0 4 0
281977f7
NS
4080
4081# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4082# this lport.
213615b3 4083test_dhcp 4 f00000000004 01 0 3 0
281977f7
NS
4084
4085# NXT_RESUMEs should be 3.
4086OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4087
49d7c759
BP
4088OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4089OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 4090
213615b3
NS
4091# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4092offer_ip=`ip_to_hex 10 0 0 6`
4093server_ip=`ip_to_hex 10 0 0 1`
4094expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4095src_ip=$offer_ip
4096dst_ip=$server_ip
4097test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4098
4099# NXT_RESUMEs should be 4.
4100OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4101
4102$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4103cat 2.expected | cut -c -48 > expout
4104AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4105# Skipping the IPv4 checksum.
4106cat 2.expected | cut -c 53- > expout
4107AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4108
4109reset_pcap_file hv1-vif1 hv1/vif1
4110reset_pcap_file hv1-vif2 hv1/vif2
4111rm -f 1.expected
4112rm -f 2.expected
4113
4114# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4115offer_ip=`ip_to_hex 10 0 0 6`
4116server_ip=`ip_to_hex 10 0 0 1`
4117expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4118src_ip=$offer_ip
4119dst_ip=`ip_to_hex 255 255 255 255`
4120test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4121
4122# NXT_RESUMEs should be 5.
4123OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4124
4125$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4126cat 2.expected | cut -c -48 > expout
4127AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4128# Skipping the IPv4 checksum.
4129cat 2.expected | cut -c 53- > expout
4130AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4131
4132reset_pcap_file hv1-vif1 hv1/vif1
4133reset_pcap_file hv1-vif2 hv1/vif2
4134rm -f 1.expected
4135rm -f 2.expected
4136
4137# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4138# The packet should not be received by ovn-controller.
4139src_ip=`ip_to_hex 10 0 0 6`
4140dst_ip=`ip_to_hex 10 0 0 4`
4141test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4142
4143# NXT_RESUMEs should be 5.
4144OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4145
4146# vif1-tx.pcap should have received the DHCPv4 request packet
4147OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4148
281977f7 4149as hv1
33ac3c83
NS
4150OVS_APP_EXIT_AND_WAIT([ovn-controller])
4151OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4152OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4153
4154as ovn-sb
4155OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4156
4157as ovn-nb
4158OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4159
4160as northd
4161OVS_APP_EXIT_AND_WAIT([ovn-northd])
4162
4163as main
4164OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4165OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4166
4167AT_CLEANUP
4168
40df4566 4169AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
4170AT_SKIP_IF([test $HAVE_PYTHON = no])
4171ovn_start
4172
4173ovn-nbctl ls-add ls1
4174ovn-nbctl lsp-add ls1 ls1-lp1 \
4175-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4176
4177ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4178
4179ovn-nbctl lsp-add ls1 ls1-lp2 \
4180-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4181
4182ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4183
40df4566
ZKL
4184ovn-nbctl lsp-add ls1 ls1-lp3 \
4185-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4186
4187ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4188
9060fc9a
MM
4189d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4190options="\"server_id\"=\"00:00:00:10:00:01\"")"
4191
4192ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4193ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4194
4195d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4196options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
33ac3c83 4197
9060fc9a 4198ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
40df4566 4199
33ac3c83
NS
4200ovn-nbctl ls-add ls2
4201ovn-nbctl lsp-add ls2 ls2-lp1 \
4202-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4203ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4204ovn-nbctl lsp-add ls2 ls2-lp2 \
4205-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4206ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4207
4208net_add n1
4209sim_add hv1
4210
4211as hv1
4212ovs-vsctl add-br br-phys
4213ovn_attach n1 br-phys 192.168.0.1
4214ovs-vsctl -- add-port br-int hv1-vif1 -- \
4215 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4216 options:tx_pcap=hv1/vif1-tx.pcap \
4217 options:rxq_pcap=hv1/vif1-rx.pcap \
4218 ofport-request=1
4219
4220ovs-vsctl -- add-port br-int hv1-vif2 -- \
4221 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4222 options:tx_pcap=hv1/vif2-tx.pcap \
4223 options:rxq_pcap=hv1/vif2-rx.pcap \
4224 ofport-request=2
4225
4226ovs-vsctl -- add-port br-int hv1-vif3 -- \
4227 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4228 options:tx_pcap=hv1/vif3-tx.pcap \
4229 options:rxq_pcap=hv1/vif3-rx.pcap \
4230 ofport-request=3
4231
4232ovs-vsctl -- add-port br-int hv1-vif4 -- \
4233 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4234 options:tx_pcap=hv1/vif4-tx.pcap \
4235 options:rxq_pcap=hv1/vif4-rx.pcap \
4236 ofport-request=4
4237
40df4566
ZKL
4238ovs-vsctl -- add-port br-int hv1-vif5 -- \
4239 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4240 options:tx_pcap=hv1/vif5-tx.pcap \
4241 options:rxq_pcap=hv1/vif5-rx.pcap \
4242 ofport-request=5
4243
74868f2c 4244OVN_POPULATE_ARP
33ac3c83
NS
4245
4246sleep 2
4247
4248trim_zeros() {
4249 sed 's/\(00\)\{1,\}$//'
4250}
4251
4252# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4253# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4254# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4255# packet should be received twice (one from ovn-controller and the other
4256# from the "ovs-ofctl monitor br-int resume"
4257test_dhcpv6() {
4258 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4259 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4260 # dst ip ff02::1:2
ab187e7e 4261 request=${request}ff020000000000000000000000010002
33ac3c83 4262 # udp header and dhcpv6 header
ab187e7e 4263 request=${request}02220223002affff${msg_code}010203
33ac3c83 4264 # Client identifier
ab187e7e 4265 request=${request}0001000a00030001${src_mac}
33ac3c83 4266 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 4267 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
4268 shift; shift; shift; shift; shift;
4269 if test $offer_ip != 0; then
4270 local server_mac=000000100001
4271 local server_lla=fe80000000000000020000fffe100001
4272 local reply_code=07
4273 if test $msg_code = 01; then
4274 reply_code=02
4275 fi
40df4566
ZKL
4276 local msg_len=54
4277 if test $offer_ip = 1; then
4278 msg_len=28
4279 fi
4280 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4281 # udp header and dhcpv6 header
ab187e7e 4282 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4283 # Client identifier
ab187e7e 4284 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4285 # IA-NA
40df4566 4286 if test $offer_ip != 1; then
ab187e7e 4287 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4288 fi
33ac3c83 4289 # Server identifier
ab187e7e 4290 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4291 echo $reply | trim_zeros >> $inport.expected
4292 else
4293 for outport; do
4294 echo $request | trim_zeros >> $outport.expected
4295 done
4296 fi
4297
4298 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4299}
4300
4301reset_pcap_file() {
4302 local iface=$1
4303 local pcap_file=$2
4304 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4305options:rxq_pcap=dummy-rx.pcap
4306 rm -f ${pcap_file}*.pcap
4307 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4308options:rxq_pcap=${pcap_file}-rx.pcap
4309}
4310
4311AT_CAPTURE_FILE([ofctl_monitor0.log])
4312as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4313--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4314
4315echo "---------NB dump-----"
4316ovn-nbctl show
4317echo "---------------------"
4318echo "---------SB dump-----"
4319ovn-sbctl list datapath_binding
4320echo "---------------------"
4321ovn-sbctl list logical_flow
4322echo "---------------------"
4323
4324echo "---------------------"
4325ovn-sbctl dump-flows
4326echo "---------------------"
4327
4328echo "------ hv1 dump ----------"
4329as hv1 ovs-ofctl dump-flows br-int
4330
4331src_mac=f00000000001
4332src_lla=fe80000000000000f20000fffe000001
4333offer_ip=ae700000000000000000000000000004
4334test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4335
4336# NXT_RESUMEs should be 1.
4337OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4338
4339$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4340# cat 1.expected | trim_zeros > expout
4341cat 1.expected | cut -c -120 > expout
4342AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4343# Skipping the UDP checksum
4344cat 1.expected | cut -c 125- > expout
4345AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4346
4347rm 1.expected
4348
4349# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4350# without any modifications and the packet should be received by ls1-lp1.
4351# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4352# resume and the other from ovs-ofctl monitor resume.
4353
4354reset_pcap_file hv1-vif1 hv1/vif1
4355reset_pcap_file hv1-vif2 hv1/vif2
4356
4357src_mac=f00000000002
4358src_lla=fe80000000000000f20000fffe000002
4359offer_ip=ae700000000000000000000000000005
4360# Set invalid msg_type
4361
4362test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4363
4364# NXT_RESUMEs should be 2.
4365OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4366
4367# vif2-tx.pcap should not have received the DHCPv6 reply packet
4368rm 2.packets
4369$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4370AT_CHECK([cat 2.packets], [0], [])
4371
4372# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4373$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4374cat 1.expected > expout
4375AT_CHECK([cat 1.packets], [0], [expout])
4376
4377# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4378# There should be no DHCPv6 reply from ovn-controller and the request packet
4379# should be received by ls2-lp2.
4380
4381src_mac=f00000000003
4382src_lla=fe80000000000000f20000fffe000003
4383test_dhcpv6 3 $src_mac $src_lla 01 0 4
4384
4385# NXT_RESUMEs should be 2 only.
4386OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4387
4388# vif3-tx.pcap should not have received the DHCPv6 reply packet
4389$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4390AT_CHECK([cat 3.packets], [0], [])
4391
4392# vif4-tx.pcap should have received the DHCPv6 request packet
4393$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4394cat 4.expected > expout
4395AT_CHECK([cat 4.packets], [0], [expout])
4396
40df4566
ZKL
4397# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4398# The DHCPv6 reply should doesn't contian offer_ip.
4399src_mac=f00000000022
4400src_lla=fe80000000000000f20000fffe000022
4401reset_pcap_file hv1-vif5 hv1/vif5
4402test_dhcpv6 5 $src_mac $src_lla 01 1 5
4403
4404# NXT_RESUMEs should be 3.
4405OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4406
4407$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4408# Skipping the UDP checksum
4409cat 5.expected | cut -c 1-120,125- > expout
4410AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4411
33ac3c83 4412as hv1
281977f7
NS
4413OVS_APP_EXIT_AND_WAIT([ovn-controller])
4414OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4415OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4416
4417as ovn-sb
4418OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4419
4420as ovn-nb
4421OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4422
4423as northd
4424OVS_APP_EXIT_AND_WAIT([ovn-northd])
4425
4426as main
4427OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4428OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4429
4430AT_CLEANUP
4431
c1645003 4432AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4433AT_SKIP_IF([test $HAVE_PYTHON = no])
4434ovn_start
4435
4436# Logical network:
4437# Two LRs - R1 and R2 that are connected to each other via LS "join"
4438# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4439# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4440# R2 is a gateway router.
4441
4442
4443
4444# Create two hypervisor and create OVS ports corresponding to logical ports.
4445net_add n1
4446
4447sim_add hv1
4448as hv1
4449ovs-vsctl add-br br-phys
4450ovn_attach n1 br-phys 192.168.0.1
4451ovs-vsctl -- add-port br-int hv1-vif1 -- \
4452 set interface hv1-vif1 external-ids:iface-id=foo1 \
4453 options:tx_pcap=hv1/vif1-tx.pcap \
4454 options:rxq_pcap=hv1/vif1-rx.pcap \
4455 ofport-request=1
4456
4457
4458sim_add hv2
4459as hv2
4460ovs-vsctl add-br br-phys
4461ovn_attach n1 br-phys 192.168.0.2
4462ovs-vsctl -- add-port br-int hv2-vif1 -- \
4463 set interface hv2-vif1 external-ids:iface-id=alice1 \
4464 options:tx_pcap=hv2/vif1-tx.pcap \
4465 options:rxq_pcap=hv2/vif1-rx.pcap \
4466 ofport-request=1
4467
4468# Pre-populate the hypervisors' ARP tables so that we don't lose any
4469# packets for ARP resolution (native tunneling doesn't queue packets
4470# for ARP resolution).
74868f2c 4471OVN_POPULATE_ARP
c1645003
GS
4472
4473ovn-nbctl create Logical_Router name=R1
4474ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4475
ea46a4e9
JP
4476ovn-nbctl ls-add foo
4477ovn-nbctl ls-add alice
4478ovn-nbctl ls-add join
c1645003
GS
4479
4480# Connect foo to R1
31114af7 4481ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4482ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4483 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4484
4485# Connect alice to R2
31114af7 4486ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4487ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4488 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4489
4490# Connect R1 to join
31114af7 4491ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4492ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4493 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4494
4495# Connect R2 to join
31114af7 4496ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4497ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4498 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4499
4500
4501#install static routes
4502ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4503ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4504R1 static_routes @lrt
4505
4506ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4507ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4508R2 static_routes @lrt
4509
4510# Create logical port foo1 in foo
31ed1192
JP
4511ovn-nbctl lsp-add foo foo1 \
4512-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4513
4514# Create logical port alice1 in alice
31ed1192
JP
4515ovn-nbctl lsp-add alice alice1 \
4516-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4517
4518
4519# Allow some time for ovn-northd and ovn-controller to catch up.
4520# XXX This should be more systematic.
4521sleep 2
4522
4523ip_to_hex() {
4524 printf "%02x%02x%02x%02x" "$@"
4525}
c1645003
GS
4526
4527# Send ip packets between foo1 and alice1
4528src_mac="f00000010203"
4529dst_mac="000001010203"
4530src_ip=`ip_to_hex 192 168 1 2`
4531dst_ip=`ip_to_hex 172 16 1 2`
4532packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4533
4534echo "---------NB dump-----"
4535ovn-nbctl show
4536echo "---------------------"
4537ovn-nbctl list logical_router
4538echo "---------------------"
4539ovn-nbctl list logical_router_port
4540echo "---------------------"
4541
4542echo "---------SB dump-----"
4543ovn-sbctl list datapath_binding
4544echo "---------------------"
4545ovn-sbctl list port_binding
4546echo "---------------------"
4547ovn-sbctl dump-flows
4548echo "---------------------"
4549ovn-sbctl list chassis
4550ovn-sbctl list encap
4551echo "---------------------"
4552
c1645003
GS
4553# Packet to Expect at alice1
4554src_mac="000002010203"
4555dst_mac="f00000010204"
4556src_ip=`ip_to_hex 192 168 1 2`
4557dst_ip=`ip_to_hex 172 16 1 2`
4558expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4559
4560
4561as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4562as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4563
ab39371d
RM
4564echo "------ hv1 dump after packet 1 ----------"
4565as hv1 ovs-ofctl show br-int
4566as hv1 ovs-ofctl dump-flows br-int
4567echo "------ hv2 dump after packet 1 ----------"
4568as hv2 ovs-ofctl show br-int
4569as hv2 ovs-ofctl dump-flows br-int
4570echo "----------------------------"
4571
49d7c759
BP
4572echo $expected > expected
4573OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4574
34114cf8
GS
4575# Delete the router and re-create it. Things should work as before.
4576ovn-nbctl lr-del R2
4577ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4578# Connect alice to R2
4579ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4580# Connect R2 to join
4581ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4582
4583ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4584ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4585R2 static_routes @lrt
4586
4587# Wait for ovn-controller to catch up.
4588sleep 1
4589
4590# Send the packet again.
4591as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4592
4593echo "------ hv1 dump after packet 2 ----------"
4594as hv1 ovs-ofctl show br-int
4595as hv1 ovs-ofctl dump-flows br-int
4596echo "------ hv2 dump after packet 2 ----------"
4597as hv2 ovs-ofctl show br-int
4598as hv2 ovs-ofctl dump-flows br-int
4599echo "----------------------------"
4600
49d7c759
BP
4601echo $expected >> expected
4602OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4603
7a8f15e0 4604OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4605
4606AT_CLEANUP
bb3c4568
FF
4607
4608AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4609AT_KEYWORDS([router-icmp-reply])
4610AT_SKIP_IF([test $HAVE_PYTHON = no])
4611ovn_start
4612
4613# Logical network:
4614# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4615# and has switch ls2 (172.16.1.0/24) connected to it.
4616
fa2a27b2 4617ovn-nbctl lr-add R1
bb3c4568 4618
ea46a4e9
JP
4619ovn-nbctl ls-add ls1
4620ovn-nbctl ls-add ls2
bb3c4568
FF
4621
4622# Connect ls1 to R1
31114af7 4623ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4624ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4625 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4626
4627# Connect ls2 to R1
31114af7 4628ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4629ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4630 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4631
4632# Create logical port ls1-lp1 in ls1
31ed1192
JP
4633ovn-nbctl lsp-add ls1 ls1-lp1 \
4634-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4635
4636# Create logical port ls2-lp1 in ls2
31ed1192
JP
4637ovn-nbctl lsp-add ls2 ls2-lp1 \
4638-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4639
4640# Create one hypervisor and create OVS ports corresponding to logical ports.
4641net_add n1
4642
4643sim_add hv1
4644as hv1
4645ovs-vsctl add-br br-phys
4646ovn_attach n1 br-phys 192.168.0.1
4647ovs-vsctl -- add-port br-int vif1 -- \
4648 set interface vif1 external-ids:iface-id=ls1-lp1 \
4649 options:tx_pcap=hv1/vif1-tx.pcap \
4650 options:rxq_pcap=hv1/vif1-rx.pcap \
4651 ofport-request=1
4652
4653ovs-vsctl -- add-port br-int vif2 -- \
4654 set interface vif2 external-ids:iface-id=ls2-lp1 \
4655 options:tx_pcap=hv1/vif2-tx.pcap \
4656 options:rxq_pcap=hv1/vif2-rx.pcap \
4657 ofport-request=1
4658
4659
4660# Allow some time for ovn-northd and ovn-controller to catch up.
4661# XXX This should be more systematic.
4662sleep 1
4663
4664
4665ip_to_hex() {
4666 printf "%02x%02x%02x%02x" "$@"
4667}
bb3c4568
FF
4668for i in 1 2; do
4669 : > vif$i.expected
4670done
4671# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4672#
4673# Causes a packet to be received on INPORT. The packet is an ICMPv4
4674# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4675# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4676# provided, then it should be the ip and icmp checksums of the packet
4677# responded; otherwise, no reply is expected.
4678# In the absence of an ip checksum calculation helpers, this relies
4679# on the caller to provide the checksums for the ip and icmp headers.
4680# XXX This should be more systematic.
4681#
4682# INPORT is an lport number, e.g. 11 for vif11.
4683# ETH_SRC and ETH_DST are each 12 hex digits.
4684# IPV4_SRC and IPV4_DST are each 8 hex digits.
4685# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4686# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4687test_ipv4_icmp_request() {
4688 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4689 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4690 shift; shift; shift; shift; shift; shift; shift
4691 shift; shift
4692
4693 # Use ttl to exercise section 4.2.2.9 of RFC1812
4694 local ip_ttl=01
4695 local icmp_id=5fbf
4696 local icmp_seq=0001
4697 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4698 local icmp_type_code_request=0800
4699 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4700 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4701
4702 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4703 if test X$exp_icmp_chksum != X; then
4704 # Expect to receive the reply, if any. In same port where packet was sent.
4705 # Note: src and dst fields are expected to be reversed.
4706 local icmp_type_code_response=0000
4707 local reply_icmp_ttl=fe
4708 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4709 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4710 echo $reply >> vif$inport.expected
4711 fi
4712}
4713
4714# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4715rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4716rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4717l1_ip=$(ip_to_hex 192 168 1 2)
4718l2_ip=$(ip_to_hex 172 16 1 2)
4719
4720# Ping router ip address that is on same subnet as the logical port
4721test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4722test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4723
4724# Ping router ip address that is on the other side of the logical ports
4725test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4726test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4727
4728echo "---------NB dump-----"
4729ovn-nbctl show
4730echo "---------------------"
4731ovn-nbctl list logical_router
4732echo "---------------------"
4733ovn-nbctl list logical_router_port
4734echo "---------------------"
4735
4736echo "---------SB dump-----"
4737ovn-sbctl list datapath_binding
4738echo "---------------------"
4739ovn-sbctl list logical_flow
4740echo "---------------------"
4741
4742echo "------ hv1 dump ----------"
4743as hv1 ovs-ofctl dump-flows br-int
4744
4745# Now check the packets actually received against the ones expected.
4746for inport in 1 2; do
49d7c759 4747 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4748done
4749
7a8f15e0 4750OVN_CLEANUP([hv1])
bb3c4568
FF
4751
4752AT_CLEANUP
94f79fcb
RB
4753
4754# 1 hypervisor, 1 port
4755# make sure that the port state is properly set to up and back down
4756# when created and deleted.
4757AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
4758ovn_start
4759
4760ovn-nbctl ls-add ls1
4761ovn-nbctl lsp-add ls1 lp1
4762ovn-nbctl lsp-set-addresses lp1 unknown
4763
4764net_add n1
4765sim_add hv1
4766as hv1 ovs-vsctl add-br br-phys
4767as hv1 ovn_attach n1 br-phys 192.168.0.1
4768
4769as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4770OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4771
4772as hv1 ovs-vsctl del-port br-int vif1
4773OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4774
7a8f15e0 4775OVN_CLEANUP([hv1])
94f79fcb 4776
94f79fcb 4777AT_CLEANUP
e75451fe 4778
ccc6e1db
FF
4779# 1 hypervisor, 1 port
4780# make sure that the OF rules created to support a datapath are added/cleared
4781# when logical switch is created and removed.
4782AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 4783AT_KEYWORDS([cleanup])
ccc6e1db
FF
4784ovn_start
4785
4786net_add n1
4787sim_add hv1
4788as hv1 ovs-vsctl add-br br-phys
4789as hv1 ovn_attach n1 br-phys 192.168.0.1
4790
4791# This shell function checks if OF rules in br-int have clauses
4792# related to OVN datapaths. The caller determines if it should find
4793# a match in the output, or not.
4794#
4795# EXPECT_DATAPATH param determines whether flows that refer to
4796# datapath to should be present or not. 0 means
4797# they should not be.
4798# STAGE_INFO param is a simple string to help identify the stage
4799# in the test when this function was invoked.
4800test_datapath_in_of_rules() {
4801 local expect_datapath=$1 stage_info=$2
4802 echo "------ ovn-nbctl show ${stage_info} ------"
4803 ovn-nbctl show
4804 echo "------ ovn-sbctl show ${stage_info} ------"
4805 ovn-sbctl show
4806 echo "------ OF rules ${stage_info} ------"
4807 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4808 # if there is a datapath mentioned in the output, check for the
4809 # magic keyword that represents one, based on the exit status of
4810 # a quiet grep
4811 if test $expect_datapath != 0; then
4618b102 4812 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 4813 else
4618b102 4814 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
4815 fi
4816}
4817
4818test_datapath_in_of_rules 0 "before ls+port create"
4819
4820ovn-nbctl ls-add ls1
4821ovn-nbctl lsp-add ls1 lp1
4822ovn-nbctl lsp-set-addresses lp1 unknown
4823
4824as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4825OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4826
4827test_datapath_in_of_rules 1 "after port is bound"
4828
4829as hv1 ovs-vsctl del-port br-int vif1
4830OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4831
4832ovn-nbctl lsp-set-addresses lp1
4833ovn-nbctl lsp-del lp1
4834ovn-nbctl ls-del ls1
4835
4836# wait for earlier changes to take effect
4837AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4838
4839# ensure OF rules are no longer present. There used to be a bug here.
4840test_datapath_in_of_rules 0 "after lport+ls removal"
4841
4842OVN_CLEANUP([hv1])
4843
4844AT_CLEANUP
4845
f8a8db39 4846AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
4847AT_SKIP_IF([test $HAVE_PYTHON = no])
4848ovn_start
4849
4850#TODO: since patch port for IPv6 logical router port is not ready not,
4851# so we are not going to test vifs on different lswitches cases. Try
4852# to update for that once relevant stuff implemented.
4853
4854# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4855# with. NS packet we test, from one VIF for another VIF, will be replied
4856# by local ovn-controller, but not by target VIF.
4857
4858# Create hypervisors and logical switch lsw0.
4859ovn-nbctl ls-add lsw0
4860net_add n1
4861sim_add hv1
4862as hv1
4863ovs-vsctl add-br br-phys
4864ovn_attach n1 br-phys 192.168.0.2
4865
4866# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4867ovs-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
4868ovn-nbctl lsp-add lsw0 lp1
4869ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4870ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4871
4872# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4873ovs-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
4874ovn-nbctl lsp-add lsw0 lp2
4875ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4876ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4877
4878# Add ACL rule for ICMPv6 on lsw0
4879ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4880ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4881ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4882
4883# Allow some time for ovn-northd and ovn-controller to catch up.
4884# XXX This should be more systematic.
4885sleep 1
4886
4887# Given the name of a logical port, prints the name of the hypervisor
4888# on which it is located.
4889vif_to_hv() {
4890 echo hv1${1%?}
4891}
e75451fe
ZKL
4892for i in 1 2; do
4893 : > $i.expected
4894done
4895
4896# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4897# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4898# vif2 will not receive NS packet, since ovn-controller will reply for it.
4899ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4900na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4901
4902as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 4903echo $na_packet >> 1.expected
e75451fe 4904
e75451fe
ZKL
4905echo "------ hv1 dump ------"
4906as hv1 ovs-vsctl show
4907as hv1 ovs-ofctl -O OpenFlow13 show br-int
4908as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4909
4910for i in 1 2; do
49d7c759 4911 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
4912done
4913
7a8f15e0 4914OVN_CLEANUP([hv1])
e75451fe
ZKL
4915
4916AT_CLEANUP
7417d147
RM
4917
4918AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
4919ovn_start
4920
4921net_add n1
4922
4923sim_add hv1
4924as hv1
4925ovs-vsctl add-br br-phys
4926ovn_attach n1 br-phys 192.168.0.1
4927
4928row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4929ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4930ovn-nbctl destroy Address_Set $row
4931
4932sleep 1
4933
4934# A bug previously existed in the address set support code
4935# that caused ovn-controller to crash after an address set
4936# was updated and then removed. This test case ensures
4937# that ovn-controller is at least still running after
4938# creating, updating, and deleting an address set.
4939AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4940
4941OVN_CLEANUP([hv1])
4942
4943AT_CLEANUP
8639f9be
ND
4944
4945AT_SETUP([ovn -- ipam])
8639f9be
ND
4946AT_SKIP_IF([test $HAVE_PYTHON = no])
4947ovn_start
4948
4949# Add a port to a switch that does not have a subnet set, then set the
4950# subnet which should result in an address being allocated for the port.
4951ovn-nbctl ls-add sw0
4952ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 4953ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
4954AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4955 ["0a:00:00:00:00:01 192.168.1.2"
4956])
4957
4958# Add 9 more ports to sw0, addresses should all be unique.
4959for n in `seq 1 9`; do
11547f85 4960 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4961done
4962AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4963 ["0a:00:00:00:00:02 192.168.1.3"
4964])
4965AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4966 ["0a:00:00:00:00:03 192.168.1.4"
4967])
4968AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4969 ["0a:00:00:00:00:04 192.168.1.5"
4970])
4971AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4972 ["0a:00:00:00:00:05 192.168.1.6"
4973])
4974AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4975 ["0a:00:00:00:00:06 192.168.1.7"
4976])
4977AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4978 ["0a:00:00:00:00:07 192.168.1.8"
4979])
4980AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4981 ["0a:00:00:00:00:08 192.168.1.9"
4982])
4983AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4984 ["0a:00:00:00:00:09 192.168.1.10"
4985])
4986AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4987 ["0a:00:00:00:00:0a 192.168.1.11"
4988])
4989
4990# Trying similar tests with a second switch. MAC addresses should be unique
4991# across both switches but IP's only need to be unique within the same switch.
4992ovn-nbctl ls-add sw1
4993ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 4994ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
4995AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4996 ["0a:00:00:00:00:0b 192.168.1.2"
4997])
4998
4999for n in `seq 11 19`; do
11547f85 5000 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5001done
5002AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5003 ["0a:00:00:00:00:0c 192.168.1.3"
5004])
5005AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5006 ["0a:00:00:00:00:0d 192.168.1.4"
5007])
5008AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5009 ["0a:00:00:00:00:0e 192.168.1.5"
5010])
5011AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5012 ["0a:00:00:00:00:0f 192.168.1.6"
5013])
5014AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5015 ["0a:00:00:00:00:10 192.168.1.7"
5016])
5017AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5018 ["0a:00:00:00:00:11 192.168.1.8"
5019])
5020AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5021 ["0a:00:00:00:00:12 192.168.1.9"
5022])
5023AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5024 ["0a:00:00:00:00:13 192.168.1.10"
5025])
5026AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5027 ["0a:00:00:00:00:14 192.168.1.11"
5028])
5029
5030# Change a port's address to test for multiple ip's for a single address entry
5031# and addresses set by the user.
5032ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
11547f85 5033ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
5034AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5035 ["0a:00:00:00:00:16 192.168.1.13"
5036])
5037
5038# Test for logical router port address management.
5039ovn-nbctl create Logical_Router name=R1
5040ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5041network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5042-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5043-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 5044ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
5045AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5046 ["0a:00:00:00:00:18 192.168.1.15"
5047])
5048
5049# Test for address reuse after logical port is deleted.
5050ovn-nbctl lsp-del p0
11547f85 5051ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
5052AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5053 ["0a:00:00:00:00:19 192.168.1.2"
5054])
5055
5056# Test for multiple addresses to one logical port.
5057ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5058"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 5059ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
5060AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5061 ["0a:00:00:00:00:1c 192.168.1.16"
5062])
5063
5064# Test for exhausting subnet address space.
5065ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 5066ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
5067AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5068 ["0a:00:00:00:00:1d 172.16.1.2"
5069])
5070
11547f85 5071ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 5072AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
7cc0741e 5073 ["0a:00:00:00:00:1e"
8639f9be
ND
5074])
5075
5076# Test that address management does not add duplicate MAC for lsp/lrp peers.
5077ovn-nbctl create Logical_Router name=R2
5078ovn-nbctl ls-add sw3
5079ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
7cc0741e 5080"0a:00:00:00:00:1f"
8639f9be
ND
5081ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5082network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5083-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5084-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 5085ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
5086AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5087 ["0a:00:00:00:00:20 192.168.1.17"
5088])
5089
6374d518
LR
5090# Test static MAC address with dynamically allocated IP
5091ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5092"fe:dc:ba:98:76:54 dynamic"
5093AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5094 ["fe:dc:ba:98:76:54 192.168.1.18"
5095])
5096
6c4f7a8a
NS
5097# Update the static MAC address with dynamically allocated IP and check
5098# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5099ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5100ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5101
5102AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5103 ["fe:dc:ba:98:76:55 192.168.1.18"
5104])
5105
5106ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5107AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5108 ["fe:dc:ba:98:76:55 192.168.1.18"
5109])
5110
5111ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5112AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5113 ["fe:dc:ba:98:76:56 192.168.1.18"
5114])
5115
161ea2c8
NS
5116
5117# Test the exclude_ips from the IPAM list
5118ovn-nbctl --wait=sb set logical_switch sw0 \
5119other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5120
5121ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5122"dynamic"
5123# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5124AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5125 ["0a:00:00:00:00:21 192.168.1.20"
5126])
5127
5128ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5129"dynamic"
5130# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5131AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5132 ["0a:00:00:00:00:22 192.168.1.22"
5133])
5134
5135ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5136"dynamic"
5137# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5138AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5139 ["0a:00:00:00:00:23 192.168.1.51"
5140])
5141
5142# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5143ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5144ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5145"dynamic"
5146AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5147 ["0a:00:00:00:00:24 192.168.1.19"
5148])
5149
5150# Set invalid data in exclude_ips list. It should be ignored.
5151ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5152ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5153"dynamic"
5154# 192.168.1.21 should be assigned as that's the next free one.
5155AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5156 ["0a:00:00:00:00:25 192.168.1.21"
5157])
5158
5159# Clear the dynamic addresses assignment request.
5160ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5161AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5162 [[[]]
5163])
5164
7cc0741e
NS
5165# Set IPv6 prefix
5166ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5167ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5168"dynamic"
5169
5170# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5171# - aef0::800:ff:fe00:26 (EUI64)
5172AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5173 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5174])
5175
5176ovn-nbctl --wait=sb ls-add sw4
5177ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5178ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5179"dynamic"
5180
5181AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5182 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5183])
5184
5185ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5186"f0:00:00:00:10:12 dynamic"
5187
5188AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5189 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5190])
5191
5192# Clear the other_config for sw4. No dynamic ip should be assigned.
5193ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5194ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5195"dynamic"
5196
5197AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5198 [[[]]
5199])
5200
5201# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5202ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5203-- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5204
5205# Now p40 should be assigned with dynamic addresses.
5206AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5207 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5208])
5209
5210ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5211"dynamic"
5212# p41 should not have IPv4 address (as the pool is exhausted).
5213AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5214 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5215])
5216
8639f9be
ND
5217as ovn-sb
5218OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5219
5220as ovn-nb
5221OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5222
5223as northd
5224OVS_APP_EXIT_AND_WAIT([ovn-northd])
5225
5226AT_CLEANUP
5227
5228AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5229AT_SKIP_IF([test $HAVE_PYTHON = no])
5230ovn_start
5231
5232ovn-nbctl lr-add R1
5233
5234# Test for a ping using dynamically allocated addresses.
5235ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5236ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5237
5238# Connect foo to R1
5239ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5240ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5241 options:router-port=foo \
5242 -- lsp-set-addresses rp-foo router
8639f9be
ND
5243
5244# Connect alice to R1
5245ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5246ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5247 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5248
5249# Create logical port foo1 in foo
fd3b31e9 5250ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5251-- lsp-set-addresses foo1 "dynamic"
8bc2c143 5252AT_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
5253
5254# Create logical port alice1 in alice
fd3b31e9 5255ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5256-- lsp-set-addresses alice1 "dynamic"
8bc2c143 5257AT_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
5258
5259# Create logical port foo2 in foo
fd3b31e9 5260ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5261-- lsp-set-addresses foo2 "dynamic"
8bc2c143 5262AT_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
5263
5264# Create a hypervisor and create OVS ports corresponding to logical ports.
5265net_add n1
5266
5267sim_add hv1
5268as hv1
5269ovs-vsctl add-br br-phys
5270ovn_attach n1 br-phys 192.168.0.1
5271ovs-vsctl -- add-port br-int hv1-vif1 -- \
5272 set interface hv1-vif1 external-ids:iface-id=foo1 \
5273 options:tx_pcap=hv1/vif1-tx.pcap \
5274 options:rxq_pcap=hv1/vif1-rx.pcap \
5275 ofport-request=1
5276
5277ovs-vsctl -- add-port br-int hv1-vif2 -- \
5278 set interface hv1-vif2 external-ids:iface-id=foo2 \
5279 options:tx_pcap=hv1/vif2-tx.pcap \
5280 options:rxq_pcap=hv1/vif2-rx.pcap \
5281 ofport-request=2
5282
5283ovs-vsctl -- add-port br-int hv1-vif3 -- \
5284 set interface hv1-vif3 external-ids:iface-id=alice1 \
5285 options:tx_pcap=hv1/vif3-tx.pcap \
5286 options:rxq_pcap=hv1/vif3-rx.pcap \
5287 ofport-request=3
5288
5289# Allow some time for ovn-northd and ovn-controller to catch up.
5290# XXX This should be more systematic.
5291sleep 1
5292
5293ip_to_hex() {
5294 printf "%02x%02x%02x%02x" "$@"
5295}
8639f9be
ND
5296
5297# Send ip packets between foo1 and foo2
5298src_mac="0a0000000001"
5299dst_mac="0a0000000003"
5300src_ip=`ip_to_hex 192 168 1 2`
5301dst_ip=`ip_to_hex 192 168 1 3`
5302packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5303as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5304
5305# Send ip packets between foo1 and alice1
5306src_mac="0a0000000001"
5307dst_mac="000000010203"
5308src_ip=`ip_to_hex 192 168 1 2`
5309dst_ip=`ip_to_hex 192 168 2 2`
5310packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5311as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5312
5313echo "---------NB dump-----"
5314ovn-nbctl show
5315echo "---------------------"
5316ovn-nbctl list logical_router
5317echo "---------------------"
5318ovn-nbctl list logical_router_port
5319echo "---------------------"
5320
5321echo "---------SB dump-----"
5322ovn-sbctl list datapath_binding
5323echo "---------------------"
5324ovn-sbctl list port_binding
5325echo "---------------------"
5326
5327echo "------ hv1 dump ----------"
5328as hv1 ovs-ofctl dump-flows br-int
5329
5330# Packet to Expect at foo2
5331src_mac="0a0000000001"
5332dst_mac="0a0000000003"
5333src_ip=`ip_to_hex 192 168 1 2`
5334dst_ip=`ip_to_hex 192 168 1 3`
5335expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5336
e4543cfe
DDP
5337$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5338echo $expected > expout
8639f9be
ND
5339AT_CHECK([cat received1.packets], [0], [expout])
5340
5341# Packet to Expect at alice1
5342src_mac="000000010204"
5343dst_mac="0a0000000002"
5344src_ip=`ip_to_hex 192 168 1 2`
5345dst_ip=`ip_to_hex 192 168 2 2`
5346expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5347
e4543cfe
DDP
5348$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5349echo $expected > expout
8639f9be
ND
5350AT_CHECK([cat received2.packets], [0], [expout])
5351
5352OVN_CLEANUP([hv1])
5353
5354AT_CLEANUP
f5792c3f
NS
5355
5356AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5357AT_KEYWORDS([vswitchd])
f5792c3f
NS
5358AT_SKIP_IF([test $HAVE_PYTHON = no])
5359ovn_start
5360
5361ovn-nbctl ls-add ls1
5362
5363ovn-nbctl lsp-add ls1 ls1-lp1 \
5364-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5365
5366ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5367
5368net_add n1
5369sim_add hv1
5370
5371as hv1
5372ovs-vsctl add-br br-phys
5373ovn_attach n1 br-phys 192.168.0.1
5374ovs-vsctl -- add-port br-int hv1-vif1 -- \
5375 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5376 options:tx_pcap=hv1/vif1-tx.pcap \
5377 options:rxq_pcap=hv1/vif1-rx.pcap \
5378 ofport-request=1
5379
74868f2c 5380OVN_POPULATE_ARP
f5792c3f
NS
5381sleep 2
5382
5383as hv1 ovs-vsctl show
5384
5385echo "---------------------"
5386ovn-sbctl dump-flows
5387echo "---------------------"
5388
5389echo "------ hv1 dump ----------"
5390as hv1 ovs-ofctl dump-flows br-int
5391total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5392
5393echo "Total flows before vswitchd restart = " $total_flows
5394
5395# Code taken from ovs-save utility
5396save_flows () {
5397 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5398 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5399 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5400 echo "EOF" >> restore_flows.sh
5401}
5402
5403restart_vswitchd () {
5404 restore_flows=$1
5405
5406 if test $restore_flows = true; then
5407 save_flows
5408 fi
5409
5410 as hv1
5411 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5412
5413 if test $restore_flows = true; then
5414 as hv1
5415 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5416 fi
5417
5418 as hv1
5419 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5420 ovs-ofctl dump-flows br-int
5421
5422 if test $restore_flows = true; then
5423 sh ./restore_flows.sh
5424 echo "Flows after restore"
5425 as hv1
5426 ovs-ofctl dump-flows br-int
5427 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5428 flow-restore-wait="true"
5429 fi
5430}
5431
5432# Save the flows, restart vswitchd and restore the flows
5433restart_vswitchd true
5434OVS_WAIT_UNTIL([
5435 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5436 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5437 test "${total_flows}" = "${total_flows_after_restart}"
5438])
5439
5440# Restart vswitchd without restoring
5441restart_vswitchd false
5442OVS_WAIT_UNTIL([
5443 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5444 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5445 test "${total_flows}" = "${total_flows_after_restart}"
5446])
5447
5448OVN_CLEANUP([hv1])
5449AT_CLEANUP
47021598
CSV
5450
5451AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5452AT_SKIP_IF([test $HAVE_PYTHON = no])
5453ovn_start
5454
5455# Topology: Two LSs - ls1 and ls2 are connected via router r0
5456
5457# Create logical switches
5458ovn-nbctl ls-add ls1
5459ovn-nbctl ls-add ls2
5460
5461# Create router
5462ovn-nbctl create Logical_Router name=lr0
5463
5464# Add router ls1p1 port to gateway router
5465ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5466ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5467 type=router options:router-port=lrp-ls1lp1 \
5468 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5469
5470# Add router ls2p2 port to gateway router
5471ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5472ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5473 type=router options:router-port=lrp-ls2lp1 \
5474 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5475
5476# Set default gateway (nexthop) to 192.168.1.254
5477ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5478
5479# Create logical port ls1lp2 in ls1
5480ovn-nbctl lsp-add ls1 ls1lp2 \
5481-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5482
5483# Create logical port ls2lp2 in ls2
5484ovn-nbctl lsp-add ls2 ls2lp2 \
5485-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5486
5487net_add n1
5488sim_add hv1
5489as hv1
5490ovs-vsctl add-br br-phys
5491ovn_attach n1 br-phys 192.168.0.1
5492ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5493 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5494 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5495 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5496 ofport-request=1
5497ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5498 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5499 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5500 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5501 ofport-request=2
5502
5503# Allow some time for ovn-northd and ovn-controller to catch up.
5504# XXX This should be more systematic.
5505sleep 1
5506
5507echo "---------NB dump-----"
5508ovn-nbctl show
5509echo "---------------------"
5510ovn-nbctl list logical_router
5511echo "---------------------"
5512ovn-nbctl list logical_router_port
5513echo "---------------------"
5514
5515echo "---------SB dump-----"
5516ovn-sbctl list datapath_binding
5517echo "---------------------"
5518ovn-sbctl list port_binding
5519echo "---------------------"
5520ovn-sbctl dump-flows
5521echo "---------------------"
5522ovn-sbctl list chassis
5523ovn-sbctl list encap
5524echo "---------------------"
5525
5526echo "------Flows dump-----"
5527as hv1
5528ovs-ofctl dump-flows
5529echo "---------------------"
5530
5531ip_to_hex() {
5532 printf "%02x%02x%02x%02x" "$@"
5533}
5534
5535src_mac="f00000000003"
5536dst_mac="f00000000001"
5537src_ip=`ip_to_hex 192 168 0 2`
5538dst_ip=`ip_to_hex 8 8 8 8`
5539packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5540
5541# Send IP packet destined to 8.8.8.8 from lsp1lp2
5542as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5543
5544trim_zeros() {
5545 sed 's/\(00\)\{1,\}$//'
5546}
5547
5548# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5549# not 8.8.8.8
5550
5551$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5552expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5553echo $expected > expout
5554AT_CHECK([cat packets], [0], [expout])
5555cat packets
5556
5557OVN_CLEANUP([hv1])
5558
5559AT_CLEANUP
8439c2eb
CSV
5560
5561AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5562AT_SKIP_IF([test $HAVE_PYTHON = no])
5563ovn_start
5564# Create logical switch
5565ovn-nbctl ls-add ls0
5566# Create gateway router
5567ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5568# Add router port to gateway router
5569ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5570ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5571 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
5572# Add nat-address option
5573ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5574
5575net_add n1
5576sim_add hv1
5577as hv1
5578ovs-vsctl \
5579 -- add-br br-phys \
5580 -- add-br br-eth0
5581
5582ovn_attach n1 br-phys 192.168.0.1
5583
5584AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5585AT_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])
5586
5587# Create a localnet port.
5588AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5589AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5590AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5591AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5592
5593
5594# Wait for packet to be received.
5595OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5596trim_zeros() {
5597 sed 's/\(00\)\{1,\}$//'
5598}
5599$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5600expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5601echo $expected > expout
5602AT_CHECK([sort packets], [0], [expout])
5603cat packets
5604
5605OVN_CLEANUP([hv1])
5606
5607AT_CLEANUP
6e31816f 5608
e914fb54
MS
5609AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5610AT_SKIP_IF([test $HAVE_PYTHON = no])
5611ovn_start
5612# Create logical switch
5613ovn-nbctl ls-add ls0
5614# Create gateway router
5615ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5616# Add router port to gateway router
5617ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5618ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5619 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
5620# Add nat-address option
5621ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5622# Add NAT rules
5623AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5624AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5625# Add load balancers
5626AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5627AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5628AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5629AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5630
5631net_add n1
5632sim_add hv1
5633as hv1
5634ovs-vsctl \
5635 -- add-br br-phys \
5636 -- add-br br-eth0
5637
5638ovn_attach n1 br-phys 192.168.0.1
5639
5640AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5641AT_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])
5642
5643# Create a localnet port.
5644AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5645AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5646AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5647AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5648
5649
5650# Wait for packet to be received.
5651OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5652trim_zeros() {
5653 sed 's/\(00\)\{1,\}$//'
5654}
5655$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5656expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5657echo $expected > expout
5658expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5659echo $expected >> expout
5660expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5661echo $expected >> expout
5662AT_CHECK([sort packets], [0], [expout])
5663cat packets
5664
5665OVN_CLEANUP([hv1])
5666
5667AT_CLEANUP
5668
6e31816f 5669AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
5670ovn_start
5671net_add n1
5672sim_add hv1
5673as hv1
5674ovs-vsctl -- add-br br-phys
5675ovn_attach n1 br-phys 192.168.0.1
5676# Create logical switch ls0
5677ovn-nbctl ls-add ls0
5678# Create ports lp0, lp1 in ls0
5679ovn-nbctl lsp-add ls0 lp0
5680ovn-nbctl lsp-add ls0 lp1
5681ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5682ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5683dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5684ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5685ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5686ovn-sbctl find MAC_Binding
093aa761 5687# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5688ovn-nbctl lsp-del lp0
5689ovn-sbctl find MAC_Binding
093aa761
BP
5690OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5691# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5692ovn-nbctl ls-del ls0
5693ovn-sbctl find MAC_Binding
093aa761 5694OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
5695
5696OVN_CLEANUP([hv1])
5697
5698AT_CLEANUP
926c34fd
RM
5699
5700AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
5701AT_SKIP_IF([test $HAVE_PYTHON = no])
5702ovn_start
5703
5704# Logical network:
5705# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5706# connected to a router R1.
5707# foo has foo1 to act as a client.
5708# bar has bar1, bar2, bar3 to act as servers.
5709
5710net_add n1
5711
5712sim_add hv1
5713as hv1
5714ovs-vsctl add-br br-phys
5715ovn_attach n1 br-phys 192.168.0.1
5716for i in foo1 bar1 bar2 bar3; do
5717 ovs-vsctl -- add-port br-int $i -- \
5718 set interface $i external-ids:iface-id=$i \
5719 options:tx_pcap=hv1/$i-tx.pcap \
5720 options:rxq_pcap=hv1/$i-rx.pcap
5721done
5722
5723ovn-nbctl create Logical_Router name=R1
5724ovn-nbctl ls-add foo
5725ovn-nbctl ls-add bar
5726
5727# Connect foo to R1
5728ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5729ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5730 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5731
5732# Connect bar to R1
5733ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5734ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5735 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5736
5737# Create logical port foo1 in foo
5738ovn-nbctl lsp-add foo foo1 \
5739-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5740
5741# Create logical port bar1, bar2 and bar3 in bar
5742for i in `seq 1 3`; do
5743 ip=`expr $i + 1`
5744 ovn-nbctl lsp-add bar bar$i \
5745 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5746done
5747
5748OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5749
5750OVN_CLEANUP([hv1])
5751
5752AT_CLEANUP
b511690b
GS
5753
5754AT_SETUP([ovn -- tag allocation])
b511690b
GS
5755ovn_start
5756
5757AT_CHECK([ovn-nbctl ls-add ls0])
5758AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5759AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5760AT_CHECK([ovn-nbctl ls-add ls1])
5761
5762dnl When a tag is provided, no allocation is done
5763AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5764AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5765])
5766dnl The same 'tag' gets created in southbound database.
5767AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5768logical_port="c0"], [0], [3
5769])
5770
5771dnl Allocate tags and see it getting created in both NB and SB
5772AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5773AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5774])
5775AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5776logical_port="c1"], [0], [1
5777])
5778
5779AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5780AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5781])
5782AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5783logical_port="c2"], [0], [2
5784])
5785AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5786AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5787])
5788AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5789logical_port="c3"], [0], [4
5790])
5791
5792dnl A different parent.
5793AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5794AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5795])
5796AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5797logical_port="c4"], [0], [1
5798])
5799
5800AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5801AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5802])
5803AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5804logical_port="c5"], [0], [2
5805])
5806
5807dnl Delete a logical port and create a new one.
5808AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5809AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5810AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5811])
5812AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5813logical_port="c6"], [0], [1
5814])
5815
5816dnl Restart northd to see that the same allocation remains.
5817as northd
5818OVS_APP_EXIT_AND_WAIT([ovn-northd])
5819start_daemon ovn-northd \
5820 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5821 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5822
5823dnl Create a switch to make sure that ovn-northd has run through the main loop.
5824AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5825AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5826])
5827AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5828])
5829AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5830])
5831AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5832])
5833AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5834])
5835AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5836])
5837
5838dnl Create a switch port with a tag that has already been allocated.
5839dnl It should go through fine with a duplicate tag.
5840AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5841AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5842])
5843AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5844logical_port="c7"], [0], [2
5845])
5846AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5847])
5848
5849AT_CHECK([ovn-nbctl ls-add ls2])
5850dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5851dnl gets copied to 'tag'
5852AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5853AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5854])
5855dnl The same 'tag' gets created in southbound database.
5856AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5857logical_port="local0"], [0], [25
5858])
5859dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5860AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5861AT_CHECK([ovn-nbctl lsp-get-tag local1])
5862dnl change the tag_request.
5863AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5864AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5865])
5866
5867AT_CLEANUP
57afd0c0
RR
5868
5869AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
5870ovn_start
5871ovn-nbctl ls-add lsw0
5872net_add n1
5873for i in 1 2; do
5874 sim_add hv$i
5875 as hv$i
5876 ovs-vsctl add-br br-phys
5877 ovn_attach n1 br-phys 192.168.0.$i
5878 ovs-vsctl add-br br-eth0
5879 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5880done
5881
5882# Create a localnet port.
5883AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5884AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5885AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5886AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5887
5888
5889# Create 3 vifs.
5890AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5891AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5892AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5893AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5894AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5895AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5896AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5897AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5898AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5899
5900# Bind the localvif1 to hv1.
5901as hv1
5902AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5903
5904# On hv1, check that there are no flows outputting bcast to tunnel
5905OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5906
1ea9b847 5907# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 5908as hv2
1ea9b847 5909OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
5910
5911# Now bind vif2 on hv2.
5912AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5913
5914# At this point, the broadcast flow on vif2 should be deleted.
5915# because, there is now a localnet vif bound (table=32 programming logic)
5916OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5917
5918# Verify that the local net patch port exists on hv2.
5919OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5920
5921# Now bind vif3 on hv2.
5922AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5923
5924# Verify that the local net patch port still exists on hv2
5925OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5926
5927# Delete localvif2
5928AT_CHECK([ovn-nbctl lsp-del localvif2])
5929
5930# Verify that the local net patch port still exists on hv2,
5931# because, localvif3 is still bound.
5932OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5933
57afd0c0 5934OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
5935
5936AT_CLEANUP
5937
d383eed5
JP
5938
5939AT_SETUP([ovn -- ACL logging])
5940AT_KEYWORDS([ovn])
5941ovn_start
5942
5943net_add n1
5944
5945sim_add hv
5946as hv
5947ovs-vsctl add-br br-phys
5948ovn_attach n1 br-phys 192.168.0.1
5949for i in lp1 lp2; do
5950 ovs-vsctl -- add-port br-int $i -- \
5951 set interface $i external-ids:iface-id=$i \
5952 options:tx_pcap=hv/$i-tx.pcap \
5953 options:rxq_pcap=hv/$i-rx.pcap
5954done
5955
5956lp1_mac="f0:00:00:00:00:01"
5957lp1_ip="192.168.1.2"
5958
5959lp2_mac="f0:00:00:00:00:02"
5960lp2_ip="192.168.1.3"
5961
5962ovn-nbctl ls-add lsw0
5963ovn-nbctl --wait=sb lsp-add lsw0 lp1
5964ovn-nbctl --wait=sb lsp-add lsw0 lp2
5965ovn-nbctl lsp-set-addresses lp1 $lp1_mac
5966ovn-nbctl lsp-set-addresses lp2 $lp2_mac
5967ovn-nbctl --wait=sb sync
5968
5969ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
5970ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
5971
5972ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
5973ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
5974
5975ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
5976ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
5977
5978ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
5979ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
5980
5981ovn-sbctl dump-flows
5982
5983
5984# Send packet that should be dropped without logging.
5985packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5986 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5987 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
5988as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5989
5990# Send packet that should be dropped with logging.
5991packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5992 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5993 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
5994as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5995
5996# Send packet that should be allowed without logging.
5997packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5998 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5999 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6000as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6001
6002# Send packet that should be allowed with logging.
6003packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6004 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6005 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6006as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6007
6008# Send packet that should allow related flows without logging.
6009packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6010 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6011 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6012as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6013
6014# Send packet that should allow related flows with logging.
6015packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6016 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6017 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6018as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6019
df48cfc7 6020# Send packet that should be rejected without logging.
d383eed5
JP
6021packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6022 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6023 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6024as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6025
df48cfc7 6026# Send packet that should be rejected with logging.
d383eed5
JP
6027packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6028 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6029 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6030as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6031
c1f272f9
NS
6032OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6033
d383eed5
JP
6034AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6035name="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
6036name="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
6037name="<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
6038name="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
6039])
6040
6041OVN_CLEANUP([hv])
6042AT_CLEANUP
6043
6044
66d89287 6045AT_SETUP([ovn -- DSCP marking and meter check])
1a03fc7d
BS
6046AT_KEYWORDS([ovn])
6047ovn_start
6048
6049ovn-nbctl ls-add lsw0
6050ovn-nbctl --wait=sb lsp-add lsw0 lp1
6051ovn-nbctl --wait=sb lsp-add lsw0 lp2
e50ed58a 6052ovn-nbctl --wait=sb lsp-add lsw0 lp3
1a03fc7d
BS
6053ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6054ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
e50ed58a 6055ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
1a03fc7d
BS
6056ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6057ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6058ovn-nbctl --wait=sb sync
6059net_add n1
6060sim_add hv
6061as hv
6062ovs-vsctl add-br br-phys
6063ovn_attach n1 br-phys 192.168.0.1
6064ovs-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
6065ovs-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
6066
6067AT_CAPTURE_FILE([trace])
6068ovn_trace () {
6069 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6070}
6071
6072# Extracts nw_tos from the final flow from ofproto/trace output and prints
6073# it on stdout. Prints "none" if no nw_tos was included.
6074get_final_nw_tos() {
6075 if flow=$(grep '^Final flow:' stdout); then :; else
6076 # The output didn't have a final flow.
6077 return 99
6078 fi
6079
6080 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6081 case $tos in
6082 '') echo none ;;
6083 *) echo $tos ;;
6084 esac
6085}
6086
6087# check_tos TOS
6088#
6089# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6090check_tos() {
6091 # First check with ovn-trace for logical flows.
6092 echo "checking for tos $1"
6093 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6094 echo 'output("lp2");') > expout
6095 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])
6096
6097 # Then re-check with ofproto/trace for a physical packet.
6098 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])
6099 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6100])
6101}
6102
6103# check at L2
6104AT_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");
6105])
6106AT_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])
6107AT_CHECK([get_final_nw_tos], [0], [none
6108])
6109
6110# check at L3 without dscp marking
6111check_tos 0
6112
6113# Mark DSCP with a valid value
e50ed58a 6114qos_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
6115AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6116])
1a03fc7d
BS
6117check_tos 48
6118
66d89287
GL
6119# check at hv without qos meter
6120AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6121])
6122
6123# Update the meter rate
6124ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6125
6126# check at hv with a qos meter table
6127AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6128])
6129AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6130])
6131
1a03fc7d
BS
6132# Update the DSCP marking
6133ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6134check_tos 63
6135
66d89287
GL
6136# Update the meter rate
6137ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6138
6139# check at hv with a qos meter table
6140AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6141])
6142AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6143])
6144
1a03fc7d
BS
6145ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6146check_tos 63
6147
6148# Disable DSCP marking
5ee33cbd
GL
6149ovn-nbctl --wait=hv qos-del lsw0
6150AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6151])
1a03fc7d
BS
6152check_tos 0
6153
66d89287
GL
6154# check at hv without qos meter
6155AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6156])
6157
e50ed58a
GL
6158# check meter with chassis not resident
6159ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6160AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6161])
6162
6163# check no meter table
6164AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6165])
6166AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6167])
6168
1a03fc7d 6169OVN_CLEANUP([hv])
57afd0c0 6170AT_CLEANUP
7fff4eb7
LR
6171
6172AT_SETUP([ovn -- read-only sb db:ptcp access])
6173AT_SKIP_IF([test $HAVE_PYTHON = no])
6174
6175: > .$1.db.~lock~
6176ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6177
6178# Add read-only remote to sb ovsdb-server
6179AT_CHECK(
6180 [ovsdb-tool transact ovn-sb.db \
6181 ['["OVN_Southbound",
6182 {"op": "insert",
6183 "table": "SB_Global",
6184 "row": {
6185 "connections": ["set", [["named-uuid", "xyz"]]]}},
6186 {"op": "insert",
6187 "table": "Connection",
6188 "uuid-name": "xyz",
6189 "row": {"target": "ptcp:0:127.0.0.1",
6190 "read_only": true}}]']], [0], [ignore], [ignore])
6191
6192start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6193
6194PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6195
6196# read-only accesses should succeed
6197AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6198AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6199
6200# write access should fail
6201AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6202[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6203])
6204
6205OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6206AT_CLEANUP
6207
6208AT_SETUP([ovn -- read-only sb db:pssl access])
6209AT_SKIP_IF([test $HAVE_PYTHON = no])
6210AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6211PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6212AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6213\\]"])
6214
6215: > .$1.db.~lock~
6216ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6217
6218# Add read-only remote to sb ovsdb-server
6219AT_CHECK(
6220 [ovsdb-tool transact ovn-sb.db \
6221 ['["OVN_Southbound",
6222 {"op": "insert",
6223 "table": "SB_Global",
6224 "row": {
6225 "connections": ["set", [["named-uuid", "xyz"]]]}},
6226 {"op": "insert",
6227 "table": "Connection",
6228 "uuid-name": "xyz",
6229 "row": {"target": "pssl:0:127.0.0.1",
6230 "read_only": true}}]']], [0], [ignore], [ignore])
6231
6232start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6233 --remote=db:OVN_Southbound,SB_Global,connections \
6234 --private-key="$PKIDIR/testpki-privkey2.pem" \
6235 --certificate="$PKIDIR/testpki-cert2.pem" \
6236 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6237 ovn-sb.db
6238
6239PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6240
6241# read-only accesses should succeed
6242AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6243 --private-key=$PKIDIR/testpki-privkey.pem \
6244 --certificate=$PKIDIR/testpki-cert.pem \
6245 --ca-cert=$PKIDIR/testpki-cacert.pem \
6246 list SB_Global], [0], [stdout], [ignore])
6247AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6248 --private-key=$PKIDIR/testpki-privkey.pem \
6249 --certificate=$PKIDIR/testpki-cert.pem \
6250 --ca-cert=$PKIDIR/testpki-cacert.pem \
6251 list Connection], [0], [stdout], [ignore])
6252
6253# write access should fail
6254AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6255 --private-key=$PKIDIR/testpki-privkey.pem \
6256 --certificate=$PKIDIR/testpki-cert.pem \
6257 --ca-cert=$PKIDIR/testpki-cacert.pem \
6258 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6259[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6260])
6261
6262OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6263AT_CLEANUP
6264
821302cf
LR
6265AT_SETUP([ovn -- nb connection/ssl commands])
6266AT_SKIP_IF([test $HAVE_PYTHON = no])
6267AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6268PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6269AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6270\\]"])
6271
6272: > .$1.db.~lock~
6273ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6274
6275# Start nb db server using db connection/ssl entries (unpopulated initially)
6276start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6277 --remote=db:OVN_Northbound,NB_Global,connections \
6278 --private-key=db:OVN_Northbound,SSL,private_key \
6279 --certificate=db:OVN_Northbound,SSL,certificate \
6280 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6281 ovn-nb.db
6282
6283# Populate SSL configuration entries in nb db
6284AT_CHECK(
6285 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6286 $PKIDIR/testpki-cert.pem \
6287 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6288
6289# Populate a passive SSL connection in nb db
6290AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6291
6292PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6293
6294# Verify SSL connetivity to nb db server
6295AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6296 --private-key=$PKIDIR/testpki-privkey.pem \
6297 --certificate=$PKIDIR/testpki-cert.pem \
6298 --ca-cert=$PKIDIR/testpki-cacert.pem \
6299 list NB_Global],
6300 [0], [stdout], [ignore])
6301AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6302 --private-key=$PKIDIR/testpki-privkey.pem \
6303 --certificate=$PKIDIR/testpki-cert.pem \
6304 --ca-cert=$PKIDIR/testpki-cacert.pem \
6305 list Connection],
6306 [0], [stdout], [ignore])
6307AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6308 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6309 --certificate=$PKIDIR/testpki-cert.pem \
6310 --ca-cert=$PKIDIR/testpki-cacert.pem \
6311 get-connection],
6312 [0], [stdout], [ignore])
6313
6314OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6315AT_CLEANUP
6316
6317AT_SETUP([ovn -- sb connection/ssl commands])
6318AT_SKIP_IF([test $HAVE_PYTHON = no])
6319AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6320PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6321AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6322\\]"])
6323
6324: > .$1.db.~lock~
6325ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6326
6327# Start sb db server using db connection/ssl entries (unpopulated initially)
6328start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6329 --remote=db:OVN_Southbound,SB_Global,connections \
6330 --private-key=db:OVN_Southbound,SSL,private_key \
6331 --certificate=db:OVN_Southbound,SSL,certificate \
6332 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6333 ovn-sb.db
6334
6335# Populate SSL configuration entries in sb db
6336AT_CHECK(
6337 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6338 $PKIDIR/testpki-cert.pem \
6339 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6340
6341# Populate a passive SSL connection in sb db
6342AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6343
6344PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6345
6346# Verify SSL connetivity to sb db server
6347AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6348 --private-key=$PKIDIR/testpki-privkey.pem \
6349 --certificate=$PKIDIR/testpki-cert.pem \
6350 --ca-cert=$PKIDIR/testpki-cacert.pem \
6351 list SB_Global],
6352 [0], [stdout], [ignore])
6353AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6354 --private-key=$PKIDIR/testpki-privkey.pem \
6355 --certificate=$PKIDIR/testpki-cert.pem \
6356 --ca-cert=$PKIDIR/testpki-cacert.pem \
6357 list Connection],
6358 [0], [stdout], [ignore])
6359AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6360 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
6361 --certificate=$PKIDIR/testpki-cert.pem \
6362 --ca-cert=$PKIDIR/testpki-cacert.pem \
6363 get-connection],
6364 [0], [stdout], [ignore])
6365
6366OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6367AT_CLEANUP
6368
75fd74f8
GS
6369AT_SETUP([ovn -- nested containers])
6370ovn_start
6371
6372# Physical network:
6373# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6374
6375# Logical network:
6376# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6377# and "bar" (192.168.2.0/24). They are all connected to router R1.
6378
6379ovn-nbctl lr-add R1
6380ovn-nbctl ls-add mgmt
6381ovn-nbctl ls-add foo
6382ovn-nbctl ls-add bar
6383
6384# Connect mgmt to R1
6385ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6386ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6387 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6388
6389# Connect foo to R1
6390ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6391ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6392 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6393
6394# Connect bar to R1
6395ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6396ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6397 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6398
6399# "mgmt" has VM1 and VM2 connected
6400ovn-nbctl lsp-add mgmt vm1 \
6401-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6402
6403ovn-nbctl lsp-add mgmt vm2 \
6404-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6405
6406# "foo1" and "foo2" are containers belonging to switch "foo"
6407# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6408ovn-nbctl lsp-add foo foo1 vm1 1 \
6409-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6410
6411ovn-nbctl lsp-add foo foo2 vm2 2 \
6412-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6413
6414# "bar1" and "bar2" are containers belonging to switch "bar"
6415# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6416ovn-nbctl lsp-add bar bar1 vm1 2 \
6417-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6418
6419ovn-nbctl lsp-add bar bar2 vm2 1 \
6420-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6421
6422# bar3 is a standalone VM belonging to switch "bar"
6423ovn-nbctl lsp-add bar bar3 \
6424-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6425
6426# Create two hypervisor and create OVS ports corresponding to logical ports.
6427net_add n1
6428
6429sim_add hv1
6430as hv1
6431ovs-vsctl add-br br-phys
6432ovn_attach n1 br-phys 192.168.0.1
6433ovs-vsctl -- add-port br-int vm1 -- \
6434 set interface vm1 external-ids:iface-id=vm1 \
6435 options:tx_pcap=hv1/vm1-tx.pcap \
6436 options:rxq_pcap=hv1/vm1-rx.pcap \
6437 ofport-request=1
6438
6439ovs-vsctl -- add-port br-int bar3 -- \
6440 set interface bar3 external-ids:iface-id=bar3 \
6441 options:tx_pcap=hv1/bar3-tx.pcap \
6442 options:rxq_pcap=hv1/bar3-rx.pcap \
6443 ofport-request=2
6444
6445sim_add hv2
6446as hv2
6447ovs-vsctl add-br br-phys
6448ovn_attach n1 br-phys 192.168.0.2
6449ovs-vsctl -- add-port br-int vm2 -- \
6450 set interface vm2 external-ids:iface-id=vm2 \
6451 options:tx_pcap=hv2/vm2-tx.pcap \
6452 options:rxq_pcap=hv2/vm2-rx.pcap \
6453 ofport-request=1
6454
6455# Pre-populate the hypervisors' ARP tables so that we don't lose any
6456# packets for ARP resolution (native tunneling doesn't queue packets
6457# for ARP resolution).
74868f2c 6458OVN_POPULATE_ARP
75fd74f8
GS
6459
6460# Allow some time for ovn-northd and ovn-controller to catch up.
6461# XXX This should be more systematic.
6462sleep 1
6463
6464ip_to_hex() {
6465 printf "%02x%02x%02x%02x" "$@"
6466}
6467
6468# Send ip packets between foo1 and foo2 (same switch, different HVs and
6469# different VLAN tags).
6470src_mac="f00000010205"
6471dst_mac="f00000010206"
6472src_ip=`ip_to_hex 192 168 1 2`
6473dst_ip=`ip_to_hex 192 168 1 3`
6474packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6475as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6476
6477# expected packet at foo2
6478packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6479echo $packet > expected
6480OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6481
6482# Send ip packets between foo1 and bar2 (different switch, different HV)
6483src_mac="f00000010205"
6484dst_mac="000000010203"
6485src_ip=`ip_to_hex 192 168 1 2`
6486dst_ip=`ip_to_hex 192 168 2 3`
6487packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6488as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6489
6490# expected packet at bar2
6491src_mac="000000010204"
6492dst_mac="f00000010208"
6493packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6494echo $packet >> expected
6495OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6496
6497# Send ip packets between foo1 and bar1
6498# (different switch, loopback to same vm but different tag)
6499src_mac="f00000010205"
6500dst_mac="000000010203"
6501src_ip=`ip_to_hex 192 168 1 2`
6502dst_ip=`ip_to_hex 192 168 2 2`
6503packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6504as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6505
6506# expected packet at bar1
6507src_mac="000000010204"
6508dst_mac="f00000010207"
6509packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6510echo $packet > expected1
6511OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6512
6513# Send ip packets between bar1 and bar3
6514# (same switch. But one is container and another is a standalone VM)
6515src_mac="f00000010207"
6516dst_mac="f00000010209"
6517src_ip=`ip_to_hex 192 168 2 2`
6518dst_ip=`ip_to_hex 192 168 2 3`
6519packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6520as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6521
6522# expected packet at bar3
6523packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6524echo $packet > expected
6525OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6526
6527# Send ip packets between foo1 and vm1.
6528(different switch, container to the VM hosting it.)
6529src_mac="f00000010205"
6530dst_mac="000000010203"
6531src_ip=`ip_to_hex 192 168 1 2`
6532dst_ip=`ip_to_hex 172 16 1 2`
6533packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6534as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6535
6536# expected packet at vm1
6537src_mac="000000010202"
6538dst_mac="f00000010203"
6539packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6540echo $packet >> expected1
6541OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6542
6543# Send packets from vm1 to bar1.
6544(different switch, A hosting VM to a container inside it)
6545src_mac="f00000010203"
6546dst_mac="000000010202"
6547src_ip=`ip_to_hex 172 16 1 2`
6548dst_ip=`ip_to_hex 192 168 2 2`
6549packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6550as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6551
6552# expected packet at vm1
6553src_mac="000000010204"
6554dst_mac="f00000010207"
6555packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6556echo $packet >> expected1
6557OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6558
6559OVN_CLEANUP([hv1],[hv2])
6560
6561AT_CLEANUP
440a9f4b
GS
6562
6563AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6564AT_SKIP_IF([test $HAVE_PYTHON = no])
6565ovn_start
6566
6567# Logical network:
6568# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6569# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6570# (192.168.2.0/24) connected to it.
6571#
6572# R2 and R3 are gateway routers.
6573# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6574# connected to it. Note how both alice and bob have the same subnet behind it.
6575# We are trying to simulate external network via those 2 switches. In real
6576# world the switch ports of these switches will have addresses set as "unknown"
6577# to make them learning switches. Or those switches will be "localnet" ones.
6578
6579# Create three hypervisors and create OVS ports corresponding to logical ports.
6580net_add n1
6581
6582sim_add hv1
6583as hv1
6584ovs-vsctl add-br br-phys
6585ovn_attach n1 br-phys 192.168.0.1
6586ovs-vsctl -- add-port br-int hv1-vif1 -- \
6587 set interface hv1-vif1 external-ids:iface-id=foo1 \
6588 options:tx_pcap=hv1/vif1-tx.pcap \
6589 options:rxq_pcap=hv1/vif1-rx.pcap \
6590 ofport-request=1
6591
6592ovs-vsctl -- add-port br-int hv1-vif2 -- \
6593 set interface hv1-vif2 external-ids:iface-id=bar1 \
6594 options:tx_pcap=hv1/vif2-tx.pcap \
6595 options:rxq_pcap=hv1/vif2-rx.pcap \
6596 ofport-request=2
6597
6598sim_add hv2
6599as hv2
6600ovs-vsctl add-br br-phys
6601ovn_attach n1 br-phys 192.168.0.2
6602ovs-vsctl -- add-port br-int hv2-vif1 -- \
6603 set interface hv2-vif1 external-ids:iface-id=alice1 \
6604 options:tx_pcap=hv2/vif1-tx.pcap \
6605 options:rxq_pcap=hv2/vif1-rx.pcap \
6606 ofport-request=1
6607
6608sim_add hv3
6609as hv3
6610ovs-vsctl add-br br-phys
6611ovn_attach n1 br-phys 192.168.0.3
6612ovs-vsctl -- add-port br-int hv3-vif1 -- \
6613 set interface hv3-vif1 external-ids:iface-id=bob1 \
6614 options:tx_pcap=hv3/vif1-tx.pcap \
6615 options:rxq_pcap=hv3/vif1-rx.pcap \
6616 ofport-request=1
6617
6618
6619ovn-nbctl create Logical_Router name=R1
6620ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6621ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6622
6623ovn-nbctl ls-add foo
6624ovn-nbctl ls-add bar
6625ovn-nbctl ls-add alice
6626ovn-nbctl ls-add bob
6627ovn-nbctl ls-add join
6628
6629# Connect foo to R1
6630ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6631ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6632 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6633
6634# Connect bar to R1
6635ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6636ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6637 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6638
6639# Connect alice to R2
6640ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6641ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6642 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6643
6644# Connect bob to R3
6645ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6646ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6647 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6648
6649# Connect R1 to join
6650ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6651ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6652 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6653
6654# Connect R2 to join
6655ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6656ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6657 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6658
6659# Connect R3 to join
6660ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6661ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6662 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6663
6664# Install static routes with source ip address as the policy for routing.
6665# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6666ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6667ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6668
6669# Install static routes with destination ip address as the policy for routing.
6670ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6671
6672ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6673
6674# Create logical port foo1 in foo
6675ovn-nbctl lsp-add foo foo1 \
6676-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6677
6678# Create logical port bar1 in bar
6679ovn-nbctl lsp-add bar bar1 \
6680-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6681
6682# Create logical port alice1 in alice
6683ovn-nbctl lsp-add alice alice1 \
6684-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6685
6686# Create logical port bob1 in bob
6687ovn-nbctl lsp-add bob bob1 \
6688-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6689
6690# Pre-populate the hypervisors' ARP tables so that we don't lose any
6691# packets for ARP resolution (native tunneling doesn't queue packets
6692# for ARP resolution).
74868f2c 6693OVN_POPULATE_ARP
440a9f4b
GS
6694
6695# Allow some time for ovn-northd and ovn-controller to catch up.
6696# XXX This should be more systematic.
6697sleep 1
6698
6699ip_to_hex() {
6700 printf "%02x%02x%02x%02x" "$@"
6701}
6702trim_zeros() {
6703 sed 's/\(00\)\{1,\}$//'
6704}
6705
6706# Send ip packets between foo1 and bar1
6707# (East-west traffic should flow normally)
6708src_mac="f00000010203"
6709dst_mac="000001010203"
6710src_ip=`ip_to_hex 192 168 1 2`
6711dst_ip=`ip_to_hex 192 168 2 2`
6712packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6713as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6714
6715# Send ip packets between foo1 and alice1
6716src_mac="f00000010203"
6717dst_mac="000001010203"
6718src_ip=`ip_to_hex 192 168 1 2`
6719dst_ip=`ip_to_hex 172 16 1 3`
6720packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6721as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 6722as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
6723
6724# Send ip packets between bar1 and bob1
6725src_mac="f00000010204"
6726dst_mac="000001010204"
6727src_ip=`ip_to_hex 192 168 2 2`
6728dst_ip=`ip_to_hex 172 16 1 4`
6729packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6730as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6731#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6732
6733# Packet to expect at bar1
6734src_mac="000001010204"
6735dst_mac="f00000010204"
6736src_ip=`ip_to_hex 192 168 1 2`
6737dst_ip=`ip_to_hex 192 168 2 2`
6738expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6739echo $expected > expected
6740OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6741
6742# Packet to Expect at alice1
6743src_mac="000002010203"
6744dst_mac="f00000010205"
6745src_ip=`ip_to_hex 192 168 1 2`
6746dst_ip=`ip_to_hex 172 16 1 3`
6747expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6748echo $expected > expected
6749OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6750
6751# Packet to Expect at bob1
6752src_mac="000003010203"
6753dst_mac="f00000010206"
6754src_ip=`ip_to_hex 192 168 2 2`
6755dst_ip=`ip_to_hex 172 16 1 4`
6756expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6757echo $expected > expected
6758OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6759
6760for sim in hv1 hv2 hv3; do
6761 as $sim
6762 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6763 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6764 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6765done
6766
6767as ovn-sb
6768OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6769
6770as ovn-nb
6771OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6772
6773as northd
6774OVS_APP_EXIT_AND_WAIT([ovn-northd])
6775
6776as main
6777OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6778OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6779
6780AT_CLEANUP
41a15b71 6781
302eda27
NS
6782AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6783AT_SKIP_IF([test $HAVE_PYTHON = no])
6784ovn_start
6785
6786ovn-nbctl ls-add ls1
6787
6788ovn-nbctl lsp-add ls1 ls1-lp1 \
6789-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6790
6791ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6792
6793ovn-nbctl lsp-add ls1 ls1-lp2 \
6794-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6795
6796ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6797
6798DNS1=`ovn-nbctl create DNS records={}`
6799DNS2=`ovn-nbctl create DNS records={}`
6800
6801ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6802ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6803ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6804
6805ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6806
6807net_add n1
6808sim_add hv1
6809
6810as hv1
6811ovs-vsctl add-br br-phys
6812ovn_attach n1 br-phys 192.168.0.1
6813ovs-vsctl -- add-port br-int hv1-vif1 -- \
6814 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6815 options:tx_pcap=hv1/vif1-tx.pcap \
6816 options:rxq_pcap=hv1/vif1-rx.pcap \
6817 ofport-request=1
6818
6819ovs-vsctl -- add-port br-int hv1-vif2 -- \
6820 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6821 options:tx_pcap=hv1/vif2-tx.pcap \
6822 options:rxq_pcap=hv1/vif2-rx.pcap \
6823 ofport-request=2
6824
74868f2c 6825OVN_POPULATE_ARP
302eda27
NS
6826sleep 2
6827as hv1 ovs-vsctl show
6828
6829echo "*************************"
6830ovn-sbctl list DNS
6831echo "*************************"
6832
6833ip_to_hex() {
6834 printf "%02x%02x%02x%02x" "$@"
6835}
6836
6837reset_pcap_file() {
6838 local iface=$1
6839 local pcap_file=$2
6840 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6841options:rxq_pcap=dummy-rx.pcap
6842 rm -f ${pcap_file}*.pcap
6843 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6844options:rxq_pcap=${pcap_file}-rx.pcap
6845}
6846
6847# set_dns_params host_name
6848# Sets the dns_req_data and dns_resp_data
6849set_dns_params() {
6850 local hname=$1
6851 local ttl=00000e10
6852 an_count=0001
6853 type=0001
6854 case $hname in
6855 vm1)
6856 # vm1.ovn.org
6857 query_name=03766d31036f766e036f726700
6858 # IPv4 address - 10.0.0.4
6859 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6860 ;;
6861 vm2)
6862 # vm2.ovn.org
6863 query_name=03766d32036f766e036f726700
6864 # IPv4 address - 10.0.0.6
6865 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6866 # IPv4 address - 20.0.0.4
6867 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6868 an_count=0002
6869 ;;
6870 vm3)
6871 # vm3.ovn.org
6872 query_name=03766d33036f766e036f726700
6873 # IPv4 address - 40.0.0.4
6874 expected_dns_answer=${query_name}00010001${ttl}000428000004
6875 ;;
6876 vm1_ipv6_only)
6877 # vm1.ovn.org
6878 query_name=03766d31036f766e036f726700
6879 # IPv6 address - aef0::4
6880 type=001c
6881 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6882 ;;
6883 vm1_ipv4_v6)
6884 # vm1.ovn.org
6885 query_name=03766d31036f766e036f726700
6886 type=00ff
6887 an_count=0002
6888 # IPv4 address - 10.0.0.4
6889 # IPv6 address - aef0::4
6890 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6891 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
6892 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
6893 ;;
6894 vm1_invalid_type)
6895 # vm1.ovn.org
6896 query_name=03766d31036f766e036f726700
6897 # IPv6 address - aef0::4
6898 type=0002
6899 ;;
6900 vm1_incomplete)
6901 # set type to none
6902 type=''
6903 esac
6904 # TTL - 3600
6905 local dns_req_header=010201200001000000000000
6906 local dns_resp_header=010281200001${an_count}00000000
6907 dns_req_data=${dns_req_header}${query_name}${type}0001
6908 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
6909}
6910
6911# This shell function sends a DNS request packet
6912# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
6913test_dns() {
6914 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6915 local dns_query_data=$7
6916 shift; shift; shift; shift; shift; shift; shift;
6917 # Packet size => IPv4 header (20) + UDP header (8) +
6918 # DNS data (header + query)
6919 ip_len=`expr 28 + ${#dns_query_data} / 2`
6920 udp_len=`expr $ip_len - 20`
6921 ip_len=$(printf "%x" $ip_len)
6922 udp_len=$(printf "%x" $udp_len)
6923 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
6924 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
6925 # dns data
6926 request=${request}${dns_query_data}
6927
6928 if test $dns_reply != 0; then
6929 local dns_reply=$1
6930 ip_len=`expr 28 + ${#dns_reply} / 2`
6931 udp_len=`expr $ip_len - 20`
6932 ip_len=$(printf "%x" $ip_len)
6933 udp_len=$(printf "%x" $udp_len)
6934 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
6935 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
6936 echo $reply >> $inport.expected
6937 else
6938 for outport; do
6939 echo $request >> $outport.expected
6940 done
6941 fi
6942 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6943}
6944
f8e79d82
MM
6945test_dns6() {
6946 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6947 local dns_query_data=$7
6948 shift; shift; shift; shift; shift; shift; shift;
6949 # Packet size => UDP header (8) +
6950 # DNS data (header + query)
6951 ip_len=`expr 8 + ${#dns_query_data} / 2`
6952 udp_len=$ip_len
6953 ip_len=$(printf "%x" $ip_len)
6954 udp_len=$(printf "%x" $udp_len)
6955 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
6956 request=${request}9234003500${udp_len}0000
6957 #dns data
6958 request=${request}${dns_query_data}
6959
6960 if test $dns_reply != 0; then
6961 local dns_reply=$1
6962 ip_len=`expr 8 + ${#dns_reply} / 2`
6963 udp_len=$ip_len
6964 ip_len=$(printf "%x" $ip_len)
6965 udp_len=$(printf "%x" $udp_len)
6966 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
6967 reply=${reply}0035923400${udp_len}0000${dns_reply}
6968 echo $reply >> $inport.expected
6969 else
6970 for outport; do
6971 echo $request >> $outport.expected
6972 done
6973 fi
6974 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6975}
6976
302eda27
NS
6977AT_CAPTURE_FILE([ofctl_monitor0.log])
6978as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
6979--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
6980
6981set_dns_params vm2
6982src_ip=`ip_to_hex 10 0 0 4`
6983dst_ip=`ip_to_hex 10 0 0 1`
6984dns_reply=1
6985test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6986
6987# NXT_RESUMEs should be 1.
6988OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6989
6990$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6991cat 1.expected | cut -c -48 > expout
6992AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6993# Skipping the IPv4 checksum.
6994cat 1.expected | cut -c 53- > expout
6995AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6996
6997reset_pcap_file hv1-vif1 hv1/vif1
6998reset_pcap_file hv1-vif2 hv1/vif2
6999rm -f 1.expected
7000rm -f 2.expected
7001
7002set_dns_params vm1
7003src_ip=`ip_to_hex 10 0 0 6`
7004dst_ip=`ip_to_hex 10 0 0 1`
7005dns_reply=1
7006test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7007
7008# NXT_RESUMEs should be 2.
7009OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7010
7011$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7012cat 2.expected | cut -c -48 > expout
7013AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7014# Skipping the IPv4 checksum.
7015cat 2.expected | cut -c 53- > expout
7016AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7017
7018reset_pcap_file hv1-vif1 hv1/vif1
7019reset_pcap_file hv1-vif2 hv1/vif2
7020rm -f 1.expected
7021rm -f 2.expected
7022
7023# Clear the query name options for ls1-lp2
7024ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7025
7026set_dns_params vm2
7027src_ip=`ip_to_hex 10 0 0 4`
7028dst_ip=`ip_to_hex 10 0 0 1`
7029dns_reply=0
7030test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7031
7032# NXT_RESUMEs should be 3.
7033OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7034
7035$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7036AT_CHECK([cat 1.packets], [0], [])
7037
7038reset_pcap_file hv1-vif1 hv1/vif1
7039reset_pcap_file hv1-vif2 hv1/vif2
7040rm -f 1.expected
7041rm -f 2.expected
7042
7043# Clear the query name for ls1-lp1
7044# Since ls1 has no query names configued,
7045# ovn-northd should not add the DNS flows.
7046ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7047
7048set_dns_params vm1
7049src_ip=`ip_to_hex 10 0 0 6`
7050dst_ip=`ip_to_hex 10 0 0 1`
7051dns_reply=0
7052test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7053
7054# NXT_RESUMEs should be 3 only.
7055OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7056
7057$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7058AT_CHECK([cat 2.packets], [0], [])
7059
7060reset_pcap_file hv1-vif1 hv1/vif1
7061reset_pcap_file hv1-vif2 hv1/vif2
7062rm -f 1.expected
7063rm -f 2.expected
7064
7065# Test IPv6 (AAAA records) using IPv4 packet.
7066# Add back the DNS options for ls1-lp1.
7067ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7068
7069set_dns_params vm1_ipv6_only
7070src_ip=`ip_to_hex 10 0 0 6`
7071dst_ip=`ip_to_hex 10 0 0 1`
7072dns_reply=1
7073test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7074
7075# NXT_RESUMEs should be 4.
7076OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7077
7078$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7079cat 2.expected | cut -c -48 > expout
7080AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7081# Skipping the IPv4 checksum.
7082cat 2.expected | cut -c 53- > expout
7083AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7084
7085reset_pcap_file hv1-vif1 hv1/vif1
7086reset_pcap_file hv1-vif2 hv1/vif2
7087rm -f 1.expected
7088rm -f 2.expected
7089
7090# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7091set_dns_params vm1_ipv4_v6
7092src_ip=`ip_to_hex 10 0 0 6`
7093dst_ip=`ip_to_hex 10 0 0 1`
7094dns_reply=1
7095test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7096
7097# NXT_RESUMEs should be 5.
7098OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7099
7100$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7101cat 2.expected | cut -c -48 > expout
7102AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7103# Skipping the IPv4 checksum.
7104cat 2.expected | cut -c 53- > expout
7105AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7106
7107reset_pcap_file hv1-vif1 hv1/vif1
7108reset_pcap_file hv1-vif2 hv1/vif2
7109rm -f 1.expected
7110rm -f 2.expected
7111
7112# Invalid type.
7113set_dns_params vm1_invalid_type
7114src_ip=`ip_to_hex 10 0 0 6`
7115dst_ip=`ip_to_hex 10 0 0 1`
7116dns_reply=0
7117test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7118
7119# NXT_RESUMEs should be 6.
7120OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7121
7122$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7123AT_CHECK([cat 2.packets], [0], [])
7124
7125reset_pcap_file hv1-vif1 hv1/vif1
7126reset_pcap_file hv1-vif2 hv1/vif2
7127rm -f 1.expected
7128rm -f 2.expected
7129
7130# Incomplete DNS packet.
7131set_dns_params vm1_incomplete
7132src_ip=`ip_to_hex 10 0 0 6`
7133dst_ip=`ip_to_hex 10 0 0 1`
7134dns_reply=0
7135test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7136
7137# NXT_RESUMEs should be 7.
7138OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7139
7140$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7141AT_CHECK([cat 2.packets], [0], [])
7142
7143reset_pcap_file hv1-vif1 hv1/vif1
7144reset_pcap_file hv1-vif2 hv1/vif2
7145rm -f 1.expected
7146rm -f 2.expected
7147
7148# Add one more DNS record to the ls1.
7149ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7150
7151set_dns_params vm3
7152src_ip=`ip_to_hex 10 0 0 4`
7153dst_ip=`ip_to_hex 10 0 0 1`
7154dns_reply=1
7155test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7156
7157# NXT_RESUMEs should be 8.
7158OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7159
7160$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7161cat 1.expected | cut -c -48 > expout
7162AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7163# Skipping the IPv4 checksum.
7164cat 1.expected | cut -c 53- > expout
7165AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7166
7167reset_pcap_file hv1-vif1 hv1/vif1
7168reset_pcap_file hv1-vif2 hv1/vif2
7169rm -f 1.expected
7170rm -f 2.expected
7171
f8e79d82
MM
7172# Try DNS query over IPv6
7173set_dns_params vm1
7174src_ip=aef00000000000000000000000000004
7175dst_ip=aef00000000000000000000000000001
7176dns_reply=1
7177test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7178
7179# NXT_RESUMEs should be 9.
7180OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7181
7182$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
b75f2651
MM
7183# Skipping the UDP checksum.
7184cat 1.expected | cut -c 1-120,125- > expout
7185AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
f8e79d82
MM
7186
7187reset_pcap_file hv1-vif1 hv1/vif1
7188reset_pcap_file hv1-vif2 hv1/vif2
7189rm -f 1.expected
7190rm -f 2.expected
7191
302eda27
NS
7192as hv1
7193 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7194OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7195OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7196
7197as ovn-sb
7198OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7199
7200as ovn-nb
7201OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7202
7203as northd
7204OVS_APP_EXIT_AND_WAIT([ovn-northd])
7205
7206as main
7207OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7208OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7209AT_CLEANUP
7210
75f9e007 7211AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 7212AT_SKIP_IF([test $HAVE_PYTHON = no])
7213ovn_start
7214
7215net_add n1
7216
7217sim_add hv1
7218as hv1
7219ovs-vsctl add-br br-phys
7220ovn_attach n1 br-phys 192.168.0.1
7221ovs-vsctl -- add-port br-int hv1-vif1 -- \
7222 set interface hv1-vif1 external-ids:iface-id=foo1 \
7223 options:tx_pcap=hv1/vif1-tx.pcap \
7224 options:rxq_pcap=hv1/vif1-rx.pcap \
7225 ofport-request=1
7226
7227sim_add gw1
7228as gw1
7229ovs-vsctl add-br br-phys
7230ovn_attach n1 br-phys 192.168.0.2
7231
7232sim_add gw2
7233as gw2
7234ovs-vsctl add-br br-phys
7235ovn_attach n1 br-phys 192.168.0.4
7236
7237sim_add ext1
7238as ext1
7239ovs-vsctl add-br br-phys
7240ovn_attach n1 br-phys 192.168.0.3
7241ovs-vsctl -- add-port br-int ext1-vif1 -- \
7242 set interface ext1-vif1 external-ids:iface-id=outside1 \
7243 options:tx_pcap=ext1/vif1-tx.pcap \
7244 options:rxq_pcap=ext1/vif1-rx.pcap \
7245 ofport-request=1
7246
7247# Pre-populate the hypervisors' ARP tables so that we don't lose any
7248# packets for ARP resolution (native tunneling doesn't queue packets
7249# for ARP resolution).
74868f2c 7250OVN_POPULATE_ARP
1da17a0b 7251
7252ovn-nbctl create Logical_Router name=R1
7253
7254ovn-nbctl ls-add foo
7255ovn-nbctl ls-add alice
7256ovn-nbctl ls-add outside
7257
7258# Connect foo to R1
7259ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7260ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7261 type=router options:router-port=foo \
7262 -- lsp-set-addresses rp-foo router
7263
7264# Connect alice to R1 as distributed router gateway port on gw1
7265ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7266
7267ovn-nbctl \
7268 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7269 chassis_name=gw1 \
7270 priority=20 -- \
7271 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7272 chassis_name=gw2 \
7273 priority=10 -- \
7274 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7275
7276ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7277 type=router options:router-port=alice \
7278 -- lsp-set-addresses rp-alice router
7279
7280# Create logical port foo1 in foo
7281ovn-nbctl lsp-add foo foo1 \
7282-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7283
7284# Create logical port outside1 in outside
7285ovn-nbctl lsp-add outside outside1 \
7286-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7287
7288# Create localnet port in alice
7289ovn-nbctl lsp-add alice ln-alice
7290ovn-nbctl lsp-set-addresses ln-alice unknown
7291ovn-nbctl lsp-set-type ln-alice localnet
7292ovn-nbctl lsp-set-options ln-alice network_name=phys
7293
7294# Create localnet port in outside
7295ovn-nbctl lsp-add outside ln-outside
7296ovn-nbctl lsp-set-addresses ln-outside unknown
7297ovn-nbctl lsp-set-type ln-outside localnet
7298ovn-nbctl lsp-set-options ln-outside network_name=phys
7299
7300# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7301# mapping to the external network, is the one generating packets
7302as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7303as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7304as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7305
7306AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7307
7308# Allow some time for ovn-northd and ovn-controller to catch up.
7309# XXX This should be more systematic.
7310sleep 2
7311
7312ip_to_hex() {
7313 printf "%02x%02x%02x%02x" "$@"
7314}
7315
7316reset_pcap_file() {
7317 local iface=$1
7318 local pcap_file=$2
7319 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7320options:rxq_pcap=dummy-rx.pcap
7321 rm -f ${pcap_file}*.pcap
7322 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7323options:rxq_pcap=${pcap_file}-rx.pcap
7324}
7325
7326test_ip_packet()
7327{
7328 local active_gw=$1
7329 local backup_gw=$2
7330
7331 # Send ip packet between foo1 and outside1
7332 src_mac="f00000010203" # foo1 mac
7333 dst_mac="000001010203" # rp-foo mac (internal router leg)
7334 src_ip=`ip_to_hex 192 168 1 2`
7335 dst_ip=`ip_to_hex 172 16 1 3`
7336 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7337
7338 # ARP request packet to expect at outside1
7339 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7340
7341 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7342
7343 # Send ARP reply from outside1 back to the router
7344 # XXX: note, we could avoid this if we plug this port into a netns
7345 # and setup the IP address into the port, so the kernel would simply reply
7346 src_mac="000002010203"
7347 reply_mac="f00000010204"
7348 dst_ip=`ip_to_hex 172 16 1 3`
7349 src_ip=`ip_to_hex 172 16 1 1`
7350 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7351
7352 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7353
86c9d79a
NS
7354 OVS_WAIT_UNTIL([
7355 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7356grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7357 ])
7358
1da17a0b 7359 # Packet to Expect at ext1 chassis, outside1 port
7360 src_mac="000002010203"
7361 dst_mac="f00000010204"
7362 src_ip=`ip_to_hex 192 168 1 2`
7363 dst_ip=`ip_to_hex 172 16 1 3`
7364 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7365 echo $expected > ext1-vif1.expected
7366
7367 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7368 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7369 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7370
7371 # Resend packet from foo1 to outside1
7372 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7373
7374 sleep 1
7375
7376 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7377 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7378 AT_CHECK([grep $expected packets | sort], [0], [expout])
7379 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7380 AT_CHECK([grep $expected packets | sort], [0], [])
7381}
7382
7383test_ip_packet gw1 gw2
7384
75f9e007
GZ
7385ovn-nbctl --timeout=3 --wait=hv \
7386 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7387 chassis_name=gw1 \
7388 priority=10 -- \
7389 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7390 chassis_name=gw2 \
7391 priority=20 -- \
7392 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7393
7394test_ip_packet gw2 gw1
7395
7396OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7397AT_CLEANUP
7398
7399AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7400AT_SKIP_IF([test $HAVE_PYTHON = no])
7401ovn_start
7402
7403net_add n1
7404
7405sim_add hv1
7406as hv1
7407ovs-vsctl add-br br-phys
7408ovn_attach n1 br-phys 192.168.0.1
7409ovs-vsctl -- add-port br-int hv1-vif1 -- \
7410 set interface hv1-vif1 external-ids:iface-id=foo1 \
7411 options:tx_pcap=hv1/vif1-tx.pcap \
7412 options:rxq_pcap=hv1/vif1-rx.pcap \
7413 ofport-request=1
7414
7415sim_add gw1
7416as gw1
7417ovs-vsctl add-br br-phys
7418ovn_attach n1 br-phys 192.168.0.2
7419
7420sim_add gw2
7421as gw2
7422ovs-vsctl add-br br-phys
7423ovn_attach n1 br-phys 192.168.0.4
7424
7425sim_add ext1
7426as ext1
7427ovs-vsctl add-br br-phys
7428ovn_attach n1 br-phys 192.168.0.3
7429ovs-vsctl -- add-port br-int ext1-vif1 -- \
7430 set interface ext1-vif1 external-ids:iface-id=outside1 \
7431 options:tx_pcap=ext1/vif1-tx.pcap \
7432 options:rxq_pcap=ext1/vif1-rx.pcap \
7433 ofport-request=1
7434
7435# Pre-populate the hypervisors' ARP tables so that we don't lose any
7436# packets for ARP resolution (native tunneling doesn't queue packets
7437# for ARP resolution).
74868f2c 7438OVN_POPULATE_ARP
75f9e007
GZ
7439
7440ovn-nbctl create Logical_Router name=R0
7441ovn-nbctl create Logical_Router name=R1
7442
7443ovn-nbctl ls-add foo
7444ovn-nbctl ls-add join
7445ovn-nbctl ls-add alice
7446ovn-nbctl ls-add outside
7447
7448#Connect foo to R0
7449ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7450ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7451 type=router options:router-port=R0-foo \
7452 -- lsp-set-addresses foo-R0 router
7453
7454#Connect R0 to join
7455ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7456ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7457 type=router options:router-port=R0-join \
7458 -- lsp-set-addresses join-R0 router
7459
7460#Connect join to R1
7461ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7462ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7463 type=router options:router-port=R1-join \
7464 -- lsp-set-addresses join-R1 router
7465
7466#add route rules
7467ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7468ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7469
7470# Connect alice to R1 as distributed router gateway port on gw1
7471ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7472
7473ovn-nbctl \
7474 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7475 chassis_name=gw1 \
7476 priority=20 -- \
7477 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7478 chassis_name=gw2 \
7479 priority=10 -- \
7480 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7481
7482ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7483 type=router options:router-port=alice \
7484 -- lsp-set-addresses rp-alice router
7485
7486# Create logical port foo1 in foo
7487ovn-nbctl lsp-add foo foo1 \
7488-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7489
7490# Create logical port outside1 in outside
7491ovn-nbctl lsp-add outside outside1 \
7492-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7493
7494# Create localnet port in alice
7495ovn-nbctl lsp-add alice ln-alice
7496ovn-nbctl lsp-set-addresses ln-alice unknown
7497ovn-nbctl lsp-set-type ln-alice localnet
7498ovn-nbctl lsp-set-options ln-alice network_name=phys
7499
7500# Create localnet port in outside
7501ovn-nbctl lsp-add outside ln-outside
7502ovn-nbctl lsp-set-addresses ln-outside unknown
7503ovn-nbctl lsp-set-type ln-outside localnet
7504ovn-nbctl lsp-set-options ln-outside network_name=phys
7505
7506# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7507# mapping to the external network, is the one generating packets
7508as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7509as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7510as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7511
7512AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7513
7514# Allow some time for ovn-northd and ovn-controller to catch up.
7515# XXX This should be more systematic.
7516sleep 2
7517
7518ip_to_hex() {
7519 printf "%02x%02x%02x%02x" "$@"
7520}
7521
7522reset_pcap_file() {
7523 local iface=$1
7524 local pcap_file=$2
7525 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7526options:rxq_pcap=dummy-rx.pcap
7527 rm -f ${pcap_file}*.pcap
7528 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7529options:rxq_pcap=${pcap_file}-rx.pcap
7530}
7531
7532test_ip_packet()
7533{
7534 local active_gw=$1
7535 local backup_gw=$2
7536
7537 # Send ip packet between foo1 and outside1
7538 src_mac="f00000010203" # foo1 mac
7539 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7540 src_ip=`ip_to_hex 192 168 1 2`
7541 dst_ip=`ip_to_hex 172 16 1 3`
7542 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7543
7544 # ARP request packet to expect at outside1
7545 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7546
7547 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7548
7549 # Send ARP reply from outside1 back to the router
7550 # XXX: note, we could avoid this if we plug this port into a netns
7551 # and setup the IP address into the port, so the kernel would simply reply
7552 src_mac="000002010203"
7553 reply_mac="f00000010204"
7554 dst_ip=`ip_to_hex 172 16 1 3`
7555 src_ip=`ip_to_hex 172 16 1 1`
7556 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7557
7558 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7559
86c9d79a
NS
7560 OVS_WAIT_UNTIL([
7561 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7562grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7563 ])
7564
75f9e007
GZ
7565 # Packet to Expect at ext1 chassis, outside1 port
7566 src_mac="000002010203"
7567 dst_mac="f00000010204"
7568 src_ip=`ip_to_hex 192 168 1 2`
7569 dst_ip=`ip_to_hex 172 16 1 3`
7570 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7571 echo $expected > ext1-vif1.expected
7572
7573 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7574 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7575 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7576
7577 # Resend packet from foo1 to outside1
7578 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7579
7580 sleep 1
7581
7582 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7583 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7584 AT_CHECK([grep $expected packets | sort], [0], [expout])
7585 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7586 AT_CHECK([grep $expected packets | sort], [0], [])
7587}
7588
7589test_ip_packet gw1 gw2
7590
8e1d9349 7591ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 7592 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7593 chassis_name=gw1 \
7594 priority=10 -- \
7595 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7596 chassis_name=gw2 \
7597 priority=20 -- \
7598 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7599
7600test_ip_packet gw2 gw1
7601
7602OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7603AT_CLEANUP
7604
41a15b71
MS
7605AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7606AT_SKIP_IF([test $HAVE_PYTHON = no])
7607ovn_start
7608
7609# Logical network:
7610# One LR R1 that has switches foo (192.168.1.0/24) and
7611# alice (172.16.1.0/24) connected to it. The logical port
7612# between R1 and alice has a "redirect-chassis" specified,
7613# i.e. it is the distributed router gateway port.
7614# Switch alice also has a localnet port defined.
7615# An additional switch outside has a localnet port and the
7616# same subnet as alice (172.16.1.0/24).
7617
7618# Physical network:
7619# Three hypervisors hv[123].
7620# hv1 hosts vif foo1.
7621# hv2 is the "redirect-chassis" that hosts the distributed
7622# router gateway port.
7623# hv3 hosts vif outside1.
7624# In order to show that connectivity works only through hv2,
7625# an initial round of tests is run without any bridge-mapping
7626# defined for the localnet on hv2. These tests are expected
7627# to fail.
7628# Subsequent tests are run after defining the bridge-mapping
7629# for the localnet on hv2. These tests are expected to succeed.
7630
7631# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 7632# to logical ports.
41a15b71
MS
7633net_add n1
7634
7635sim_add hv1
7636as hv1
7637ovs-vsctl add-br br-phys
7638ovn_attach n1 br-phys 192.168.0.1
7639ovs-vsctl -- add-port br-int hv1-vif1 -- \
7640 set interface hv1-vif1 external-ids:iface-id=foo1 \
7641 options:tx_pcap=hv1/vif1-tx.pcap \
7642 options:rxq_pcap=hv1/vif1-rx.pcap \
7643 ofport-request=1
7644
7645sim_add hv2
7646as hv2
7647ovs-vsctl add-br br-phys
7648ovn_attach n1 br-phys 192.168.0.2
7649
7650sim_add hv3
7651as hv3
7652ovs-vsctl add-br br-phys
7653ovn_attach n1 br-phys 192.168.0.3
7654ovs-vsctl -- add-port br-int hv3-vif1 -- \
7655 set interface hv3-vif1 external-ids:iface-id=outside1 \
7656 options:tx_pcap=hv3/vif1-tx.pcap \
7657 options:rxq_pcap=hv3/vif1-rx.pcap \
7658 ofport-request=1
7659
7660# Pre-populate the hypervisors' ARP tables so that we don't lose any
7661# packets for ARP resolution (native tunneling doesn't queue packets
7662# for ARP resolution).
74868f2c 7663OVN_POPULATE_ARP
41a15b71
MS
7664
7665ovn-nbctl create Logical_Router name=R1
7666
7667ovn-nbctl ls-add foo
7668ovn-nbctl ls-add alice
7669ovn-nbctl ls-add outside
7670
7671# Connect foo to R1
7672ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7673ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7674 type=router options:router-port=foo \
7675 -- lsp-set-addresses rp-foo router
7676
7677# Connect alice to R1 as distributed router gateway port on hv2
7678ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7679 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7680ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7681 type=router options:router-port=alice \
7682 -- lsp-set-addresses rp-alice router
7683
7684# Create logical port foo1 in foo
7685ovn-nbctl lsp-add foo foo1 \
7686-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7687
7688# Create logical port outside1 in outside
7689ovn-nbctl lsp-add outside outside1 \
7690-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7691
7692# Create localnet port in alice
7693ovn-nbctl lsp-add alice ln-alice
7694ovn-nbctl lsp-set-addresses ln-alice unknown
7695ovn-nbctl lsp-set-type ln-alice localnet
7696ovn-nbctl lsp-set-options ln-alice network_name=phys
7697
7698# Create localnet port in outside
7699ovn-nbctl lsp-add outside ln-outside
7700ovn-nbctl lsp-set-addresses ln-outside unknown
7701ovn-nbctl lsp-set-type ln-outside localnet
7702ovn-nbctl lsp-set-options ln-outside network_name=phys
7703
7704# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7705as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7706as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7707
7708
7709# Allow some time for ovn-northd and ovn-controller to catch up.
7710# XXX This should be more systematic.
7711sleep 2
7712
7713echo "---------NB dump-----"
7714ovn-nbctl show
7715echo "---------------------"
7716ovn-nbctl list logical_router
7717echo "---------------------"
7718ovn-nbctl list logical_router_port
7719echo "---------------------"
7720
7721echo "---------SB dump-----"
7722ovn-sbctl list datapath_binding
7723echo "---------------------"
7724ovn-sbctl list port_binding
7725echo "---------------------"
7726ovn-sbctl dump-flows
7727echo "---------------------"
7728ovn-sbctl list chassis
7729ovn-sbctl list encap
1da17a0b 7730echo "------ Gateway_Chassis dump (SBDB) -------"
7731ovn-sbctl list Gateway_Chassis
7732echo "------ Port_Binding chassisredirect -------"
7733ovn-sbctl find Port_Binding type=chassisredirect
7734echo "-------------------------------------------"
41a15b71
MS
7735
7736echo "------ hv1 dump ----------"
7737as hv1 ovs-ofctl show br-int
7738as hv1 ovs-ofctl dump-flows br-int
7739echo "------ hv2 dump ----------"
7740as hv2 ovs-ofctl show br-int
7741as hv2 ovs-ofctl dump-flows br-int
7742echo "------ hv3 dump ----------"
7743as hv3 ovs-ofctl show br-int
7744as hv3 ovs-ofctl dump-flows br-int
7745echo "--------------------------"
7746
1da17a0b 7747
41a15b71
MS
7748# Check that redirect mapping is programmed only on hv2
7749AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7750])
7751AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7752])
7753# Check that hv1 sends chassisredirect port traffic to hv2
7754AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7755])
7756AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7757])
7758# Check that arp reply on distributed gateway port is only programmed on hv2
7759AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7760])
7761AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7762])
7763
7764
7765ip_to_hex() {
7766 printf "%02x%02x%02x%02x" "$@"
7767}
7768
7769
7770: > hv2-vif1.expected
7771: > hv3-vif1.expected
7772
7773# test_arp INPORT SHA SPA TPA [REPLY_HA]
7774#
7775# Causes a packet to be received on INPORT. The packet is an ARP
7776# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7777# it should be the hardware address of the target to expect to receive in an
7778# ARP reply; otherwise no reply is expected.
7779#
7780# INPORT is an logical switch port number, e.g. 11 for vif11.
7781# SHA and REPLY_HA are each 12 hex digits.
7782# SPA and TPA are each 8 hex digits.
7783test_arp() {
7784 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7785 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7786 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7787
7788 if test X$reply_ha != X; then
7789 # Expect to receive the reply, if any.
7790 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7791 echo $reply >> hv${hv}-vif$inport.expected
7792 fi
7793}
7794
7795rtr_ip=$(ip_to_hex 172 16 1 1)
7796foo_ip=$(ip_to_hex 192 168 1 2)
7797outside_ip=$(ip_to_hex 172 16 1 3)
7798
7799echo $rtr_ip
7800echo $foo_ip
7801echo $outside_ip
7802
7803# ARP for router IP address from outside1, no response expected
7804test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7805
7806# Now check the packets actually received against the ones expected.
7807OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7808
7809# Send ip packet between foo1 and outside1
7810src_mac="f00000010203"
7811dst_mac="000001010203"
7812src_ip=`ip_to_hex 192 168 1 2`
7813dst_ip=`ip_to_hex 172 16 1 3`
7814packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7815
7816# Now check the packets actually received against the ones expected.
7817OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7818
7819# Now add bridge-mappings on hv2, which should make everything work
7820as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7821
7822# Allow some time for ovn-northd and ovn-controller to catch up.
7823# XXX This should be more systematic.
7824sleep 2
7825
7826# ARP for router IP address from outside1
7827test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7828
7829# Now check the packets actually received against the ones expected.
7830OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7831
7832# Send ip packet between foo1 and outside1
7833src_mac="f00000010203"
7834dst_mac="000001010203"
7835src_ip=`ip_to_hex 192 168 1 2`
7836dst_ip=`ip_to_hex 172 16 1 3`
7837packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7838
7839# ARP request packet to expect at outside1
7840src_mac="000002010203"
7841src_ip=`ip_to_hex 172 16 1 1`
7842arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7843
7844as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7845
7846echo $arp_request >> hv3-vif1.expected
7847OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7848
7849# Send ARP reply from outside1 back to the router
7850reply_mac="f00000010204"
7851arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7852
7853as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7854
7855# Allow some time for ovn-northd and ovn-controller to catch up.
7856# XXX This should be more systematic.
7857sleep 1
7858
7859# Packet to Expect at outside1
7860src_mac="000002010203"
7861dst_mac="f00000010204"
7862src_ip=`ip_to_hex 192 168 1 2`
7863dst_ip=`ip_to_hex 172 16 1 3`
7864expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7865
7866# Resend packet from foo1 to outside1
7867as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7868
7869echo "------ hv1 dump ----------"
7870as hv1 ovs-ofctl show br-int
7871as hv1 ovs-ofctl dump-flows br-int
7872echo "------ hv2 dump ----------"
7873as hv2 ovs-ofctl show br-int
7874as hv2 ovs-ofctl dump-flows br-int
7875echo "------ hv3 dump ----------"
7876as hv3 ovs-ofctl show br-int
7877as hv3 ovs-ofctl dump-flows br-int
7878echo "----------------------------"
7879
7880echo $expected >> hv3-vif1.expected
7881OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7882
7883#Check ovn-trace over "chassisredirect" port
7884AT_CAPTURE_FILE([trace])
7885ovn_trace () {
7886 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7887}
7888
7889echo 'ip.ttl--;' > expout
7890echo 'eth.src = 00:00:02:01:02:03;' >> expout
7891echo 'eth.dst = f0:00:00:01:02:04;' >> expout
7892echo 'output("ln-alice");' >> expout
7893AT_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])
7894
7895# Create logical port alice1 in alice on hv1
7896as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7897 set interface hv1-vif2 external-ids:iface-id=alice1 \
7898 options:tx_pcap=hv1/vif2-tx.pcap \
7899 options:rxq_pcap=hv1/vif2-rx.pcap \
7900 ofport-request=1
7901
7902ovn-nbctl lsp-add alice alice1 \
7903-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
7904
7905# Create logical port foo2 in foo on hv2
7906as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7907 set interface hv2-vif1 external-ids:iface-id=foo2 \
7908 options:tx_pcap=hv2/vif1-tx.pcap \
7909 options:rxq_pcap=hv2/vif1-rx.pcap \
7910 ofport-request=1
7911
7912ovn-nbctl lsp-add foo foo2 \
7913-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7914
7915# Allow some time for ovn-northd and ovn-controller to catch up.
7916# XXX This should be more systematic.
7917sleep 1
7918
7919: > hv1-vif2.expected
7920
7921# Send ip packet between alice1 and foo2
7922src_mac="f00000010205"
7923dst_mac="000002010203"
7924src_ip=`ip_to_hex 172 16 1 4`
7925dst_ip=`ip_to_hex 192 168 1 3`
7926packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7927
7928as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7929
7930# Packet to Expect at foo2
7931src_mac="000001010203"
7932dst_mac="f00000010206"
7933src_ip=`ip_to_hex 172 16 1 4`
7934dst_ip=`ip_to_hex 192 168 1 3`
7935expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7936
7937echo $expected >> hv2-vif1.expected
f5f64552 7938OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 7939
0d31e5be 7940AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 7941])
7942
8e1d9349 7943ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 7944
0d31e5be 7945AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 7946])
7947
41a15b71
MS
7948OVN_CLEANUP([hv1],[hv2],[hv3])
7949
7950AT_CLEANUP
26b9e08d
MS
7951
7952AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7953AT_SKIP_IF([test $HAVE_PYTHON = no])
7954ovn_start
7955# Create logical switches
7956ovn-nbctl ls-add ls0
7957ovn-nbctl ls-add ls1
7958# Create distributed router
7959ovn-nbctl create Logical_Router name=lr0
7960# Add distributed gateway port to distributed router
7961ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
7962 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
7963ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
7964 type=router options:router-port=lrp0 addresses="router"
7965# Add router port to ls1
7966ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
7967ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
7968 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
7969# Add logical ports for NAT rules
7970ovn-nbctl lsp-add ls1 foo1 \
7971-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
7972ovn-nbctl lsp-add ls1 foo2 \
7973-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
7974# Add nat-addresses option
7975ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7976# Add NAT rules
7977AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
7978AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
7979AT_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 7980AT_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
7981
7982net_add n1
7983sim_add hv1
7984as hv1
7985ovs-vsctl add-br br-phys
7986ovn_attach n1 br-phys 192.168.0.1
7987
7988AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7989AT_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])
7990
7991sim_add hv2
7992as hv2
7993ovs-vsctl add-br br-phys
7994ovn_attach n1 br-phys 192.168.0.2
7995# Initially test with no bridge-mapping on hv2, expect to receive no packets
7996
f40c5588
MS
7997sim_add hv3
7998as hv3
7999ovs-vsctl add-br br-phys
8000ovn_attach n1 br-phys 192.168.0.3
8001# Initially test with no bridge-mapping on hv3
8002
26b9e08d
MS
8003# Create a localnet port.
8004AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8005AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8006AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8007AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8008
8009# Allow some time for ovn-northd and ovn-controller to catch up.
8010# XXX This should be more systematic.
8011sleep 2
8012
8013# Expect no packets when hv2 bridge-mapping is not present
8014: > packets
8015OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8016
8017# Add bridge-mapping on hv2
f40c5588 8018AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
8019
8020# Wait for packets to be received.
8021OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8022trim_zeros() {
8023 sed 's/\(00\)\{1,\}$//'
8024}
8025$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8026expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8027echo $expected > expout
8028expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8029echo $expected >> expout
8030AT_CHECK([sort packets], [0], [expout])
f40c5588 8031sort packets | cat
26b9e08d 8032
f40c5588
MS
8033# Temporarily remove nat-addresses option to avoid race conditions
8034# due to GARP backoff
8035ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8036
8037reset_pcap_file() {
8038 local iface=$1
8039 local pcap_file=$2
8040 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8041options:rxq_pcap=dummy-rx.pcap
8042 rm -f ${pcap_file}*.pcap
8043 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8044options:rxq_pcap=${pcap_file}-rx.pcap
8045}
8046
8047as hv1 reset_pcap_file snoopvif hv1/snoopvif
8048
8049# Add OVS ports for foo1 and foo2 on hv3
8050ovs-vsctl -- add-port br-int hv3-vif1 -- \
8051 set interface hv3-vif1 external-ids:iface-id=foo1 \
8052 ofport-request=1
8053ovs-vsctl -- add-port br-int hv3-vif2 -- \
8054 set interface hv3-vif2 external-ids:iface-id=foo2 \
8055 ofport-request=2
8056
8057# Add bridge-mapping on hv3
8058AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8059
8060# Re-add nat-addresses option
8061ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8062
8063# Wait for packets to be received.
8064OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8065trim_zeros() {
8066 sed 's/\(00\)\{1,\}$//'
8067}
8068
8069$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8070expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8071echo $expected >> expout
8072expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8073echo $expected >> expout
8074AT_CHECK([sort packets], [0], [expout])
8075sort packets | cat
8076
8077OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
8078
8079AT_CLEANUP
6b785fd8 8080
4364646c
ZKL
8081AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8082AT_KEYWORDS([ovn-nd_ra])
8083AT_SKIP_IF([test $HAVE_PYTHON = no])
8084ovn_start
8085
8086# In this test case we create 1 lswitch with 3 VIF ports attached,
8087# and a lrouter connected to the lswitch.
8088# We generate the Router solicitation packet and verify the Router Advertisement
8089# reply packet from the ovn-controller.
8090
8091# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8092# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8093# 'slaac' to allow lrp0 send RA for SLAAC mode.
8094ovn-nbctl ls-add lsw0
8095ovn-nbctl lr-add lr0
8096ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8097ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8098ovn-nbctl \
8099 -- lsp-add lsw0 lsp0 \
8100 -- set Logical_Switch_Port lsp0 type=router \
8101 options:router-port=lrp0 \
8102 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8103net_add n1
8104sim_add hv1
8105as hv1
8106ovs-vsctl add-br br-phys
8107ovn_attach n1 br-phys 192.168.0.2
8108
8109ovn-nbctl lsp-add lsw0 lp1
8110ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8111ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8112
8113ovn-nbctl lsp-add lsw0 lp2
8114ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8115ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8116
8117ovn-nbctl lsp-add lsw0 lp3
8118ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8119ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8120
8121# Add ACL rule for ICMPv6 on lsw0
8122ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8123ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8124ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8125ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8126
8127ovs-vsctl -- add-port br-int hv1-vif1 -- \
8128 set interface hv1-vif1 external-ids:iface-id=lp1 \
8129 options:tx_pcap=hv1/vif1-tx.pcap \
8130 options:rxq_pcap=hv1/vif1-rx.pcap \
8131 ofport-request=1
8132
8133ovs-vsctl -- add-port br-int hv1-vif2 -- \
8134 set interface hv1-vif2 external-ids:iface-id=lp2 \
8135 options:tx_pcap=hv1/vif2-tx.pcap \
8136 options:rxq_pcap=hv1/vif2-rx.pcap \
8137 ofport-request=2
8138
8139ovs-vsctl -- add-port br-int hv1-vif3 -- \
8140 set interface hv1-vif3 external-ids:iface-id=lp3 \
8141 options:tx_pcap=hv1/vif3-tx.pcap \
8142 options:rxq_pcap=hv1/vif3-rx.pcap \
8143 ofport-request=3
8144
8145# Allow some time for ovn-northd and ovn-controller to catch up.
8146# XXX This should be more systematic.
8147sleep 1
8148
8149reset_pcap_file() {
8150 local iface=$1
8151 local pcap_file=$2
8152 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8153options:rxq_pcap=dummy-rx.pcap
8154 rm -f ${pcap_file}*.pcap
8155 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8156options:rxq_pcap=${pcap_file}-rx.pcap
8157}
8158
8159# Make sure that ovn-controller has installed the corresponding OF Flow.
8160OVS_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"`])
8161
8162# This shell function sends a Router Solicitation packet.
8163# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8164test_ipv6_ra() {
8165 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8166 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8167
8168 local len=24
8169 local mtu_opt=""
8170 if test $mtu != 0; then
8171 len=`expr $len + 8`
8172 mtu_opt=05010000${mtu}
8173 fi
8174
8175 if test ${#prefix_opt} != 0; then
8176 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8177 len=`expr $len + ${#prefix_opt} / 2`
8178 fi
8179
8180 len=$(printf "%x" $len)
8181 local lrp_mac=fa163e000001
8182 local lrp_lla=fe80000000000000f8163efffe000001
8183 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8184 echo $reply >> $inport.expected
8185
8186 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8187}
8188
8189AT_CAPTURE_FILE([ofctl_monitor0.log])
8190as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8191--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8192
8193# MTU is not set and the address mode is set to slaac
8194addr_mode=00
8195default_prefix_option_config=030440c0ffffffffffffffff00000000
8196src_mac=fa163e000002
8197src_lla=fe80000000000000f8163efffe000002
8198test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8199
8200# NXT_RESUME should be 1.
8201OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8202
8203$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8204
8205cat 1.expected | cut -c -112 > expout
8206AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8207
8208# Skipping the ICMPv6 checksum.
8209cat 1.expected | cut -c 117- > expout
8210AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8211
8212rm -f *.expected
8213reset_pcap_file hv1-vif1 hv1/vif1
8214reset_pcap_file hv1-vif2 hv1/vif2
8215reset_pcap_file hv1-vif3 hv1/vif3
8216
8217# Set the MTU to 1500
8218ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8219
8220# Make sure that ovn-controller has installed the corresponding OF Flow.
8221OVS_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"`])
8222
8223addr_mode=00
8224default_prefix_option_config=030440c0ffffffffffffffff00000000
8225src_mac=fa163e000003
8226src_lla=fe80000000000000f8163efffe000003
8227mtu=000005dc
8228
8229test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8230
8231# NXT_RESUME should be 2.
8232OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8233
8234$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8235
8236cat 2.expected | cut -c -112 > expout
8237AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8238
8239# Skipping the ICMPv6 checksum.
8240cat 2.expected | cut -c 117- > expout
8241AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8242
8243rm -f *.expected
8244reset_pcap_file hv1-vif1 hv1/vif1
8245reset_pcap_file hv1-vif2 hv1/vif2
8246reset_pcap_file hv1-vif3 hv1/vif3
8247
8248# Set the address mode to dhcpv6_stateful
8249ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8250# Make sure that ovn-controller has installed the corresponding OF Flow.
8251OVS_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"`])
8252
8253addr_mode=80
8254default_prefix_option_config=""
8255src_mac=fa163e000004
8256src_lla=fe80000000000000f8163efffe000004
8257mtu=000005dc
8258
8259test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8260
8261# NXT_RESUME should be 3.
8262OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8263
8264$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8265
8266cat 3.expected | cut -c -112 > expout
8267AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8268
8269# Skipping the ICMPv6 checksum.
8270cat 3.expected | cut -c 117- > expout
8271AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8272
8273rm -f *.expected
8274reset_pcap_file hv1-vif1 hv1/vif1
8275reset_pcap_file hv1-vif2 hv1/vif2
8276reset_pcap_file hv1-vif3 hv1/vif3
8277
8278# Set the address mode to dhcpv6_stateless
8279ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8280# Make sure that ovn-controller has installed the corresponding OF Flow.
8281OVS_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"`])
8282
8283addr_mode=40
8284default_prefix_option_config=030440c0ffffffffffffffff00000000
8285src_mac=fa163e000002
8286src_lla=fe80000000000000f8163efffe000002
8287mtu=000005dc
8288
8289test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8290
8291# NXT_RESUME should be 4.
8292OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8293
8294$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8295
8296cat 1.expected | cut -c -112 > expout
8297AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8298
8299# Skipping the ICMPv6 checksum.
8300cat 1.expected | cut -c 117- > expout
8301AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8302
8303rm -f *.expected
8304reset_pcap_file hv1-vif1 hv1/vif1
8305reset_pcap_file hv1-vif2 hv1/vif2
8306reset_pcap_file hv1-vif3 hv1/vif3
8307
8308# Set the address mode to invalid.
8309ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8310# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8311OVS_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"`])
8312
8313addr_mode=40
8314default_prefix_option_config=""
8315src_mac=fa163e000002
8316src_lla=fe80000000000000f8163efffe000002
8317mtu=000005dc
8318
8319test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8320
8321# NXT_RESUME should be 4 only.
8322OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8323
8324$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8325AT_CHECK([cat 1.packets], [0], [])
8326
8327OVN_CLEANUP([hv1])
8328AT_CLEANUP
8329
6b785fd8
GS
8330AT_SETUP([ovn -- /32 router IP address])
8331AT_SKIP_IF([test $HAVE_PYTHON = no])
8332ovn_start
8333
8334# Logical network:
8335# 2 LS 'foo' and 'alice' connected via router R1.
8336# R1 connects to 'alice' with a /32 IP address. We use static routes and
8337# nexthop to push traffic to a logical port in switch 'alice'
8338
8339ovn-nbctl lr-add R1
8340
8341ovn-nbctl ls-add foo
8342ovn-nbctl ls-add alice
8343
8344# Connect foo to R1
8345ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8346ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8347 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8348
8349# Connect alice to R1.
8350ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8351ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8352 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8353
8354# Create logical port foo1 in foo
8355ovn-nbctl lsp-add foo foo1 \
8356-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8357
8358# Create logical port alice1 in alice
8359ovn-nbctl lsp-add alice alice1 \
8360-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8361
8362#install default route in R1 to use alice1's IP address as nexthop
8363ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8364
8365# Create two hypervisor and create OVS ports corresponding to logical ports.
8366net_add n1
8367
8368sim_add hv1
8369as hv1
8370ovs-vsctl add-br br-phys
8371ovn_attach n1 br-phys 192.168.0.1
8372ovs-vsctl -- add-port br-int hv1-vif1 -- \
8373 set interface hv1-vif1 external-ids:iface-id=foo1 \
8374 options:tx_pcap=hv1/vif1-tx.pcap \
8375 options:rxq_pcap=hv1/vif1-rx.pcap \
8376 ofport-request=1
8377
8378sim_add hv2
8379as hv2
8380ovs-vsctl add-br br-phys
8381ovn_attach n1 br-phys 192.168.0.2
8382ovs-vsctl -- add-port br-int hv2-vif1 -- \
8383 set interface hv2-vif1 external-ids:iface-id=alice1 \
8384 options:tx_pcap=hv2/vif1-tx.pcap \
8385 options:rxq_pcap=hv2/vif1-rx.pcap \
8386 ofport-request=1
8387
8388
8389# Pre-populate the hypervisors' ARP tables so that we don't lose any
8390# packets for ARP resolution (native tunneling doesn't queue packets
8391# for ARP resolution).
74868f2c 8392OVN_POPULATE_ARP
6b785fd8
GS
8393
8394# Allow some time for ovn-northd and ovn-controller to catch up.
8395# XXX This should be more systematic.
8396sleep 1
8397
8398ip_to_hex() {
8399 printf "%02x%02x%02x%02x" "$@"
8400}
8401
8402# Send ip packets between foo1 and alice1
8403src_mac="f00000010203"
8404dst_mac="000000010203"
8405src_ip=`ip_to_hex 192 168 1 2`
8406dst_ip=`ip_to_hex 10 0 0 2`
8407packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8408
8409# Send the first packet to trigger a ARP response and population of
8410# mac_bindings table.
8411as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8412OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8413
8414# Send the second packet to reach the destination.
8415as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8416
8417# Packet to Expect at 'alice1'
8418src_mac="000000010204"
8419dst_mac="f00000010204"
8420src_ip=`ip_to_hex 192 168 1 2`
8421dst_ip=`ip_to_hex 10 0 0 2`
8422echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8423
8424OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8425
8426OVN_CLEANUP([hv1],[hv2])
8427
8428AT_CLEANUP
2a38ef45
DA
8429
8430AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8431AT_SKIP_IF([test $HAVE_PYTHON = no])
8432ovn_start
8433
8434ovn-nbctl ls-add ls1
8435
8436# Add localport to the switch
8437ovn-nbctl lsp-add ls1 lp01
8438ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8439ovn-nbctl lsp-set-type lp01 localport
8440
8441net_add n1
8442
8443for i in 1 2; do
8444 sim_add hv$i
8445 as hv$i
8446 ovs-vsctl add-br br-phys
8447 ovn_attach n1 br-phys 192.168.0.$i
8448 ovs-vsctl add-port br-int vif01 -- \
8449 set Interface vif01 external-ids:iface-id=lp01 \
8450 options:tx_pcap=hv${i}/vif01-tx.pcap \
8451 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8452 ofport-request=${i}0
8453
8454 ovs-vsctl add-port br-int vif${i}1 -- \
8455 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8456 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8457 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8458 ofport-request=${i}1
8459
8460 ovn-nbctl lsp-add ls1 lp${i}1
8461 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8462 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8463
8464 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8465done
8466
8467ovn-nbctl --wait=sb sync
8468ovn-sbctl dump-flows
8469
74868f2c 8470OVN_POPULATE_ARP
2a38ef45
DA
8471
8472# Given the name of a logical port, prints the name of the hypervisor
8473# on which it is located.
8474vif_to_hv() {
8475 echo hv${1%?}
8476}
8477#
8478# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8479#
8480# This shell function causes a packet to be received on INPORT. The packet's
8481# content has Ethernet destination DST and source SRC (each exactly 12 hex
8482# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8483# logical switch port numbers, e.g. 11 for vif11.
8484#
8485# EOUT is the end-to-end output port, that is, where the packet will end up
8486# after possibly bouncing through one or more localnet ports. LOUT is the
8487# logical output port, which might be a localnet port, as seen by ovn-trace
8488# (which doesn't know what localnet ports are connected to and therefore can't
8489# figure out the end-to-end answer).
8490#
8491# DEFHV is the default hypervisor from where the packet is going to be sent
8492# if the source port is a localport.
8493for i in 1 2; do
8494 for j in 0 1; do
8495 : > $i$j.expected
8496 done
8497done
8498test_packet() {
8499 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8500 echo "$@"
8501
8502 # First try tracing the packet.
8503 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8504 if test $lout != drop; then
8505 echo "output(\"$lout\");"
8506 fi > expout
8507 AT_CAPTURE_FILE([trace])
8508 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8509
8510 # Then actually send a packet, for an end-to-end test.
8511 local packet=$(echo $dst$src | sed 's/://g')${eth}
8512 hv=`vif_to_hv $inport`
8513 # If hypervisor 0 (localport) use the defhv parameter
da88b550 8514 if test $hv = hv0; then
2a38ef45
DA
8515 hv=$defhv
8516 fi
8517 vif=vif$inport
8518 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8519 if test $eout != drop; then
8520 echo $packet >> ${eout#lp}.expected
8521 fi
8522}
8523
8524
8525# lp11 and lp21 are on different hypervisors
8526test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8527test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8528
8529# Both VIFs should be able to reach the localport on their own HV
8530test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8531test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8532
8533# Packet sent from localport on same hv should reach the vif
8534test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8535test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8536
8537# Packet sent from localport on different hv should be dropped
8538test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8539test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8540
8541# Now check the packets actually received against the ones expected.
8542for i in 1 2; do
8543 for j in 0 1; do
8544 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8545 done
8546done
8547
8548OVN_CLEANUP([hv1],[hv2])
8549
8550AT_CLEANUP
1da17a0b 8551
8552AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8553AT_SKIP_IF([test $HAVE_PYTHON = no])
8554ovn_start
8555
8556net_add n1
8557
8558# create gateways with external network connectivity
8559
8560for i in 1 2; do
8561 sim_add gw$i
8562 as gw$i
8563 ovs-vsctl add-br br-phys
8564 ovn_attach n1 br-phys 192.168.0.$i
8565 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8566done
8567
8568ovn-nbctl ls-add inside
8569ovn-nbctl ls-add outside
8570
8571# create hypervisors with a vif port each to an internal network
8572
8573for i in 1 2; do
8574 sim_add hv$i
8575 as hv$i
8576 ovs-vsctl add-br br-phys
8577 ovn_attach n1 br-phys 192.168.0.1$i
8578 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8579 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8580 options:tx_pcap=hv$i/vif1-tx.pcap \
8581 options:rxq_pcap=hv$i/vif1-rx.pcap \
8582 ofport-request=1
8583
8584 ovn-nbctl lsp-add inside inside$i \
8585 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8586
8587done
8588
74868f2c 8589OVN_POPULATE_ARP
1da17a0b 8590
8591ovn-nbctl create Logical_Router name=R1
8592
8593# Connect inside to R1
8594ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8595ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8596 type=router options:router-port=inside \
8597 -- lsp-set-addresses rp-inside router
8598
8599# Connect outside to R1 as distributed router gateway port on gw1+gw2
8600ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8601
8602ovn-nbctl --id=@gc0 create Gateway_Chassis \
8603 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8604 --id=@gc1 create Gateway_Chassis \
8605 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8606 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8607
8608ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8609 type=router options:router-port=outside \
8610 -- lsp-set-addresses rp-outside router
8611
8612# Create localnet port in outside
8613ovn-nbctl lsp-add outside ln-outside
8614ovn-nbctl lsp-set-addresses ln-outside unknown
8615ovn-nbctl lsp-set-type ln-outside localnet
8616ovn-nbctl lsp-set-options ln-outside network_name=phys
8617
8618# Allow some time for ovn-northd and ovn-controller to catch up.
8619# XXX This should be more systematic.
8e1d9349 8620ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8621
8622echo "---------NB dump-----"
8623ovn-nbctl show
8624echo "---------------------"
8625ovn-nbctl list logical_router
8626echo "---------------------"
8627ovn-nbctl list logical_router_port
8628echo "---------------------"
8629
8630echo "---------SB dump-----"
8631ovn-sbctl list datapath_binding
8632echo "---------------------"
8633ovn-sbctl list port_binding
8634echo "---------------------"
8635ovn-sbctl dump-flows
8636echo "---------------------"
8637ovn-sbctl list chassis
8638ovn-sbctl list encap
8639echo "---------------------"
8640echo "------ Gateway_Chassis dump (SBDB) -------"
8641ovn-sbctl list Gateway_Chassis
8642echo "------ Port_Binding chassisredirect -------"
8643ovn-sbctl find Port_Binding type=chassisredirect
8644echo "-------------------------------------------"
8645
3475695e
VA
8646for chassis in gw1 gw2 hv1 hv2; do
8647 as $chassis
8648 echo "------ $chassis dump ----------"
8649 ovs-ofctl show br-int
8650 ovs-ofctl dump-flows br-int
3475695e
VA
8651 echo "--------------------------"
8652done
508b7f96 8653function bfd_dump() {
8654 for chassis in gw1 gw2 hv1 hv2; do
8655 as $chassis
8656 echo "------ $chassis dump (BFD)----"
8657 echo "BFD (from $chassis):"
8658 # dump BFD config and status to the other chassis
8659 for chassis2 in gw1 gw2 hv1 hv2; do
8660 if [[ "$chassis" != "$chassis2" ]]; then
8661 echo " -> $chassis2:"
8662 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8663 fi
8664 done
8665 echo "--------------------------"
8666 done
8667}
8668
8669bfd_dump
1da17a0b 8670
8671hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8672hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8673hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8674hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8675
8676echo $hv1_gw1_ofport
8677echo $hv1_gw2_ofport
8678echo $hv2_gw1_ofport
8679echo $hv2_gw2_ofport
8680
8681echo "--- hv1 ---"
8682as hv1 ovs-ofctl dump-flows br-int table=32
8683
8684echo "--- hv2 ---"
8685as hv2 ovs-ofctl dump-flows br-int table=32
8686
508b7f96 8687gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8688gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8689
1da17a0b 8690AT_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
8691])
8692
8693AT_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
8694])
8695
508b7f96 8696sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8697
8698# make sure that flows for handling the outside router port reside on gw1
66d89287 8699AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8700]])
66d89287 8701AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8702]])
8703
8704# make sure ARP responder flows for outside router port reside on gw1 too
8705AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8706]])
8707AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8708]])
8709
8710
8711
8712# check that the chassis redirect port has been claimed by the gw1 chassis
8713AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8714 [0],[[1
8715]])
8716
8717
8718# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 8719
8720ovn-nbctl --id=@gc0 create Gateway_Chassis \
8721 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8722 --id=@gc1 create Gateway_Chassis \
8723 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8724 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8725
508b7f96 8726
1da17a0b 8727# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 8728ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8729
508b7f96 8730# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 8731AT_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
8732])
8733
8734AT_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
8735])
8736
508b7f96 8737# check that the chassis redirect port has been reclaimed by the gw2 chassis
8738AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8739 [0],[[1
8740]])
1da17a0b 8741
3475695e
VA
8742# check BFD enablement on tunnel ports from gw1 #########
8743as gw1
8744for chassis in gw2 hv1 hv2; do
8745 echo "checking gw1 -> $chassis"
8746 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8747 [[enable=true
8748]])
8749done
8750
8751
8752# check BFD enablement on tunnel ports from gw2 ##########
8753as gw2
8754for chassis in gw1 hv1 hv2; do
8755 echo "checking gw2 -> $chassis"
8756 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8757 [[enable=true
8758]])
8759done
8760
8761# check BFD enablement on tunnel ports from hv1 ###########
8762as hv1
8763for chassis in gw1 gw2; do
8764 echo "checking hv1 -> $chassis"
8765 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8766 [[enable=true
8767]])
8768done
8769# make sure BFD is not enabled to hv2, we don't need it
8770AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8771 [[enable=false
8772]])
8773
8774
8775# check BFD enablement on tunnel ports from hv2 ##########
8776as hv2
8777for chassis in gw1 gw2; do
8778 echo "checking hv2 -> $chassis"
8779 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8780 [[enable=true
8781]])
8782done
8783# make sure BFD is not enabled to hv1, we don't need it
8784AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8785 [[enable=false
8786]])
8787
508b7f96 8788sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8789
8790# make sure that flows for handling the outside router port reside on gw2 now
66d89287 8791AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8792]])
66d89287 8793AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8794]])
8795
8796# disconnect GW2 from the network, GW1 should take over
8797as gw2
8798port=${sandbox}_br-phys
8799as main ovs-vsctl del-port n1 $port
8800sleep 4
8801
8802bfd_dump
8803
8804# make sure that flows for handling the outside router port reside on gw2 now
66d89287 8805AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8806]])
66d89287 8807AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8808]])
8809
8810# check that the chassis redirect port has been reclaimed by the gw1 chassis
8811AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8812 [0],[[1
8813]])
8814
1da17a0b 8815OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8816
8817AT_CLEANUP
acfc41ff
VAK
8818
8819AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8820AT_SKIP_IF([test $HAVE_PYTHON = no])
8821ovn_start
8822ovn-nbctl ls-add ls0
8823ovn-nbctl ls-add ls1
8824ovn-nbctl create Logical_Router name=lr0
8825ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8826
8827ovn-nbctl --id=@gc0 create Gateway_Chassis \
8828 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8829 --id=@gc1 create Gateway_Chassis \
8830 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8831 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8832
8833ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8834 type=router options:router-port=lrp0 addresses="router"
8835ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8836ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8837 type=router options:router-port=lrp1 addresses="router"
8838
8839# Add NAT rules
8840AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8841
8842net_add n1
8843sim_add hv1
8844as hv1
8845ovs-vsctl add-br br-phys
8846ovn_attach n1 br-phys 192.168.0.1
8847AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8848AT_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])
8849
8850sim_add hv2
8851as hv2
8852ovs-vsctl add-br br-phys
8853ovn_attach n1 br-phys 192.168.0.2
8854AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8855
8856sim_add hv3
8857as hv3
8858ovs-vsctl add-br br-phys
8859ovn_attach n1 br-phys 192.168.0.3
8860AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8861
8862# Create a localnet port.
8863AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8864AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8865AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8866AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8867
8868# wait for earlier changes to take effect
6c8d3d69 8869AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
acfc41ff
VAK
8870
8871reset_pcap_file() {
8872 local iface=$1
8873 local pcap_file=$2
8874 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8875options:rxq_pcap=dummy-rx.pcap
8876 rm -f ${pcap_file}*.pcap
8877 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8878options:rxq_pcap=${pcap_file}-rx.pcap
8879}
8880
8881as hv1 reset_pcap_file snoopvif hv1/snoopvif
8882as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8883as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8884# add nat-addresses option
6c8d3d69 8885ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
acfc41ff
VAK
8886
8887# Wait for packets to be received through hv2.
8888OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8889trim_zeros() {
8890 sed 's/\(00\)\{1,\}$//'
8891}
8892
2db7bb2c 8893only_broadcast_from_lrp1() {
8894 grep "fffffffffffff00000000001"
8895}
8896
acfc41ff 8897garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 8898echo $garp > expout
8899
8900$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
8901echo "packets on hv1-snoopvif:"
8902cat hv1_snoop_tx
8903AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 8904$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
8905echo "packets on hv2 br-phys tx"
8906cat hv2_br_phys_tx
8907AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 8908$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
8909echo "packets on hv3 br-phys tx"
8910cat hv3_br_phys_tx
8911AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8912
8913
8914# at this point, we invert the priority of the gw chassis between hv2 and hv3
8915
8916ovn-nbctl --wait=hv \
8917 --id=@gc0 create Gateway_Chassis \
8918 name=outside_gw1 chassis_name=hv2 priority=1 -- \
8919 --id=@gc1 create Gateway_Chassis \
8920 name=outside_gw2 chassis_name=hv3 priority=10 -- \
8921 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8922
8923
8924as hv1 reset_pcap_file snoopvif hv1/snoopvif
8925as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8926as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8927
8928# Wait for packets to be received.
8929OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8930trim_zeros() {
8931 sed 's/\(00\)\{1,\}$//'
8932}
8933
2db7bb2c 8934$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 8935AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 8936$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 8937AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 8938$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 8939AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
8940
8941# change localnet port tag.
8942AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
8943
8944# wait for earlier changes to take effect
6c8d3d69 8945AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
03b85a58
GL
8946
8947# update nat-addresses option
6c8d3d69
HZ
8948ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
8949ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
03b85a58
GL
8950
8951as hv1 reset_pcap_file snoopvif hv1/snoopvif
8952as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8953as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8954
8955# Wait for packets to be received.
8956OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8957trim_zeros() {
8958 sed 's/\(00\)\{1,\}$//'
8959}
8960
8961garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
8962echo $garp > expout
8963
8964$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8965AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8966$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8967AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8968$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8969AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8970
acfc41ff
VAK
8971OVN_CLEANUP([hv1],[hv2],[hv3])
8972
8973AT_CLEANUP
79371ff5 8974
8975AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8976AT_SKIP_IF([test $HAVE_PYTHON = no])
8977ovn_start
8978
8979net_add n1
8980
8981# create two gateways with external network connectivity
8982for i in 1 2; do
8983 sim_add gw$i
8984 as gw$i
8985 ovs-vsctl add-br br-phys
8986 ovn_attach n1 br-phys 192.168.0.$i
8987 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8988done
8989
8990ovn-nbctl ls-add inside
8991ovn-nbctl ls-add outside
8992
8993# create one hypervisors with a vif port the internal network
8994sim_add hv1
8995as hv1
8996ovs-vsctl add-br br-phys
8997ovn_attach n1 br-phys 192.168.0.11
8998ovs-vsctl -- add-port br-int hv1-vif1 -- \
8999 set interface hv1-vif1 external-ids:iface-id=inside1 \
9000 options:tx_pcap=hv1/vif1-tx.pcap \
9001 options:rxq_pcap=hv1/vif1-rx.pcap \
9002 ofport-request=1
9003
9004ovn-nbctl lsp-add inside inside1 \
9005 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9006
9007
74868f2c 9008OVN_POPULATE_ARP
79371ff5 9009
9010ovn-nbctl create Logical_Router name=R1
9011
9012# Connect inside to R1
9013ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9014ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9015 type=router options:router-port=inside \
9016 -- lsp-set-addresses rp-inside router
9017
9018# Connect outside to R1 as distributed router gateway port on gw1+gw2
9019ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9020
9021ovn-nbctl --id=@gc0 create Gateway_Chassis \
9022 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9023 --id=@gc1 create Gateway_Chassis \
9024 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9025 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9026
9027ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9028 type=router options:router-port=outside \
9029 -- lsp-set-addresses rp-outside router
9030
9031# Create localnet port in outside
9032ovn-nbctl lsp-add outside ln-outside
9033ovn-nbctl lsp-set-addresses ln-outside unknown
9034ovn-nbctl lsp-set-type ln-outside localnet
9035ovn-nbctl lsp-set-options ln-outside network_name=phys
9036
9037# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 9038ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 9039
9040# currently when ovn-controller is restarted, the old entry is deleted
9041# and a new one is created, which leaves the Gateway_Chassis with
9042# an empty chassis for a while. NOTE: restarting ovn-controller in tests
9043# doesn't have the same effect because "name" is conserved, and the
9044# Chassis entry is not replaced.
9045
3a0c5805 9046> gw1/ovn-controller.log
325b2b1a 9047
79371ff5 9048gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9049ovn-sbctl destroy Chassis $gw2_chassis
9050
9051# Ensure ovn-controller has processed latest sbdb update
9052# ovn-nbctl --wait=hv sync
9053
9054AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9055
9056OVN_CLEANUP([gw1],[gw2],[hv1])
9057
9058AT_CLEANUP
63d91afa 9059
b1a3a6a4
NS
9060AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9061AT_KEYWORDS([ovn-nd_ns for unknown mac])
9062AT_SKIP_IF([test $HAVE_PYTHON = no])
9063ovn_start
9064
9065ovn-nbctl ls-add sw0_ip6
9066ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9067ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9068"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9069
9070ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9071"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9072
9073ovn-nbctl lr-add lr0_ip6
847dc1c2 9074ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
9075ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9076ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9077ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
9078ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9079ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9080
9081ovn-nbctl ls-add public
9082ovn-nbctl lsp-add public ln-public
9083ovn-nbctl lsp-set-addresses ln-public unknown
9084ovn-nbctl lsp-set-type ln-public localnet
9085ovn-nbctl lsp-set-options ln-public network_name=phys
9086
9087ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
90882001:db8:1:0:200:02ff:fe01:0204/64 \
9089-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9090
9091
9092ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9093rp-ip6_public type=router options:router-port=ip6_public \
9094-- lsp-set-addresses rp-ip6_public router
9095
9096net_add n1
9097sim_add hv1
9098as hv1
9099ovs-vsctl add-br br-phys
9100ovn_attach n1 br-phys 192.168.0.2
9101
9102ovs-vsctl -- add-port br-int hv1-vif1 -- \
9103 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9104 options:tx_pcap=hv1/vif1-tx.pcap \
9105 options:rxq_pcap=hv1/vif1-rx.pcap \
9106 ofport-request=1
9107ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9108
86c9d79a
NS
9109OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9110cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9111
9112# There is only one chassis.
9113chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9114OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
b1a3a6a4
NS
9115
9116trim_zeros() {
9117 sed 's/\(00\)\{1,\}$//'
9118}
9119
9120# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9121# addresses. ovn-controller should generate an IPv6 NS request for IPv6
9122# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9123# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9124# This function sends ipv6 packet
9125test_ipv6() {
9126 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9127 dst_ip=20010db800010000020002fffe010205
9128
9129 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9130 packet=${packet}8000000000000000
9131 shift; shift; shift; shift
9132
9133 dst_mac=3333ff010205
9134 src_mac=000002010204
9135 mcast_node_ip=ff0200000000000000000001ff010205
9136 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9137 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9138 expected_packet=${expected_packet}0101${src_mac}
9139
9140 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9141 echo $expected_packet >> ipv6_ns.expected
9142}
9143
9144src_mac=506400000002
9145dst_mac=00000000af01
9146src_ip=aef0000000000000526400fffe000002
9147# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9148# should be received by the ports attached to br-phys.
9149test_ipv6 1 $src_mac $dst_mac $src_ip 2
9150
86c9d79a
NS
9151OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9152OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9153
b1a3a6a4
NS
9154$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9155trim_zeros > 1.packets
9156$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9157trim_zeros > 2.packets
9158
9159cat ipv6_ns.expected | cut -c -112 > expout
9160AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9161AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9162
9163# Skipping the ICMPv6 checksum
9164cat ipv6_ns.expected | cut -c 117- > expout
9165AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9166AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9167
9168OVN_CLEANUP([hv1])
9169
9170AT_CLEANUP
9171
63d91afa
LR
9172AT_SETUP([ovn -- options:requested-chassis for logical port])
9173ovn_start
9174
9175net_add n1
9176
9177ovn-nbctl ls-add ls0
9178ovn-nbctl lsp-add ls0 lsp0
9179
9180# create two hypervisors, each with one vif port
9181sim_add hv1
9182as hv1
9183ovs-vsctl add-br br-phys
9184ovn_attach n1 br-phys 192.168.0.11
99cc5c92
NS
9185ovs-vsctl -- add-port br-int hv1-vif0 -- \
9186set Interface hv1-vif0 ofport-request=1
63d91afa
LR
9187
9188sim_add hv2
9189as hv2
9190ovs-vsctl add-br br-phys
9191ovn_attach n1 br-phys 192.168.0.12
99cc5c92
NS
9192ovs-vsctl -- add-port br-int hv2-vif0 -- \
9193set Interface hv2-vif0 ofport-request=1
63d91afa
LR
9194
9195# Allow only chassis hv1 to bind logical port lsp0.
9196ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9197
9198# Allow some time for ovn-northd and ovn-controller to catch up.
9199ovn-nbctl --wait=hv --timeout=3 sync
9200
9201# Retrieve hv1 and hv2 chassis UUIDs from southbound database
9202hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9203hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9204
9205# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9206echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9207as hv2
9208ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9209
9210OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9211AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9212
99cc5c92
NS
9213# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9214AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9215AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9216
9217# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
63d91afa
LR
9218echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9219as hv1
9220ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9221
9222OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9223AT_CHECK([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv1_uuid"], [0], [])
9224
99cc5c92
NS
9225# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9226as hv1 ovs-ofctl dump-flows br-int
9227AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9228AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9229
9230# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
63d91afa
LR
9231# the requested chassis for lsp0 is changed from hv1 to hv2.
9232echo "verifying that lsp0 binding moves when requested-chassis is changed"
9233
9234ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9235OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9236OVS_WAIT_UNTIL([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv2_uuid"])
9237
99cc5c92
NS
9238# (6) Chassis hv2 should add flows and hv1 should not.
9239AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9240AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9241
9242AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9243AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9244
63d91afa
LR
9245OVN_CLEANUP([hv1],[hv2])
9246
9247AT_CLEANUP
bd32425f
RB
9248
9249AT_SETUP([ovn -- options:requested-chassis with hostname])
9250
9251ovn_start
9252
9253ovn-nbctl ls-add ls0
9254ovn-nbctl lsp-add ls0 lsp0
9255
9256net_add n1
9257sim_add hv1
9258as hv1
9259ovs-vsctl add-br br-phys
9260ovn_attach n1 br-phys 192.168.0.11
99cc5c92 9261ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
bd32425f 9262
362ab40a 9263ovn-sbctl wait-until chassis hv1
bd32425f
RB
9264hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9265echo "hv1_hostname=${hv1_hostname}"
9266ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9267as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9268
9269hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9270echo "hv1_uuid=${hv1_uuid}"
9271OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9272AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
99cc5c92
NS
9273AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9274AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
bd32425f
RB
9275
9276ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9277OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9278ovn-nbctl --wait=hv --timeout=3 sync
9279AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
99cc5c92
NS
9280AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9281AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
bd32425f
RB
9282
9283OVN_CLEANUP([hv1])
9284
9285AT_CLEANUP
4446661a
MM
9286
9287AT_SETUP([ovn -- IPv6 periodic RA])
9288ovn_start
9289
9290# This test sets up two hypervisors.
9291# hv1 and hv2 run ovn-controllers, and
9292# each has a VIF connected to the same
9293# logical switch in OVN. The logical
9294# switch is connected to a logical
9295# router port that is configured to send
9296# periodic router advertisements.
9297#
9298# The reason for having two ovn-controller
9299# hypervisors is to ensure that the
9300# periodic RAs being sent by each ovn-controller
9301# are kept to their local hypervisors. If the
9302# packets are not kept local, then each port
9303# will receive too many RAs.
9304
9305net_add n1
9306sim_add hv1
9307sim_add hv2
9308as hv1
9309ovs-vsctl add-br br-phys
9310ovn_attach n1 br-phys 192.168.0.2
9311as hv2
9312ovs-vsctl add-br br-phys
9313ovn_attach n1 br-phys 192.168.0.3
9314
9315ovn-nbctl lr-add ro
1ea1b0d0 9316ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
4446661a
MM
9317
9318ovn-nbctl ls-add sw
9319ovn-nbctl lsp-add sw sw-ro
9320ovn-nbctl lsp-set-type sw-ro router
9321ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9322ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9323ovn-nbctl lsp-add sw sw-p1
9324ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9325ovn-nbctl lsp-add sw sw-p2
9326ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9327
9328ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9329ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9330ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9331ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9332
86c9d79a
NS
9333for i in 1 2 ; do
9334 as hv$i
9335 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9336 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9337 options:tx_pcap=hv$i/vif1-tx.pcap \
9338 options:rxq_pcap=hv$i/vif1-rx.pcap \
4446661a
MM
9339 ofport-request=1
9340done
9341
86c9d79a
NS
9342OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9343OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
4446661a
MM
9344
9345reset_pcap_file() {
9346 local iface=$1
9347 local pcap_file=$2
9348 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9349options:rxq_pcap=dummy-rx.pcap
9350 rm -f ${pcap_file}*.pcap
9351 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9352options:rxq_pcap=${pcap_file}-rx.pcap
9353
9354}
9355
9356construct_expected_ra() {
9357 local src_mac=000000000001
9358 local dst_mac=333300000001
9359 local src_addr=fe80000000000000020000fffe000001
9360 local dst_addr=ff020000000000000000000000000001
9361
9362 local mtu=$1
9363 local ra_mo=$2
9364 local ra_prefix_la=$3
9365
9366 local slla=0101${src_mac}
9367 local mtu_opt=""
9368 if test $mtu != 0; then
9369 mtu_opt=05010000${mtu}
9370 fi
9371 shift 3
9372
9373 local prefix=""
9374 while [[ $# -gt 0 ]] ; do
9375 local size=$1
9376 local net=$2
9377 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9378 shift 2
9379 done
9380
895ceaf7 9381 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
4446661a
MM
9382 local icmp=8600XXXX${ra}
9383
9384 local ip_len=$(expr ${#icmp} / 2)
1ea1b0d0 9385 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
4446661a
MM
9386
9387 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9388 local eth=${dst_mac}${src_mac}86dd${ip}
9389 local packet=${eth}
9390 echo $packet >> expected
9391}
9392
9393ra_test() {
9394 construct_expected_ra $@
9395
9396 for i in hv1 hv2 ; do
9397 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9398
9399 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9400
9401 cat expected | cut -c -112 > expout
9402 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9403
9404 # Skip ICMPv6 checksum.
9405 cat expected | cut -c 117- > expout
9406 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9407
9408 rm -f packets
9409 as $i reset_pcap_file $i-vif1 $i/vif1
9410 done
9411
9412 rm -f expected
9413}
9414
9415# Baseline test with no MTU
9416ra_test 0 00 c0 40 aef00000000000000000000000000000
9417
9418# Now make sure an MTU option makes it
9419ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9420ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9421
9422# Now test for multiple network prefixes
9423ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9424ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9425
9426# Test a different address mode now
9427ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9428ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9429
9430# And the other address mode
9431ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9432ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9433
9434OVN_CLEANUP([hv1],[hv2])
9435AT_CLEANUP
4826add0
LB
9436
9437AT_SETUP([ovn -- ACL reject rule test])
9438AT_KEYWORDS([acl-reject])
9439AT_SKIP_IF([test $HAVE_PYTHON = no])
9440ovn_start
9441
9442# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9443#
9444# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9445# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9446# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9447# unreachable frame generated from ACL rule hit
9448#
9449# INPORT is a lport number, e.g. 11 for vif11.
9450# HV is a hypervisor number
9451# ETH_SRC and ETH_DST are each 12 hex digits.
9452# IPV4_SRC and IPV4_DST are each 8 hex digits.
9453# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9454test_ip_packet() {
9455 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9456 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9457 shift 9
9458
9459 local ip_ttl=ff
9460 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9461
9462 local reply_icmp_ttl=ff
9463 local icmp_type_code_response=0301
9464 local icmp_data=00000000
9465 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9466 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9467 echo $reply >> vif$inport.expected
9468
9469 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9470}
9471
c319fabc
LB
9472# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
9473#
9474# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
9475# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
9476# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
9477test_ipv6_packet() {
9478 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
9479 shift 7
9480
9481 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9482 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
9483
9484 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
9485 echo $reply >> vif$inport.expected
9486
9487 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9488}
9489
c20ab6aa
LB
9490# 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
9491#
9492# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
9493# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
9494# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
9495#
9496# INPORT is an lport number, e.g. 11 for vif11.
9497# HV is an hypervisor number
9498# ETH_SRC and ETH_DST are each 12 hex digits.
9499# IPV4_SRC and IPV4_DST are each 8 hex digits.
9500# TCP_SPORT and TCP_DPORT are 4 hex digits.
9501# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
9502test_tcp_syn_packet() {
9503 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9504 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
9505 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
9506 shift 12
9507
9508 local ip_ttl=ff
9509 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
9510
9511 local tcp_rst_ttl=ff
9512 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
9513 echo $reply >> vif$inport.expected
9514
9515 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9516}
9517
4826add0
LB
9518# Create hypervisors hv[123].
9519# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
9520# Add all of the vifs to a single logical switch sw0.
9521
9522net_add n1
9523ovn-nbctl ls-add sw0
9524for i in 1 2 3; do
9525 sim_add hv$i
9526 as hv$i
9527 ovs-vsctl add-br br-phys
9528 ovn_attach n1 br-phys 192.168.0.$i
9529
9530 for j in 1 2 3; do
9531 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
9532 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
9533
9534 ovs-vsctl -- add-port br-int vif$i$j -- \
9535 set interface vif$i$j \
9536 external-ids:iface-id=sw0-p$i$j \
9537 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
9538 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
9539 ofport-request=$i$j
9540 done
9541done
9542
9543OVN_POPULATE_ARP
9544# allow some time for ovn-northd and ovn-controller to catch up.
9545sleep 1
9546
9547ip_to_hex() {
9548 printf "%02x%02x%02x%02x" "$@"
9549}
9550
9551for i in 1 2 3; do
9552 : > vif${i}1.expected
9553done
9554
9555ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
9556ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
9557ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
9558OVS_WAIT_UNTIL([test 3 = $(ovn-sbctl lflow-list | grep 'icmp4 {' | wc -l)])
9559
9560test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
9561test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
9562test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
9563
c319fabc
LB
9564test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
9565
c20ab6aa
LB
9566test_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
9567test_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
9568test_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
9569
4826add0
LB
9570for i in 1 2 3; do
9571 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
9572done
9573
9574OVN_CLEANUP([hv1], [hv2], [hv3])
9575AT_CLEANUP
689829d5
HZ
9576
9577AT_SETUP([ovn -- Port Groups])
9578AT_KEYWORDS([ovnpg])
9579AT_SKIP_IF([test $HAVE_PYTHON = no])
9580ovn_start
9581
9582# Logical network:
9583#
9584# Three logical switches ls1, ls2, ls3.
9585# One logical router lr0 connected to ls[123],
9586# with nine subnets, three per logical switch:
9587#
9588# lrp11 on ls1 for subnet 192.168.11.0/24
9589# lrp12 on ls1 for subnet 192.168.12.0/24
9590# lrp13 on ls1 for subnet 192.168.13.0/24
9591# ...
9592# lrp33 on ls3 for subnet 192.168.33.0/24
9593#
9594# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9595# digits are the subnet and the last digit distinguishes the VIF.
9596#
9597# This test will create two port groups and uses them in ACL.
9598
9599get_lsp_uuid () {
9600 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9601}
9602
9603pg1_ports=
9604pg2_ports=
9605for i in 1 2 3; do
9606 ovn-nbctl ls-add ls$i
9607 for j in 1 2 3; do
9608 for k in 1 2 3; do
9609 ovn-nbctl \
9610 -- lsp-add ls$i lp$i$j$k \
9611 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
9612 192.168.$i$j.$k"
9613 # logical ports lp[12]?1 belongs to port group pg1
9614 if test $i != 3 && test $k == 1; then
9615 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9616 fi
9617 # logical ports lp[23]?2 belongs to port group pg2
9618 if test $i != 1 && test $k == 2; then
9619 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9620 fi
9621 done
9622 done
9623done
9624
9625ovn-nbctl lr-add lr0
9626for i in 1 2 3; do
9627 for j in 1 2 3; do
9628 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9629 ovn-nbctl \
9630 -- lsp-add ls$i lrp$i$j-attachment \
9631 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9632 options:router-port=lrp$i$j \
9633 addresses='"00:00:00:00:ff:'$i$j'"'
9634 done
9635done
9636
9637ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9638ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9639
9640# create ACLs on all lswitches to drop traffic from pg2 to pg1
9641ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9642ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9643ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9644
9645# Physical network:
9646#
9647# Three hypervisors hv[123].
9648# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9649# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9650# lp?3[123] all on hv3.
9651
9652# Given the name of a logical port, prints the name of the hypervisor
9653# on which it is located.
9654vif_to_hv() {
9655 case $1 in dnl (
9656 ?11) echo 1 ;; dnl (
9657 ?12 | ?21 | ?22) echo 2 ;; dnl (
9658 ?13 | ?23 | ?3?) echo 3 ;;
9659 esac
9660}
9661
9662# Given the name of a logical port, prints the name of its logical router
9663# port, e.g. "vif_to_lrp 123" yields 12.
9664vif_to_lrp() {
9665 echo ${1%?}
9666}
9667
9668# Given the name of a logical port, prints the name of its logical
9669# switch, e.g. "vif_to_ls 123" yields 1.
9670vif_to_ls() {
9671 echo ${1%??}
9672}
9673
9674net_add n1
9675for i in 1 2 3; do
9676 sim_add hv$i
9677 as hv$i
9678 ovs-vsctl add-br br-phys
9679 ovn_attach n1 br-phys 192.168.0.$i
9680done
9681for i in 1 2 3; do
9682 for j in 1 2 3; do
9683 for k in 1 2 3; do
9684 hv=`vif_to_hv $i$j$k`
9685 as hv$hv ovs-vsctl \
9686 -- add-port br-int vif$i$j$k \
9687 -- set Interface vif$i$j$k \
9688 external-ids:iface-id=lp$i$j$k \
9689 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
9690 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
9691 ofport-request=$i$j$k
9692 done
9693 done
9694done
9695
9696# Pre-populate the hypervisors' ARP tables so that we don't lose any
9697# packets for ARP resolution (native tunneling doesn't queue packets
9698# for ARP resolution).
9699OVN_POPULATE_ARP
9700
9701# Allow some time for ovn-northd and ovn-controller to catch up.
9702# XXX This should be more systematic.
9703sleep 1
9704
9705# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9706#
9707# This shell function causes a packet to be received on INPORT. The packet's
9708# content has Ethernet destination DST and source SRC (each exactly 12 hex
9709# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
9710# more) list the VIFs on which the packet should be received. INPORT and the
9711# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9712for i in 1 2 3; do
9713 for j in 1 2 3; do
9714 for k in 1 2 3; do
9715 : > $i$j$k.expected
9716 done
9717 done
9718done
9719test_ip() {
9720 # This packet has bad checksums but logical L3 routing doesn't check.
9721 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
9722 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9723 shift; shift; shift; shift; shift
9724 hv=hv`vif_to_hv $inport`
9725 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
9726 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
9727 in_ls=`vif_to_ls $inport`
9728 in_lrp=`vif_to_lrp $inport`
9729 for outport; do
9730 out_ls=`vif_to_ls $outport`
9731 if test $in_ls = $out_ls; then
9732 # Ports on the same logical switch receive exactly the same packet.
9733 echo $packet
9734 else
9735 # Routing decrements TTL and updates source and dest MAC
9736 # (and checksum).
9737 out_lrp=`vif_to_lrp $outport`
9738 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
9739 fi >> $outport.expected
9740 done
9741}
9742
9743as hv1 ovs-vsctl --columns=name,ofport list interface
9744as hv1 ovn-sbctl list port_binding
9745as hv1 ovn-sbctl list datapath_binding
9746as hv1 ovn-sbctl list port_group
9747as hv1 ovn-sbctl list address_set
9748as hv1 ovn-sbctl dump-flows
9749as hv1 ovs-ofctl dump-flows br-int
9750
9751# Send IP packets between all pairs of source and destination ports,
9752# packets matches ACL (pg2 to pg1) should be dropped
9753ip_to_hex() {
9754 printf "%02x%02x%02x%02x" "$@"
9755}
9756for is in 1 2 3; do
9757 for js in 1 2 3; do
9758 for ks in 1 2 3; do
9759 bcast=
9760 s=$is$js$ks
9761 smac=f00000000$s
9762 sip=`ip_to_hex 192 168 $is$js $ks`
9763 for id in 1 2 3; do
9764 for jd in 1 2 3; do
9765 for kd in 1 2 3; do
9766 d=$id$jd$kd
9767 dip=`ip_to_hex 192 168 $id$jd $kd`
9768 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
9769 if test $d != $s; then unicast=$d; else unicast=; fi
9770
9771 # packets matches ACL should be dropped
9772 if test $id != 3 && test $kd == 1; then
9773 if test $is != 1 && test $ks == 2; then
9774 unicast=
9775 fi
9776 fi
9777 test_ip $s $smac $dmac $sip $dip $unicast #1
9778 done
9779 done
9780 done
9781 done
9782 done
9783done
9784
9785# Allow some time for packet forwarding.
9786# XXX This can be improved.
9787sleep 1
9788
9789# Now check the packets actually received against the ones expected.
9790for i in 1 2 3; do
9791 for j in 1 2 3; do
9792 for k in 1 2 3; do
9793 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
9794 [$i$j$k.expected])
9795 done
9796 done
9797done
9798
9799# Gracefully terminate daemons
9800OVN_CLEANUP([hv1], [hv2], [hv3])
9801AT_CLEANUP