]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
ovsdb: Fix memory leak in corner case in ovsdb_txn_commit_().
[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
RB
306$name => Syntax error at `$name' expecting address set name.
307
e0840f11
BP
308123 == xyzzy => Syntax error at `xyzzy' expecting field name.
309xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
310
311inport[1] == 1 => Cannot select subfield of string field inport.
312
313eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
314eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
315eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
316
317eth.type[5!] => Syntax error at `!' expecting `@:>@'.
318
319eth.type[5..1] => Invalid bit range 5 to 1.
320
321eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
322
323eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
324
325eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
326
327!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
328
329123 => Syntax error at end of input expecting relational operator.
330
331123 x => Syntax error at `x' expecting relational operator.
332
333{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
334
335eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
336
337(1 x) => Syntax error at `x' expecting `)'.
338
339!0x800 != eth.type => Missing parentheses around operand of !.
340
341eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
342
343eth.dst == {} => Syntax error at `}' expecting constant.
344
345eth.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).
346
3b7cb7e1 347ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
e0840f11
BP
348
3491 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
8b34ccda 350
9aef3c1b 351eth.dst[40] x => Syntax error at `x' expecting end of input.
ea382567
RB
352
353ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
354eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
e0840f11
BP
355]])
356sed 's/ =>.*//' test-cases.txt > input.txt
357sed 's/.* => //' test-cases.txt > expout
358AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
359AT_CLEANUP
360
361AT_SETUP([ovn -- expression annotation])
362dnl Input precedes =>, expected output follows =>.
363AT_DATA([test-cases.txt], [[
364ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
365ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
366ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
367ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
368ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
369
370ip => eth.type == 0x800 || eth.type == 0x86dd
371ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
372ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
373ip > 0 => Only == and != operators may be used with nominal field ip.
374!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
375ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
376
377vlan.present => vlan.tci[12]
378!vlan.present => !vlan.tci[12]
379
380!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
381vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
7700eea0 382!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
e0840f11
BP
383
384ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
385!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
386ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
387
388bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
389self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
390mutual_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'.
391mutual_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'.
392]])
393sed 's/ =>.*//' test-cases.txt > input.txt
394sed 's/.* => //' test-cases.txt > expout
395AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
396AT_CLEANUP
397
9d4aecca 398AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 399AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 400 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
401])
402AT_CLEANUP
403
9d4aecca 404AT_SETUP([ovn -- 2-term expression conversion])
e0840f11 405AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
8c3caa2c 406 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
407])
408AT_CLEANUP
409
9d4aecca 410AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 411AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
8c3caa2c 412 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
413])
414AT_CLEANUP
415
9d4aecca
BP
416AT_SETUP([ovn -- 3-term numeric expression simplification])
417AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
8c3caa2c 418 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
419])
420AT_CLEANUP
421
9d4aecca
BP
422AT_SETUP([ovn -- 4-term string expression simplification])
423AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
424 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
425])
426AT_CLEANUP
427
9d4aecca
BP
428AT_SETUP([ovn -- 3-term mixed expression simplification])
429AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
8c3caa2c 430 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
431])
432AT_CLEANUP
433
97ba1d55
BP
434AT_SETUP([ovn -- simplification special cases])
435simplify() {
436 echo "$1" | ovstest test-ovn simplify-expr
437}
438AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
439])
a3d79068
BP
440AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
441])
33f15d17
BP
442AT_CHECK([simplify 'tcp.dst >= 0'], [0],
443 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
444])
445AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
446 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
447])
448AT_CHECK([simplify 'tcp.dst > 0'], [0],
449 [[(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)
450]])
451AT_CHECK([simplify 'tcp.dst < 65535'], [0],
452 [[(!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)
453]])
97ba1d55
BP
454AT_CLEANUP
455
ba8d3816
MS
456AT_SETUP([ovn -- is_chassis_resident simplification])
457simplify() {
458 echo "$1" | ovstest test-ovn simplify-expr
459}
460AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
461])
462AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
463])
464AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
465])
466AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
467])
468AT_CLEANUP
469
9d4aecca
BP
470AT_SETUP([ovn -- 4-term numeric expression normalization])
471AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
8c3caa2c 472 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
473])
474AT_CLEANUP
475
9d4aecca
BP
476AT_SETUP([ovn -- 4-term string expression normalization])
477AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
478 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
479])
480AT_CLEANUP
481
482AT_SETUP([ovn -- 4-term mixed expression normalization])
483AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
8c3caa2c 484 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
9d4aecca
BP
485])
486AT_CLEANUP
487
488AT_SETUP([ovn -- 5-term numeric expression normalization])
489AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
8c3caa2c 490 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
9d4aecca
BP
491])
492AT_CLEANUP
493
494AT_SETUP([ovn -- 5-term string expression normalization])
495AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
496 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
497])
498AT_CLEANUP
499
500AT_SETUP([ovn -- 5-term mixed expression normalization])
501AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
8c3caa2c 502 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
503])
504AT_CLEANUP
505
506AT_SETUP([ovn -- 4-term numeric expressions to flows])
8c3caa2c 507AT_KEYWORDS([expression])
9d4aecca 508AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
8c3caa2c 509 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
9d4aecca
BP
510])
511AT_CLEANUP
512
513AT_SETUP([ovn -- 4-term string expressions to flows])
8c3caa2c 514AT_KEYWORDS([expression])
9d4aecca
BP
515AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
516 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
517])
518AT_CLEANUP
519
520AT_SETUP([ovn -- 4-term mixed expressions to flows])
8c3caa2c 521AT_KEYWORDS([expression])
9d4aecca 522AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
8c3caa2c 523 [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
524])
525AT_CLEANUP
526
527AT_SETUP([ovn -- 3-term numeric expressions to flows])
8c3caa2c 528AT_KEYWORDS([expression])
9d4aecca 529AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
8c3caa2c 530 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
531])
532AT_CLEANUP
f386a8a7
BP
533
534AT_SETUP([ovn -- converting expressions to flows -- string fields])
8c3caa2c 535AT_KEYWORDS([expression])
f386a8a7
BP
536expr_to_flow () {
537 echo "$1" | ovstest test-ovn expr-to-flows | sort
538}
cc5e28d8 539AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 540])
cc5e28d8 541AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
542])
543AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
544])
545AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
546ip,reg14=0x5
547ipv6,reg14=0x5
f386a8a7
BP
548])
549AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
550ip,reg14=0x6
551ipv6,reg14=0x6
f386a8a7
BP
552])
553AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
554])
555AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
556[reg14=0x5
557reg14=0x6
558reg14=0xfffe
f386a8a7
BP
559])
560AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
561ip,reg14=0x5
562ip,reg14=0x6
563ipv6,reg14=0x5
564ipv6,reg14=0x6
f386a8a7 565])
9d4aecca
BP
566AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
567(no flows)
568])
f386a8a7 569AT_CLEANUP
3b7cb7e1 570
2c5cbb15 571AT_SETUP([ovn -- converting expressions to flows -- address sets])
8c3caa2c 572AT_KEYWORDS([expression])
2c5cbb15
RB
573expr_to_flow () {
574 echo "$1" | ovstest test-ovn expr-to-flows | sort
575}
576AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
577ip,nw_src=10.0.0.1
578ip,nw_src=10.0.0.2
579ip,nw_src=10.0.0.3
580])
581AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
582ip,nw_src=10.0.0.1
583ip,nw_src=10.0.0.2
584ip,nw_src=10.0.0.3
585])
586AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
587ip,nw_src=1.2.3.4
588ip,nw_src=10.0.0.1
589ip,nw_src=10.0.0.2
590ip,nw_src=10.0.0.3
591])
592AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
593ip,nw_src=1.2.0.0/20
594ip,nw_src=10.0.0.1
595ip,nw_src=10.0.0.2
596ip,nw_src=10.0.0.3
597ip,nw_src=5.5.5.0/24
598])
599AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
600ipv6,ipv6_src=::1
601ipv6,ipv6_src=::2
602ipv6,ipv6_src=::3
603])
604AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
605ipv6,ipv6_src=::1
606ipv6,ipv6_src=::2
607ipv6,ipv6_src=::3
608ipv6,ipv6_src=::4
609])
610AT_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
611dl_src=00:00:00:00:00:01
612dl_src=00:00:00:00:00:02
613dl_src=00:00:00:00:00:03
614])
615AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
616dl_src=00:00:00:00:00:01
617dl_src=00:00:00:00:00:02
618dl_src=00:00:00:00:00:03
619])
ea382567
RB
620AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
621dl_src=00:00:00:00:00:01
622dl_src=00:00:00:00:00:02
623dl_src=00:00:00:00:00:03
624dl_src=ba:be:be:ef:de:ad
625])
f3a4e992
HZ
626AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
627(no flows)
628])
629AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
630ip,nw_src=1.2.3.4
631])
632AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
633ip,nw_src=1.2.3.4
634])
635AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
636
637])
638AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
639ip,nw_src=0.0.0.0/1.0.0.0
640ip,nw_src=128.0.0.0/1
641ip,nw_src=16.0.0.0/16.0.0.0
642ip,nw_src=2.0.0.0/2.0.0.0
643ip,nw_src=32.0.0.0/32.0.0.0
644ip,nw_src=4.0.0.0/4.0.0.0
645ip,nw_src=64.0.0.0/64.0.0.0
646ip,nw_src=8.0.0.0/8.0.0.0
647])
648AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
649ip,nw_src=0.0.0.0/1.0.0.0
650ip,nw_src=128.0.0.0/1
651ip,nw_src=16.0.0.0/16.0.0.0
652ip,nw_src=2.0.0.0/2.0.0.0
653ip,nw_src=32.0.0.0/32.0.0.0
654ip,nw_src=4.0.0.0/4.0.0.0
655ip,nw_src=64.0.0.0/64.0.0.0
656ip,nw_src=8.0.0.0/8.0.0.0
657])
2c5cbb15
RB
658AT_CLEANUP
659
3b7cb7e1 660AT_SETUP([ovn -- action parsing])
d5a76da4
BP
661dnl Unindented text is input (a set of OVN logical actions).
662dnl Indented text is expected output.
663AT_DATA([test-cases.txt],
664[[# drop
665drop;
666 encodes as drop
667drop; next;
668 Syntax error at `next' expecting end of input.
669next; drop;
670 Syntax error at `drop' expecting action.
5f822129
BP
671
672# output
d5a76da4
BP
673output;
674 encodes as resubmit(,64)
5f822129
BP
675
676# next
d5a76da4 677next;
00c875d0 678 encodes as resubmit(,19)
d5a76da4 679next(11);
8f5de083 680 formats as next;
00c875d0 681 encodes as resubmit(,19)
d5a76da4 682next(0);
00c875d0
MS
683 encodes as resubmit(,8)
684next(23);
d5a76da4
BP
685 encodes as resubmit(,31)
686
687next();
4c99cb18 688 Syntax error at `)' expecting "pipeline" or "table".
d5a76da4
BP
689next(10;
690 Syntax error at `;' expecting `)'.
00c875d0
MS
691next(24);
692 "next" action cannot advance beyond table 23.
5f822129 693
4c99cb18
BP
694next(table=11);
695 formats as next;
00c875d0 696 encodes as resubmit(,19)
4c99cb18
BP
697next(pipeline=ingress);
698 formats as next;
00c875d0 699 encodes as resubmit(,19)
4c99cb18
BP
700next(table=11, pipeline=ingress);
701 formats as next;
00c875d0 702 encodes as resubmit(,19)
4c99cb18
BP
703next(pipeline=ingress, table=11);
704 formats as next;
00c875d0 705 encodes as resubmit(,19)
4c99cb18
BP
706
707next(pipeline=egress);
708 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
709
710next(table=10);
711 formats as next(10);
00c875d0 712 encodes as resubmit(,18)
4c99cb18 713
5f822129 714# Loading a constant value.
d5a76da4
BP
715tcp.dst=80;
716 formats as tcp.dst = 80;
717 encodes as set_field:80->tcp_dst
718 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
719eth.dst[40] = 1;
720 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
721vlan.pcp = 2;
722 encodes as set_field:0x4000/0xe000->vlan_tci
723 has prereqs vlan.tci[12]
724vlan.tci[13..15] = 2;
725 encodes as set_field:0x4000/0xe000->vlan_tci
726inport = "";
727 encodes as set_field:0->reg14
728ip.ttl=4;
729 formats as ip.ttl = 4;
730 encodes as set_field:4->nw_ttl
731 has prereqs eth.type == 0x800 || eth.type == 0x86dd
732outport="eth0"; next; outport="LOCAL"; next;
8f5de083 733 formats as outport = "eth0"; next; outport = "LOCAL"; next;
00c875d0 734 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
d5a76da4
BP
735
736inport[1] = 1;
737 Cannot select subfield of string field inport.
738ip.proto[1] = 1;
739 Cannot select subfield of nominal field ip.proto.
740eth.dst[40] == 1;
741 Syntax error at `==' expecting `=' or `<->'.
742ip = 1;
743 Predicate symbol ip used where lvalue required.
744ip.proto = 6;
745 Field ip.proto is not modifiable.
746inport = {"a", "b"};
747 Syntax error at `{' expecting constant.
748inport = {};
749 Syntax error at `{' expecting constant.
750bad_prereq = 123;
751 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
752self_recurse = 123;
753 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'.
754vlan.present = 0;
755 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
756
757# Moving one field into another.
d5a76da4
BP
758reg0=reg1;
759 formats as reg0 = reg1;
760 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
761vlan.pcp = reg0[0..2];
762 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
763 has prereqs vlan.tci[12]
764reg0[10] = vlan.pcp[1];
765 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
766 has prereqs vlan.tci[12]
767outport = inport;
768 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
769
770reg0[0] = vlan.present;
771 Predicate symbol vlan.present used where lvalue required.
772reg0 = reg1[0..10];
773 Can't assign 11-bit value to 32-bit destination.
774inport = reg0;
775 Can't assign integer field (reg0) to string field (inport).
776inport = big_string;
777 String fields inport and big_string are incompatible for assignment.
778ip.proto = reg0[0..7];
779 Field ip.proto is not modifiable.
5f822129
BP
780
781# Exchanging fields.
d5a76da4
BP
782reg0 <-> reg1;
783 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]
784vlan.pcp <-> reg0[0..2];
785 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]
786 has prereqs vlan.tci[12]
787reg0[10] <-> vlan.pcp[1];
788 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
789 has prereqs vlan.tci[12]
790outport <-> inport;
791 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
792
793reg0[0] <-> vlan.present;
794 Predicate symbol vlan.present used where lvalue required.
795reg0 <-> reg1[0..10];
796 Can't exchange 32-bit field with 11-bit field.
797inport <-> reg0;
798 Can't exchange string field (inport) with integer field (reg0).
799inport <-> big_string;
800 String fields inport and big_string are incompatible for exchange.
801ip.proto <-> reg0[0..7];
802 Field ip.proto is not modifiable.
803reg0[0..7] <-> ip.proto;
804 Field ip.proto is not modifiable.
5f822129
BP
805
806# TTL decrement.
d5a76da4
BP
807ip.ttl--;
808 encodes as dec_ttl
809 has prereqs ip
810ip.ttl
811 Syntax error at end of input expecting `--'.
5f822129 812
467085fd 813# load balancing.
d5a76da4 814ct_lb;
00c875d0 815 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
816 has prereqs ip
817ct_lb();
818 formats as ct_lb;
00c875d0 819 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
820 has prereqs ip
821ct_lb(192.168.1.2:80, 192.168.1.3:80);
822 encodes as group:1
823 has prereqs ip
824ct_lb(192.168.1.2, 192.168.1.3, );
825 formats as ct_lb(192.168.1.2, 192.168.1.3);
826 encodes as group:2
827 has prereqs ip
9d236afa
MM
828ct_lb(fd0f::2, fd0f::3, );
829 formats as ct_lb(fd0f::2, fd0f::3);
830 encodes as group:3
831 has prereqs ip
d5a76da4
BP
832
833ct_lb(192.168.1.2:);
834 Syntax error at `)' expecting port number.
835ct_lb(192.168.1.2:123456);
836 Syntax error at `123456' expecting port number.
837ct_lb(foo);
9d236afa
MM
838 Syntax error at `foo' expecting IP address.
839ct_lb([192.168.1.2]);
840 Syntax error at `192.168.1.2' expecting IPv6 address.
d5a76da4
BP
841
842# ct_next
843ct_next;
00c875d0 844 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
d5a76da4
BP
845 has prereqs ip
846
847# ct_commit
848ct_commit;
849 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
850 has prereqs ip
851ct_commit();
852 formats as ct_commit;
853 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
854 has prereqs ip
855ct_commit(ct_mark=1);
856 formats as ct_commit(ct_mark=0x1);
857 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
858 has prereqs ip
859ct_commit(ct_mark=1/1);
860 formats as ct_commit(ct_mark=0x1/0x1);
861 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
862 has prereqs ip
863ct_commit(ct_label=1);
864 formats as ct_commit(ct_label=0x1);
865 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
866 has prereqs ip
867ct_commit(ct_label=1/1);
868 formats as ct_commit(ct_label=0x1/0x1);
869 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
870 has prereqs ip
871ct_commit(ct_mark=1, ct_label=2);
872 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
873 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
874 has prereqs ip
875
876ct_commit(ct_label=0x01020304050607080910111213141516);
877 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
878 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
879 has prereqs ip
880ct_commit(ct_label=0x181716151413121110090807060504030201);
881 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
882 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
883 has prereqs ip
884ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
885 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
886 has prereqs ip
887ct_commit(ct_label=18446744073709551615);
888 formats as ct_commit(ct_label=0xffffffffffffffff);
889 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
890 has prereqs ip
891ct_commit(ct_label=18446744073709551616);
892 Decimal constants must be less than 2**64.
893
894# ct_dnat
895ct_dnat;
00c875d0 896 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
d5a76da4
BP
897 has prereqs ip
898ct_dnat(192.168.1.2);
00c875d0 899 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
d5a76da4
BP
900 has prereqs ip
901
902ct_dnat(192.168.1.2, 192.168.1.3);
903 Syntax error at `,' expecting `)'.
904ct_dnat(foo);
905 Syntax error at `foo' expecting IPv4 address.
906ct_dnat(foo, bar);
907 Syntax error at `foo' expecting IPv4 address.
908ct_dnat();
909 Syntax error at `)' expecting IPv4 address.
910
911# ct_snat
912ct_snat;
00c875d0 913 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
d5a76da4
BP
914 has prereqs ip
915ct_snat(192.168.1.2);
00c875d0 916 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
d5a76da4
BP
917 has prereqs ip
918
919ct_snat(192.168.1.2, 192.168.1.3);
920 Syntax error at `,' expecting `)'.
921ct_snat(foo);
922 Syntax error at `foo' expecting IPv4 address.
923ct_snat(foo, bar);
924 Syntax error at `foo' expecting IPv4 address.
925ct_snat();
926 Syntax error at `)' expecting IPv4 address.
de297547 927
db0e819b
BP
928# ct_clear
929ct_clear;
930 encodes as ct_clear
931
b3bd2c33 932# clone
8f5de083 933clone { ip4.dst = 255.255.255.255; output; }; next;
00c875d0 934 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
b3bd2c33
BP
935 has prereqs eth.type == 0x800
936
6335d074 937# arp
8a41ad8e
BP
938arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
939 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 940 has prereqs ip4
bac29564
BP
941arp { };
942 formats as arp { drop; };
943 encodes as controller(userdata=00.00.00.00.00.00.00.00)
944 has prereqs ip4
6335d074 945
0bac7164 946# get_arp
d5a76da4
BP
947get_arp(outport, ip4.dst);
948 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[]
949 has prereqs eth.type == 0x800
950get_arp(inport, reg0);
951 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[]
952
953get_arp;
954 Syntax error at `;' expecting `('.
955get_arp();
956 Syntax error at `)' expecting field name.
957get_arp(inport);
958 Syntax error at `)' expecting `,'.
959get_arp(inport ip4.dst);
960 Syntax error at `ip4.dst' expecting `,'.
961get_arp(inport, ip4.dst;
962 Syntax error at `;' expecting `)'.
963get_arp(inport, eth.dst);
964 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
965get_arp(inport, outport);
966 Cannot use string field outport where numeric field is required.
967get_arp(reg0, ip4.dst);
968 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
969
970# put_arp
d5a76da4
BP
971put_arp(inport, arp.spa, arp.sha);
972 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[]
973 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 974
42814145 975# put_dhcp_opts
d5a76da4
BP
976reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
977 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)
978reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
979 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");
980 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)
981reg0[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);
982 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);
983 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)
984
985reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
986 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
987reg1[0] = put_dhcp_opts();
988 put_dhcp_opts requires offerip to be specified.
989reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
990 Syntax error at `x' expecting DHCPv4 option name.
991reg1[0] = put_dhcp_opts(router = 10.0.0.1);
992 put_dhcp_opts requires offerip to be specified.
993reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
994 Syntax error at `"hi"'.
995reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
996 Syntax error at `xyzzy' expecting DHCPv4 option name.
997reg1[0] = put_dhcp_opts(offerip="xyzzy");
998 DHCPv4 option offerip requires numeric value.
999reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1000 DHCPv4 option domain requires string value.
42814145 1001
b1a3a6a4
NS
1002# nd_ns
1003nd_ns { nd.target = xxreg0; output; };
1004 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)
1005 has prereqs ip6
1006
1007nd_ns { };
1008 formats as nd_ns { drop; };
1009 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1010 has prereqs ip6
1011
f8a8db39 1012# nd_na
d5a76da4
BP
1013nd_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; };
1014 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1015 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)
1016 has prereqs nd_ns
e75451fe 1017
c34a87b6 1018# get_nd
d5a76da4
BP
1019get_nd(outport, ip6.dst);
1020 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[]
1021 has prereqs eth.type == 0x86dd
1022get_nd(inport, xxreg0);
1023 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[]
1024get_nd;
1025 Syntax error at `;' expecting `('.
1026get_nd();
1027 Syntax error at `)' expecting field name.
1028get_nd(inport);
1029 Syntax error at `)' expecting `,'.
1030get_nd(inport ip6.dst);
1031 Syntax error at `ip6.dst' expecting `,'.
1032get_nd(inport, ip6.dst;
1033 Syntax error at `;' expecting `)'.
1034get_nd(inport, eth.dst);
1035 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1036get_nd(inport, outport);
1037 Cannot use string field outport where numeric field is required.
1038get_nd(xxreg0, ip6.dst);
1039 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
1040
1041# put_nd
d5a76da4
BP
1042put_nd(inport, nd.target, nd.sll);
1043 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[]
1044 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 1045
01cfdb2f 1046# put_dhcpv6_opts
d5a76da4 1047reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
a55dacac 1048 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
1049reg1[0] = put_dhcpv6_opts();
1050 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1051reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1052 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
a55dacac 1053 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
1054reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1055 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
a55dacac 1056 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 1057reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
a55dacac 1058 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
1059reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1060 Syntax error at `x' expecting DHCPv6 option name.
1061reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1062 Syntax error at `"hi"'.
1063reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1064 Syntax error at `xyzzy' expecting DHCPv6 option name.
1065reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1066 DHCPv6 option ia_addr requires numeric value.
1067reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1068 DHCPv6 option domain_search requires string value.
01cfdb2f 1069
a6095f81
BS
1070# set_queue
1071set_queue(0);
1072 encodes as set_queue:0
1073set_queue(61440);
1074 encodes as set_queue:61440
1075set_queue(65535);
1076 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1077
ea991ad2
NS
1078# dns_lookup
1079reg1[0] = dns_lookup();
1080 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1081 has prereqs udp
1082reg1[0] = dns_lookup("foo");
1083 dns_lookup doesn't take any parameters
1084
52ed5fcc
NS
1085# put_nd_ra_opts
1086reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1087 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)
1088 has prereqs ip6
1089reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1090 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)
1091 has prereqs ip6
1092reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1093 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)
1094 has prereqs ip6
1095reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1096 slla option not present
1097reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1098 prefix option can't be set when address mode is dhcpv6_stateful.
1099reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1100 prefix option can't be set when address mode is dhcpv6_stateful.
1101reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1102 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1103reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1104 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1105reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1106 Syntax error at `dhcpv6_stateless' expecting constant.
1107reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1108 Invalid value for "prefix" option
1109reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1110 Invalid value for "addr_mode" option
1111reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1112 IPv6 ND RA option mtu requires numeric value.
1113reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1114 Invalid value for "mtu" option
1115
5f822129 1116# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
1117ip4.src = ip6.src[0..31];
1118 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1119 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1120ip4.src <-> ip6.src[0..31];
1121 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[]
1122 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1123
1124# Miscellaneous negative tests.
1125;
1126 Syntax error at `;'.
1127xyzzy;
1128 Syntax error at `xyzzy' expecting action.
1129next; 123;
1130 Syntax error at `123'.
1131next; xyzzy;
1132 Syntax error at `xyzzy' expecting action.
1133next
9aef3c1b 1134 Syntax error at end of input expecting `;'.
3b7cb7e1 1135]])
d5a76da4
BP
1136sed '/^[[ ]]/d' test-cases.txt > input.txt
1137cp test-cases.txt expout
3b7cb7e1
BP
1138AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1139AT_CLEANUP
f295c17b
BP
1140
1141AT_BANNER([OVN end-to-end tests])
1142
9975d7be
BP
1143# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1144AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1145AT_KEYWORDS([ovnarp])
f295c17b
BP
1146AT_SKIP_IF([test $HAVE_PYTHON = no])
1147ovn_start
1148
1149# Create hypervisors hv[123].
9975d7be 1150# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1151# Add all of the vifs to a single logical switch lsw0.
1152# Turn on port security on all the vifs except vif[123]1.
1153# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1154# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1155ovn-nbctl ls-add lsw0
f295c17b
BP
1156net_add n1
1157for i in 1 2 3; do
1158 sim_add hv$i
1159 as hv$i
1160 ovs-vsctl add-br br-phys
1161 ovn_attach n1 br-phys 192.168.0.$i
1162
1163 for j in 1 2 3; do
1164 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 1165 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1166 if test $j = 1; then
31ed1192 1167 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1168 else
7dc88496
NS
1169 if test $j = 3; then
1170 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1171 else
1172 ip_addrs="192.168.0.$i$j"
1173 fi
31ed1192
JP
1174 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1175 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1176 fi
1177 done
1178done
1179ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1180ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1181ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1182ovn-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\"
1183ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b
BP
1184
1185# Pre-populate the hypervisors' ARP tables so that we don't lose any
1186# packets for ARP resolution (native tunneling doesn't queue packets
1187# for ARP resolution).
1188ovn_populate_arp
1189
1190# Allow some time for ovn-northd and ovn-controller to catch up.
1191# XXX This should be more systematic.
1192sleep 1
611099dc 1193
fc6f9978
HZ
1194# Make sure there is no attempt to adding duplicated flows by ovn-controller
1195AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1196AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1197AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1198
57d143eb
HZ
1199# Given the name of a logical port, prints the name of the hypervisor
1200# on which it is located.
1201vif_to_hv() {
1202 echo hv${1%?}
1203}
1204
f295c17b
BP
1205# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1206#
1207# This shell function causes a packet to be received on INPORT. The packet's
1208# content has Ethernet destination DST and source SRC (each exactly 12 hex
1209# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1210# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1211# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1212for i in 1 2 3; do
1213 for j in 1 2 3; do
1214 : > $i$j.expected
1215 done
1216done
1217test_packet() {
1218 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1219 hv=`vif_to_hv $inport`
f295c17b
BP
1220 vif=vif$inport
1221 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1222 for outport; do
e4543cfe 1223 echo $packet >> $outport.expected
f295c17b
BP
1224 done
1225}
1226
57d143eb
HZ
1227# test_arp INPORT SHA SPA TPA [REPLY_HA]
1228#
1229# Causes a packet to be received on INPORT. The packet is an ARP
1230# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1231# it should be the hardware address of the target to expect to receive in an
1232# ARP reply; otherwise no reply is expected.
1233#
31ed1192 1234# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1235# SHA and REPLY_HA are each 12 hex digits.
1236# SPA and TPA are each 8 hex digits.
1237test_arp() {
1238 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1239 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1240 hv=`vif_to_hv $inport`
1241 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1242
92f9822b 1243 if test X$reply_ha = X; then
57d143eb
HZ
1244 # Expect to receive the broadcast ARP on the other logical switch ports
1245 # if no reply is expected.
1246 local i j
1247 for i in 1 2 3; do
1248 for j in 1 2 3; do
1249 if test $i$j != $inport; then
1250 echo $request >> $i$j.expected
1251 fi
1252 done
1253 done
1254 else
1255 # Expect to receive the reply, if any.
1256 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1257 echo $reply >> $inport.expected
1258 fi
1259}
1260
1261ip_to_hex() {
1262 printf "%02x%02x%02x%02x" "$@"
1263}
1264
f295c17b
BP
1265# Send packets between all pairs of source and destination ports:
1266#
31ed1192
JP
1267# 1. Unicast packets are delivered to exactly one logical switch port
1268# (except that packets destined to their input ports are dropped).
f295c17b 1269#
31ed1192
JP
1270# 2. Broadcast and multicast are delivered to all logical switch ports
1271# except the input port.
f295c17b 1272#
ea46a4e9 1273# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1274# MAC address.
1275#
ea46a4e9 1276# 4. The switch drops all packets with a VLAN tag.
f295c17b 1277#
ea46a4e9 1278# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1279# affects behavior when port security is turned off, since otherwise port
1280# security would drop the packet anyway.)
1281#
ea46a4e9 1282# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1283# switch ports with "unknown" among their MAC addresses (and port
1284# security disabled).
f295c17b 1285#
ea46a4e9 1286# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1287#
ea46a4e9 1288# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1289#
9fcb6a18
BP
1290# 9. OVN generates responses to ARP requests for known IPs, except for
1291# requests from a port for the port's own IP.
57d143eb
HZ
1292#
1293# 10. No response to ARP requests for unknown IPs.
4acd1e87 1294
f295c17b
BP
1295for is in 1 2 3; do
1296 for js in 1 2 3; do
1297 s=$is$js
1298 bcast=
4d5c43d5
JP
1299 unknown=
1300 bacl2=
1301 bacl3=
f295c17b
BP
1302 for id in 1 2 3; do
1303 for jd in 1 2 3; do
1304 d=$id$jd
1305
1306 if test $d != $s; then unicast=$d; else unicast=; fi
1307 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1308
1309 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1310 impersonate=$d
1311 else
1312 impersonate=
1313 fi
f295c17b
BP
1314 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1315
4d5c43d5
JP
1316 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1317 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1318 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1319 # Source of 11, 21, or 31 and dest of 33 should be dropped
1320 # due to the 4th ACL that uses address_set(set1).
1321 acl4=
1322 else
1323 acl4=$d
1324 fi
f295c17b
BP
1325 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1326 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1327 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1328 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
f295c17b
BP
1329
1330 test_packet $s f000000000$d f00000000055 810000091234 #4
1331 test_packet $s f000000000$d 0100000000$s $s$d #5
1332
4d5c43d5
JP
1333 if test $d != $s && test $jd = 1; then
1334 unknown="$unknown $d"
1335 fi
f295c17b
BP
1336 bcast="$bcast $unicast"
1337 bacl2="$bacl2 $acl2"
1338 bacl3="$bacl3 $acl3"
57d143eb
HZ
1339
1340 sip=`ip_to_hex 192 168 0 $i$j`
1341 tip=`ip_to_hex 192 168 0 $id$jd`
1342 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1343 if test $d != $s; then
1344 reply_ha=f000000000$d
1345 else
1346 reply_ha=
1347 fi
1348 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1349 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1350
1351 if test $jd = 3; then
31ed1192 1352 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1353 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1354 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1355 fi
f295c17b
BP
1356 done
1357 done
1358
4d5c43d5 1359 # Broadcast and multicast.
f295c17b
BP
1360 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1361 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1362 if test $js = 1; then
f295c17b
BP
1363 bcast_impersonate=$bcast
1364 else
4d5c43d5
JP
1365 bcast_impersonate=
1366 fi
f295c17b
BP
1367 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1368
1369 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1370
1371 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1372 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1373 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1374 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1375 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1376 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1377 done
1378done
1379
7dc88496
NS
1380# set address for lp13 with invalid characters.
1381# lp13 should be configured with only 192.168.0.13.
31ed1192 1382ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1383
1384# Allow some time for ovn-northd and ovn-controller to catch up.
1385# XXX This should be more systematic.
1386sleep 1
1387
7dc88496
NS
1388sip=`ip_to_hex 192 168 0 11`
1389tip=`ip_to_hex 192 168 0 13`
1390test_arp 11 f00000000011 $sip $tip f00000000013
1391
1392tip=`ip_to_hex 192 169 0 13`
1393#arp request for 192.169.0.13 should be flooded
1394test_arp 11 f00000000011 $sip $tip
1395
91125642 1396# dump information and flows with counters
bb0c41d3
RM
1397ovn-sbctl dump-flows -- list multicast_group
1398
1399echo "------ hv1 dump ------"
1400as hv1 ovs-vsctl show
1401as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1402
1403echo "------ hv2 dump ------"
1404as hv2 ovs-vsctl show
1405as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1406
1407echo "------ hv3 dump ------"
1408as hv3 ovs-vsctl show
1409as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1410
f295c17b
BP
1411# Now check the packets actually received against the ones expected.
1412for i in 1 2 3; do
1413 for j in 1 2 3; do
49d7c759 1414 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1415 done
1416done
fcde56f5 1417
7a8f15e0 1418OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1419
f295c17b 1420AT_CLEANUP
eb6b08eb 1421
4acd1e87
BP
1422AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1423AT_SKIP_IF([test $HAVE_PYTHON = no])
1424ovn_start
1425
1426# Create a logical switch and some logical ports.
1427# Turn on port security on all lports except ls1.
1428# Make ls1 a destination for unknown MACs.
1429# Add some ACLs for Ethertypes 1234, 1235, 1236.
1430ovn-nbctl ls-add lsw0
1431ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1432for i in 1 2 3; do
1433 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1434done
1435ovn-nbctl --wait=sb sync
1436for i in 1 2 3; do
4acd1e87
BP
1437 ovn-sbctl lsp-bind lp$i hv0
1438 if test $i = 1; then
abb37b6b 1439 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1440 else
abb37b6b
FF
1441 if test $i = 3; then
1442 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1443 else
1444 ip_addrs="192.168.0.$i"
1445 fi
1446 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1447 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
4acd1e87
BP
1448 fi
1449done
1450ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1451ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1452ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1453ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1454ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1455
1456ovn-nbctl --wait=sb sync
1457on_exit 'kill `cat ovn-trace.pid`'
1458ovn-trace --detach --pidfile --no-chdir
1459
1460# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1461#
1462# This shell function causes a packet to be received on INPORT. The packet's
1463# content has Ethernet destination DST and source SRC (each exactly 12 hex
1464# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1465# more) list the VIFs on which the packet should be received. INPORT and the
1466# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1467test_packet() {
1468 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1469 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1470 while :; do
abb37b6b
FF
1471 case $1 in # (
1472 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1473 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1474 *) break ;;
1475 esac
4acd1e87
BP
1476 done
1477 for outport; do
abb37b6b 1478 echo "output(\"lp$outport\");"
4acd1e87
BP
1479 done > expout
1480
1481 AT_CAPTURE_FILE([trace])
1482 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1483}
1484
1485# test_arp INPORT SHA SPA TPA [REPLY_HA]
1486#
1487# Causes a packet to be received on INPORT. The packet is an ARP
1488# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1489# it should be the hardware address of the target to expect to receive in an
1490# ARP reply; otherwise no reply is expected.
1491#
1492# INPORT is an logical switch port number, e.g. 11 for vif11.
1493# SHA and REPLY_HA are each 12 hex digits.
1494# SPA and TPA are each 8 hex digits.
1495test_arp() {
1496 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1497
1498 local request="inport == \"lp$inport\"
1499 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1500 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1501 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1502
1503 if test -z "$reply_ha"; then
1504 reply=
abb37b6b
FF
1505 local i
1506 for i in 1 2 3; do
1507 if test $i != $inport; then
1508 reply="${reply}output(\"lp$i\");
4acd1e87 1509"
abb37b6b
FF
1510 fi
1511 done
4acd1e87
BP
1512 else
1513 reply="\
1514eth.dst = $sha;
1515eth.src = $reply_ha;
1516arp.op = 2;
1517arp.tha = $sha;
1518arp.sha = $reply_ha;
1519arp.tpa = $spa;
1520arp.spa = $tpa;
1521output(\"lp$inport\");
1522"
1523 fi
1524
1525 AT_CAPTURE_FILE([trace])
1526 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1527}
1528
1529# Send packets between all pairs of source and destination ports:
1530#
1531# 1. Unicast packets are delivered to exactly one logical switch port
1532# (except that packets destined to their input ports are dropped).
1533#
1534# 2. Broadcast and multicast are delivered to all logical switch ports
1535# except the input port.
1536#
1537# 3. When port security is turned on, the switch drops packets from the wrong
1538# MAC address.
1539#
1540# 4. The switch drops all packets with a VLAN tag.
1541#
1542# 5. The switch drops all packets with a multicast source address. (This only
1543# affects behavior when port security is turned off, since otherwise port
1544# security would drop the packet anyway.)
1545#
1546# 6. The switch delivers packets with an unknown destination to logical
1547# switch ports with "unknown" among their MAC addresses (and port
1548# security disabled).
1549#
1550# 7. The switch drops unicast packets that violate an ACL.
1551#
1552# 8. The switch drops multicast and broadcast packets that violate an ACL.
1553#
9fcb6a18
BP
1554# 9. OVN generates responses to ARP requests for known IPs, except for
1555# requests from a port for the port's own IP.
4acd1e87
BP
1556#
1557# 10. No response to ARP requests for unknown IPs.
1558
1559for s in 1 2 3; do
1560 bcast=
1561 unknown=
1562 bacl2=
1563 bacl3=
1564 for d in 1 2 3; do
abb37b6b
FF
1565 echo
1566 echo "lp$s -> lp$d"
1567 if test $d != $s; then unicast=$d; else unicast=; fi
1568 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1569
1570 if test $d != $s && test $s = 1; then
1571 impersonate=$d
1572 else
1573 impersonate=
1574 fi
1575 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1576
1577 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1578 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1579 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1580 # Source of 1 or 2 and dest of 3 should be dropped
1581 # due to the 4th ACL that uses address_set(set1).
1582 acl4=
1583 else
1584 acl4=$d
1585 fi
1586
1587 #7, acl1 to acl4:
1588 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1589 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1590 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1591 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1592
1593 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1594 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1595
1596 if test $d != $s && test $d = 1; then
1597 unknown="$unknown $d"
1598 fi
1599 bcast="$bcast $unicast"
1600 bacl2="$bacl2 $acl2"
1601 bacl3="$bacl3 $acl3"
1602
1603 sip=192.168.0.$s
1604 tip=192.168.0.$d
1605 tip_unknown=11.11.11.11
9fcb6a18
BP
1606 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1607 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1608 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1609
1610 if test $d = 3; then
1611 # lp3 has an additional ip 192.169.0.[123]3.
1612 tip=192.169.0.$d
9fcb6a18 1613 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1614 fi
4acd1e87
BP
1615 done
1616
1617 # Broadcast and multicast.
1618 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1619 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1620 if test $s = 1; then
abb37b6b 1621 bcast_impersonate=$bcast
4acd1e87 1622 else
abb37b6b 1623 bcast_impersonate=
4acd1e87
BP
1624 fi
1625 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1626
1627 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1628
1629 #8, acl1 to acl3:
1630 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1631 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1632 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1633
1634 #8, acl1 to acl3:
1635 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1636 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1637 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1638done
1639
1640AT_CLEANUP
1641
7277bc83
RB
1642# 2 hypervisors, 4 logical ports per HV
1643# 2 locally attached networks (one flat, one vlan tagged over same device)
1644# 2 ports per HV on each network
e90aeb57 1645AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1646AT_SKIP_IF([test $HAVE_PYTHON = no])
1647ovn_start
1648
ea46a4e9
JP
1649# In this test cases we create 3 switches, all connected to same
1650# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1651# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1652# of VIF port name indicates the hypervisor it is bound to, e.g.
1653# lp23 means VIF 3 on hv2.
1654#
ea46a4e9 1655# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1656# - ls1:
1657# - untagged
ea46a4e9 1658# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1659#
1660# - ls2:
1661# - tagged with VLAN 101
ea46a4e9 1662# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1663# - ls3:
1664# - untagged
ea46a4e9 1665# - ports: lp15, lp25
0ee7f7f1 1666#
ea46a4e9 1667# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1668# physical network.
1669
1670for i in 1 2 3; do
ea46a4e9
JP
1671 ls_name=ls$i
1672 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1673 ln_port_name=ln$i
1674 if test $i -eq 2; then
ea46a4e9 1675 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1676 else
ea46a4e9 1677 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1678 fi
31ed1192
JP
1679 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1680 ovn-nbctl lsp-set-type $ln_port_name localnet
1681 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1682done
d79fc5f4 1683
69b72264
BP
1684# lsp_to_ls LSP
1685#
1686# Prints the name of the logical switch that contains LSP.
1687lsp_to_ls () {
1688 case $1 in dnl (
1689 lp?[[12]]) echo ls1 ;; dnl (
1690 lp?[[34]]) echo ls2 ;; dnl (
1691 lp?5) echo ls3 ;; dnl (
1692 *) AT_FAIL_IF([:]) ;;
1693 esac
1694}
1695
d79fc5f4
RB
1696net_add n1
1697for i in 1 2; do
1698 sim_add hv$i
1699 as hv$i
1700 ovs-vsctl add-br br-phys
1701 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1702 ovn_attach n1 br-phys 192.168.0.$i
1703
0ee7f7f1 1704 for j in 1 2 3 4 5; do
d79fc5f4
RB
1705 ovs-vsctl add-port br-int vif$i$j -- \
1706 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1707 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1708 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1709 ofport-request=$i$j
1710
31ed1192 1711 lsp_name=lp$i$j
69b72264 1712 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 1713
ea46a4e9 1714 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1715 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1716 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1717
31ed1192 1718 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1719 done
1720done
69b72264
BP
1721ovn-nbctl --wait=sb sync
1722ovn-sbctl dump-flows
d79fc5f4
RB
1723
1724ovn_populate_arp
1725
1726# XXX This is now the 3rd copy of these functions in this file ...
1727
1728# Given the name of a logical port, prints the name of the hypervisor
1729# on which it is located.
1730vif_to_hv() {
1731 echo hv${1%?}
1732}
1733#
69b72264 1734# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
1735#
1736# This shell function causes a packet to be received on INPORT. The packet's
1737# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
1738# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1739# logical switch port numbers, e.g. 11 for vif11.
1740#
1741# EOUT is the end-to-end output port, that is, where the packet will end up
1742# after possibly bouncing through one or more localnet ports. LOUT is the
1743# logical output port, which might be a localnet port, as seen by ovn-trace
1744# (which doesn't know what localnet ports are connected to and therefore can't
1745# figure out the end-to-end answer).
d79fc5f4 1746for i in 1 2; do
0ee7f7f1 1747 for j in 1 2 3 4 5; do
d79fc5f4
RB
1748 : > $i$j.expected
1749 done
1750done
1751test_packet() {
69b72264
BP
1752 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1753 echo "$@"
1754
1755 # First try tracing the packet.
1756 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1757 if test $lout != drop; then
1758 echo "output(\"$lout\");"
1759 fi > expout
1760 AT_CAPTURE_FILE([trace])
1761 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1762
1763 # Then actually send a packet, for an end-to-end test.
1764 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
1765 hv=`vif_to_hv $inport`
1766 vif=vif$inport
1767 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
1768 if test $eout != drop; then
1769 echo $packet >> ${eout#lp}.expected
1770 fi
d79fc5f4
RB
1771}
1772
7277bc83
RB
1773# lp11 and lp21 are on the same network (phys, untagged)
1774# and on different hypervisors
69b72264
BP
1775test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1776test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 1777
7277bc83
RB
1778# lp11 and lp12 are on the same network (phys, untagged)
1779# and on the same hypervisor
69b72264
BP
1780test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1781test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
1782
1783# lp13 and lp23 are on the same network (phys, VLAN 101)
1784# and on different hypervisors
69b72264
BP
1785test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1786test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
1787
1788# lp13 and lp14 are on the same network (phys, VLAN 101)
1789# and on the same hypervisor
69b72264
BP
1790test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1791test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 1792
0ee7f7f1 1793# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 1794# same hypervisor, and on different switches
69b72264
BP
1795test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1796test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
1797
1798# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 1799# different hypervisors, and on different switches
69b72264
BP
1800test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1801test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 1802
d79fc5f4 1803# Ports that should not be able to communicate
69b72264
BP
1804test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1805test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1806test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1807test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1808test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1809test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1810test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1811test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 1812
d79fc5f4
RB
1813# Dump a bunch of info helpful for debugging if there's a failure.
1814
1815echo "------ OVN dump ------"
1816ovn-nbctl show
1817ovn-sbctl show
1818
1819echo "------ hv1 dump ------"
1820as hv1 ovs-vsctl show
1821as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1822
1823echo "------ hv2 dump ------"
1824as hv2 ovs-vsctl show
1825as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1826
1827# Now check the packets actually received against the ones expected.
1828for i in 1 2; do
0ee7f7f1 1829 for j in 1 2 3 4 5; do
49d7c759 1830 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
1831 done
1832done
1833
7a8f15e0 1834OVN_CLEANUP([hv1],[hv2])
d9c8c57c 1835
d79fc5f4
RB
1836AT_CLEANUP
1837
91125642
FF
1838AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1839AT_KEYWORDS([vtep])
eb6b08eb
JP
1840AT_SKIP_IF([test $HAVE_PYTHON = no])
1841ovn_start
1842
1843# Configure the Northbound database
ea46a4e9 1844ovn-nbctl ls-add lsw0
eb6b08eb 1845
31ed1192
JP
1846ovn-nbctl lsp-add lsw0 lp1
1847ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 1848
31ed1192
JP
1849ovn-nbctl lsp-add lsw0 lp2
1850ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 1851
31ed1192
JP
1852ovn-nbctl lsp-add lsw0 lp-vtep
1853ovn-nbctl lsp-set-type lp-vtep vtep
1854ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1855ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 1856
77adbb62
DB
1857# lpr, lr and lrp1 are used for the ARP request handling test only.
1858ovn-nbctl lsp-add lsw0 lpr
1859ovn-nbctl lr-add lr
1860ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1861ovn-nbctl set Logical_Switch_Port lpr type=router \
1862 options:router-port=lrp1 \
1863 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1864
1865
eb6b08eb
JP
1866net_add n1 # Network to connect hv1, hv2, and vtep
1867net_add n2 # Network to connect vtep and hv3
1868
1869# Create hypervisor hv1 connected to n1
1870sim_add hv1
1871as hv1
1872ovs-vsctl add-br br-phys
1873ovn_attach n1 br-phys 192.168.0.1
1874ovs-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
1875
1876# Create hypervisor hv2 connected to n1
1877sim_add hv2
1878as hv2
1879ovs-vsctl add-br br-phys
1880ovn_attach n1 br-phys 192.168.0.2
1881ovs-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
1882
1883
1884# Start the vtep emulator with a leg in both networks
1885sim_add vtep
1886as vtep
1887
1888ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1889ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1890
1891ovs-vsctl add-br br-phys
1892net_attach n1 br-phys
1893
1894mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1895arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1896ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1897ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1898
1899ovs-vsctl add-br br-vtep
1900net_attach n2 br-vtep
1901
1902vtep-ctl add-ps br-vtep
1903vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1904vtep-ctl add-ls lsw0
1905
1906start_daemon ovs-vtep br-vtep
1907start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1908
8cdc4312 1909OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 1910
475f0a2c
DB
1911OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1912 grep -- source`"])
1913# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
1914sleep 1
1915
1916# Add hv3 on the other side of the vtep
1917sim_add hv3
1918as hv3
1919ovs-vsctl add-br br-phys
1920net_attach n2 br-phys
1921
1922ovs-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
1923
1924# Pre-populate the hypervisors' ARP tables so that we don't lose any
1925# packets for ARP resolution (native tunneling doesn't queue packets
1926# for ARP resolution).
1927ovn_populate_arp
1928
1929# Allow some time for ovn-northd and ovn-controller to catch up.
1930# XXX This should be more systematic.
1931sleep 1
6977df72 1932
eb6b08eb
JP
1933# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1934#
1935# This shell function causes a packet to be received on INPORT. The packet's
1936# content has Ethernet destination DST and source SRC (each exactly 12 hex
1937# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1938# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1939# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
1940for i in 1 2 3; do
1941 : > $i.expected
1942done
1943test_packet() {
1944 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1945 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1946 hv=hv$inport
1947 vif=vif$inport
1948 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1949 for outport; do
e4543cfe 1950 echo $packet >> $outport.expected
eb6b08eb
JP
1951 done
1952}
1953
1954# Send packets between all pairs of source and destination ports:
1955#
31ed1192
JP
1956# 1. Unicast packets are delivered to exactly one logical switch port
1957# (except that packets destined to their input ports are dropped).
eb6b08eb 1958#
31ed1192
JP
1959# 2. Broadcast and multicast are delivered to all logical switch ports
1960# except the input port.
eb6b08eb 1961#
ea46a4e9 1962# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1963# switch ports with "unknown" among their MAC addresses (and port
1964# security disabled).
eb6b08eb
JP
1965for s in 1 2 3; do
1966 bcast=
1967 unknown=
1968 for d in 1 2 3; do
1969 if test $d != $s; then unicast=$d; else unicast=; fi
1970 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1971
1972 # The vtep (vif3) is the only one configured for "unknown"
1973 if test $d != $s && test $d = 3; then
1974 unknown="$unknown $d"
1975 fi
1976 bcast="$bcast $unicast"
1977 done
1978
1979 # Broadcast and multicast.
46ed1382
DB
1980 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1981 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
1982
1983 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1984done
1985
77adbb62
DB
1986# ARP request should not be responded to by logical switch router
1987# type arp responder on HV1 and HV2 and should reach directly to
1988# vif1 and vif2
1989ip_to_hex() {
1990 printf "%02x%02x%02x%02x" "$@"
1991}
1992sha=f00000000003
1993spa=`ip_to_hex 192 168 1 2`
1994tpa=`ip_to_hex 192 168 1 1`
1995request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1996as hv3 ovs-appctl netdev-dummy/receive vif3 $request
1997echo $request >> 1.expected
1998echo $request >> 2.expected
1999
bb0c41d3
RM
2000# dump information with counters
2001echo "------ OVN dump ------"
2002ovn-nbctl show
2003ovn-sbctl show
2004
77adbb62
DB
2005echo "---------SB dump-----"
2006ovn-sbctl list datapath_binding
2007echo "---------------------"
2008ovn-sbctl list port_binding
2009echo "---------------------"
2010ovn-sbctl dump-flows
2011
bb0c41d3
RM
2012echo "------ hv1 dump ------"
2013as hv1 ovs-vsctl show
6195e2e7 2014as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2015as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2016
2017echo "------ hv2 dump ------"
2018as hv2 ovs-vsctl show
6195e2e7 2019as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2020as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2021
2022echo "------ hv3 dump ------"
2023as hv3 ovs-vsctl show
6754e92d
FF
2024# note: hv3 has no logical port bind, thus it should not have br-int
2025AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2026[ovs-ofctl: br-int is not a bridge or a socket
2027])
bb0c41d3 2028
eb6b08eb
JP
2029# Now check the packets actually received against the ones expected.
2030for i in 1 2 3; do
49d7c759 2031 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 2032done
fcde56f5
LR
2033
2034# Gracefully terminate daemons
7a8f15e0
LR
2035OVN_CLEANUP([hv1],[hv2],[vtep])
2036OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 2037
eb6b08eb 2038AT_CLEANUP
9975d7be 2039
184bc3ca
RB
2040# Similar test to "hardware GW"
2041AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2042AT_SKIP_IF([test $HAVE_PYTHON = no])
2043ovn_start
2044
2045# Configure the Northbound database
2046ovn-nbctl ls-add lsw0
2047
2048ovn-nbctl lsp-add lsw0 lp1
2049ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2050
2051ovn-nbctl lsp-add lsw0 lp2
2052ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2053
2054ovn-nbctl lsp-add lsw0 lp-gw
2055ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 2056ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
2057ovn-nbctl lsp-set-addresses lp-gw unknown
2058
2059net_add n1 # Network to connect hv1, hv2, and gw
2060net_add n2 # Network to connect gw and hv3
2061
2062# Create hypervisor hv1 connected to n1
2063sim_add hv1
2064as hv1
2065ovs-vsctl add-br br-phys
2066ovn_attach n1 br-phys 192.168.0.1
2067ovs-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
2068
2069# Create hypervisor hv2 connected to n1
2070sim_add hv2
2071as hv2
2072ovs-vsctl add-br br-phys
2073ovn_attach n1 br-phys 192.168.0.2
2074ovs-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
2075
2076# Create hypervisor hv_gw connected to n1 and n2
2077# connect br-phys bridge to n1; connect hv-gw bridge to n2
2078sim_add hv_gw
2079as hv_gw
2080ovs-vsctl add-br br-phys
2081ovn_attach n1 br-phys 192.168.0.3
2082ovs-vsctl add-br br-phys2
2083net_attach n2 br-phys2
2084ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2085
184bc3ca
RB
2086# Add hv3 on the other side of the GW
2087sim_add hv3
2088as hv3
2089ovs-vsctl add-br br-phys
2090net_attach n2 br-phys
2091ovs-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
2092
2093
2094# Pre-populate the hypervisors' ARP tables so that we don't lose any
2095# packets for ARP resolution (native tunneling doesn't queue packets
2096# for ARP resolution).
2097ovn_populate_arp
2098
2099# Allow some time for ovn-northd and ovn-controller to catch up.
2100# XXX This should be more systematic.
2101sleep 1
2102
2103# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2104#
2105# This shell function causes a packet to be received on INPORT. The packet's
2106# content has Ethernet destination DST and source SRC (each exactly 12 hex
2107# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2108# more) list the VIFs on which the packet should be received. INPORT and the
2109# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
2110for i in 1 2 3; do
2111 : > $i.expected
2112done
2113test_packet() {
2114 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2115 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2116 hv=hv$inport
2117 vif=vif$inport
2118 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2119 for outport; do
e4543cfe 2120 echo $packet >> $outport.expected
184bc3ca
RB
2121 done
2122}
2123
2124# Send packets between all pairs of source and destination ports:
2125#
2126# 1. Unicast packets are delivered to exactly one lport (except that packets
2127# destined to their input ports are dropped).
2128#
2129# 2. Broadcast and multicast are delivered to all lports except the input port.
2130#
2131# 3. The lswitch delivers packets with an unknown destination to lports with
2132# "unknown" among their MAC addresses (and port security disabled).
2133for s in 1 2 3 ; do
2134 bcast=
2135 unknown=
2136 for d in 1 2 3 ; do
2137 if test $d != $s; then unicast=$d; else unicast=; fi
2138 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2139
2140 # The vtep (vif3) is the only one configured for "unknown"
2141 if test $d != $s && test $d = 3; then
2142 unknown="$unknown $d"
2143 fi
2144 bcast="$bcast $unicast"
2145 done
2146
2147 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2148 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2149 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2150done
2151
184bc3ca
RB
2152echo "------ ovn-nbctl show ------"
2153ovn-nbctl show
2154echo "------ ovn-sbctl show ------"
2155ovn-sbctl show
2156
2157echo "------ hv1 ------"
2158as hv1 ovs-vsctl show
2159echo "------ hv1 br-int ------"
2160as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2161echo "------ hv1 br-phys ------"
2162as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2163
2164echo "------ hv2 ------"
2165as hv2 ovs-vsctl show
2166echo "------ hv2 br-int ------"
2167as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2168echo "------ hv2 br-phys ------"
2169as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2170
2171echo "------ hv_gw ------"
2172as hv_gw ovs-vsctl show
2173echo "------ hv_gw br-phys ------"
2174as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2175echo "------ hv_gw br-phys2 ------"
2176as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2177
2178echo "------ hv3 ------"
2179as hv3 ovs-vsctl show
2180echo "------ hv3 br-phys ------"
2181as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2182
2183# Now check the packets actually received against the ones expected.
2184for i in 1 2 3; do
49d7c759 2185 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2186done
2187AT_CLEANUP
2188
9975d7be
BP
2189# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2190AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2191AT_SKIP_IF([test $HAVE_PYTHON = no])
2192ovn_start
2193
2194# Logical network:
2195#
2196# Three logical switches ls1, ls2, ls3.
86e98048
BP
2197# One logical router lr0 connected to ls[123],
2198# with nine subnets, three per logical switch:
2199#
2200# lrp11 on ls1 for subnet 192.168.11.0/24
2201# lrp12 on ls1 for subnet 192.168.12.0/24
2202# lrp13 on ls1 for subnet 192.168.13.0/24
2203# ...
2204# lrp33 on ls3 for subnet 192.168.33.0/24
2205#
2206# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2207# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2208for i in 1 2 3; do
ea46a4e9 2209 ovn-nbctl ls-add ls$i
9975d7be 2210 for j in 1 2 3; do
86e98048 2211 for k in 1 2 3; do
31ed1192
JP
2212 # Add "unknown" to MAC addresses for lp?11, so packets for
2213 # MAC-IP bindings discovered via ARP later have somewhere to go.
2214 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2215
2216 ovn-nbctl \
2217 -- lsp-add ls$i lp$i$j$k \
2218 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2219 192.168.$i$j.$k" $unknown
86e98048
BP
2220 done
2221 done
2222done
2223
fa2a27b2 2224ovn-nbctl lr-add lr0
86e98048
BP
2225for i in 1 2 3; do
2226 for j in 1 2 3; do
bf44c2cd 2227 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2228 ovn-nbctl \
31ed1192 2229 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2230 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2231 options:router-port=lrp$i$j \
86e98048 2232 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2233 done
2234done
2235
80f408f4 2236ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2237 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2238
9975d7be
BP
2239# Physical network:
2240#
2241# Three hypervisors hv[123].
86e98048
BP
2242# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2243# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2244# lp?3[123] all on hv3.
2245
9975d7be
BP
2246
2247# Given the name of a logical port, prints the name of the hypervisor
2248# on which it is located.
2249vif_to_hv() {
2250 case $1 in dnl (
86e98048
BP
2251 ?11) echo 1 ;; dnl (
2252 ?12 | ?21 | ?22) echo 2 ;; dnl (
2253 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2254 esac
2255}
2256
86e98048
BP
2257# Given the name of a logical port, prints the name of its logical router
2258# port, e.g. "vif_to_lrp 123" yields 12.
2259vif_to_lrp() {
2260 echo ${1%?}
2261}
2262
2263# Given the name of a logical port, prints the name of its logical
2264# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2265vif_to_ls() {
86e98048 2266 echo ${1%??}
e3393e3f
BP
2267}
2268
9975d7be
BP
2269net_add n1
2270for i in 1 2 3; do
2271 sim_add hv$i
2272 as hv$i
2273 ovs-vsctl add-br br-phys
2274 ovn_attach n1 br-phys 192.168.0.$i
2275done
2276for i in 1 2 3; do
2277 for j in 1 2 3; do
86e98048 2278 for k in 1 2 3; do
269ecccc
JP
2279 hv=`vif_to_hv $i$j$k`
2280 as hv$hv ovs-vsctl \
2281 -- add-port br-int vif$i$j$k \
2282 -- set Interface vif$i$j$k \
2283 external-ids:iface-id=lp$i$j$k \
2284 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2285 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2286 ofport-request=$i$j$k
86e98048 2287 done
9975d7be
BP
2288 done
2289done
2290
2291# Pre-populate the hypervisors' ARP tables so that we don't lose any
2292# packets for ARP resolution (native tunneling doesn't queue packets
2293# for ARP resolution).
2294ovn_populate_arp
2295
2296# Allow some time for ovn-northd and ovn-controller to catch up.
2297# XXX This should be more systematic.
2298sleep 1
2299
e3393e3f 2300# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2301#
2302# This shell function causes a packet to be received on INPORT. The packet's
2303# content has Ethernet destination DST and source SRC (each exactly 12 hex
2304# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2305# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2306# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2307for i in 1 2 3; do
2308 for j in 1 2 3; do
86e98048
BP
2309 for k in 1 2 3; do
2310 : > $i$j$k.expected
269ecccc 2311 done
9975d7be
BP
2312 done
2313done
e3393e3f 2314test_ip() {
9975d7be
BP
2315 # This packet has bad checksums but logical L3 routing doesn't check.
2316 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2317 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2318 shift; shift; shift; shift; shift
2319 hv=hv`vif_to_hv $inport`
2320 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2321 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2322 in_ls=`vif_to_ls $inport`
2323 in_lrp=`vif_to_lrp $inport`
9975d7be 2324 for outport; do
269ecccc 2325 out_ls=`vif_to_ls $outport`
86e98048 2326 if test $in_ls = $out_ls; then
9975d7be
BP
2327 # Ports on the same logical switch receive exactly the same packet.
2328 echo $packet
2329 else
2330 # Routing decrements TTL and updates source and dest MAC
2331 # (and checksum).
269ecccc 2332 out_lrp=`vif_to_lrp $outport`
86e98048 2333 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2334 fi >> $outport.expected
9975d7be
BP
2335 done
2336}
2337
e3393e3f 2338as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2339as hv1 ovn-sbctl list port_binding
2340as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2341as hv1 ovn-sbctl dump-flows
2342as hv1 ovs-ofctl dump-flows br-int
2343
e3393e3f 2344# Send IP packets between all pairs of source and destination ports:
9975d7be 2345#
31ed1192
JP
2346# 1. Unicast IP packets are delivered to exactly one logical switch port
2347# (except that packets destined to their input ports are dropped).
9975d7be 2348#
31ed1192
JP
2349# 2. Broadcast IP packets are delivered to all logical switch ports
2350# except the input port.
86e98048
BP
2351ip_to_hex() {
2352 printf "%02x%02x%02x%02x" "$@"
2353}
9975d7be 2354for is in 1 2 3; do
269ecccc
JP
2355 for js in 1 2 3; do
2356 for ks in 1 2 3; do
2357 bcast=
2358 s=$is$js$ks
2359 smac=f00000000$s
2360 sip=`ip_to_hex 192 168 $is$js $ks`
2361 for id in 1 2 3; do
2362 for jd in 1 2 3; do
2363 for kd in 1 2 3; do
2364 d=$id$jd$kd
2365 dip=`ip_to_hex 192 168 $id$jd $kd`
2366 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2367 if test $d != $s; then unicast=$d; else unicast=; fi
2368
2369 test_ip $s $smac $dmac $sip $dip $unicast #1
2370
2371 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2372 done
2373 done
9975d7be 2374 done
269ecccc
JP
2375 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2376 done
2377 done
e3393e3f
BP
2378done
2379
0bac7164
BP
2380# 3. Send an IP packet from every logical port to every other subnet,
2381# to an IP address that does not have a static IP-MAC binding.
2382# This should generate a broadcast ARP request for the destination
2383# IP address in the destination subnet.
2384for is in 1 2 3; do
269ecccc
JP
2385 for js in 1 2 3; do
2386 for ks in 1 2 3; do
2387 s=$is$js$ks
2388 smac=f00000000$s
2389 sip=`ip_to_hex 192 168 $is$js $ks`
2390 for id in 1 2 3; do
2391 for jd in 1 2 3; do
2392 if test $is$js = $id$jd; then
2393 continue
2394 fi
2395
2396 # Send the packet.
2397 dmac=00000000ff$is$js
2398 # Calculate a 4th octet for the destination that is
2399 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2400 # that have static MAC bindings, and fits in the range
2401 # 0-255.
2402 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2403 dip=`ip_to_hex 192 168 $id$jd $o4`
2404 test_ip $s $smac $dmac $sip $dip
2405
2406 # Every LP on the destination subnet's lswitch should
2407 # receive the ARP request.
2408 lrmac=00000000ff$id$jd
2409 lrip=`ip_to_hex 192 168 $id$jd 254`
2410 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2411 for jd2 in 1 2 3; do
2412 for kd in 1 2 3; do
e4543cfe 2413 echo $arp >> $id$jd2$kd.expected
0bac7164 2414 done
269ecccc 2415 done
0bac7164 2416 done
269ecccc 2417 done
0bac7164 2418 done
269ecccc 2419 done
0bac7164
BP
2420done
2421
e3393e3f
BP
2422# test_arp INPORT SHA SPA TPA [REPLY_HA]
2423#
2424# Causes a packet to be received on INPORT. The packet is an ARP
2425# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2426# it should be the hardware address of the target to expect to receive in an
2427# ARP reply; otherwise no reply is expected.
2428#
31ed1192 2429# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2430# SHA and REPLY_HA are each 12 hex digits.
2431# SPA and TPA are each 8 hex digits.
2432test_arp() {
2433 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2434 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2435 hv=hv`vif_to_hv $inport`
2436 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2d9b49dd 2437 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
e3393e3f 2438
57d143eb 2439 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2440 # IP address is not configured to the switch patch port.
e3393e3f 2441 local i=`vif_to_ls $inport`
86e98048 2442 local j k
e3393e3f 2443 for j in 1 2 3; do
86e98048 2444 for k in 1 2 3; do
ea46a4e9 2445 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2446 # so no ARP flooding expected for it.
2447 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2448 echo $request >> $i$j$k.expected
2449 fi
2450 done
e3393e3f
BP
2451 done
2452
2453 # Expect to receive the reply, if any.
2454 if test X$reply_ha != X; then
86e98048
BP
2455 lrp=`vif_to_lrp $inport`
2456 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2457 echo $reply >> $inport.expected
2458 fi
2459}
2460
2461# Test router replies to ARP requests from all source ports:
2462#
0bac7164 2463# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2464#
0bac7164 2465# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2466# in its subnet.
2467#
0bac7164 2468# 6. Router replies to query for its MAC address from another subnet.
e3393e3f 2469#
0bac7164 2470# 7. No reply to query for IP address other than router IP.
e3393e3f 2471for i in 1 2 3; do
269ecccc
JP
2472 for j in 1 2 3; do
2473 for k in 1 2 3; do
2474 smac=f00000000$i$j$k # Source MAC
2475 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2476 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2477 rmac=00000000ff$i$j # Router MAC
2478 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2479 test_arp $i$j$k $smac $sip $rip $rmac #4
2480 test_arp $i$j$k $smac $otherip $rip $rmac #5
2481 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2482 test_arp $i$j$k $smac $sip $otherip #7
0bac7164 2483 done
269ecccc 2484 done
0bac7164
BP
2485done
2486
2487# Allow some time for packet forwarding.
2488# XXX This can be improved.
2489sleep 1
2490
2491# 8. Generate an ARP reply for each of the IP addresses ARPed for
2492# earlier as #3.
2493#
2494# Here, the $s is the VIF that originated the ARP request and $d is
2495# the VIF that sends the ARP reply, which is somewhat backward but
2496# it means that $s and $d are the same as #3.
2497: > mac_bindings.expected
2498for is in 1 2 3; do
269ecccc
JP
2499 for js in 1 2 3; do
2500 for ks in 1 2 3; do
2501 s=$is$js$ks
2502 for id in 1 2 3; do
2503 for jd in 1 2 3; do
2504 if test $is$js = $id$jd; then
2505 continue
2506 fi
2507
2508 kd=1
2509 d=$id$jd$kd
2510
2511 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2512 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2513 host_mac=8000000000$o4
2514
2515 lrmac=00000000ff$id$jd
2516 lrip=`ip_to_hex 192 168 $id$jd 254`
2517
2518 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2519
2520 echo
2521 echo
2522 echo
2523 hv=hv`vif_to_hv $d`
2524 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2525 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2526 #as $hv ovs-ofctl dump-flows br-int table=19
2527
2528 host_ip_pretty=192.168.$id$jd.$o4
2529 host_mac_pretty=80:00:00:00:00:$o4
2530 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2531 done
269ecccc 2532 done
9975d7be 2533 done
269ecccc 2534 done
9975d7be 2535done
0bac7164 2536
9975d7be
BP
2537# Allow some time for packet forwarding.
2538# XXX This can be improved.
2539sleep 1
2540
0bac7164
BP
2541# 9. Send an IP packet from every logical port to every other subnet. These
2542# are the same packets already sent as #3, but now the destinations' IP-MAC
2543# bindings have been discovered via ARP, so instead of provoking an ARP
2544# request, these packets now get routed to their destinations (which don't
2545# have static MAC bindings, so they go to the port we've designated as
2546# accepting "unknown" MACs.)
2547for is in 1 2 3; do
269ecccc
JP
2548 for js in 1 2 3; do
2549 for ks in 1 2 3; do
2550 s=$is$js$ks
2551 smac=f00000000$s
2552 sip=`ip_to_hex 192 168 $is$js $ks`
2553 for id in 1 2 3; do
2554 for jd in 1 2 3; do
2555 if test $is$js = $id$jd; then
2556 continue
2557 fi
2558
2559 # Send the packet.
2560 dmac=00000000ff$is$js
2561 # Calculate a 4th octet for the destination that is
2562 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2563 # that have static MAC bindings, and fits in the range
2564 # 0-255.
2565 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2566 dip=`ip_to_hex 192 168 $id$jd $o4`
2567 test_ip $s $smac $dmac $sip $dip
2568
2569 # Expect the packet egress.
2570 host_mac=8000000000$o4
2571 outport=${id}11
2572 out_lrp=$id$jd
e4543cfe 2573 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2574 done
269ecccc 2575 done
0bac7164 2576 done
269ecccc 2577 done
0bac7164
BP
2578done
2579
0bac7164
BP
2580ovn-sbctl -f csv -d bare --no-heading \
2581 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2582
9975d7be
BP
2583# Now check the packets actually received against the ones expected.
2584for i in 1 2 3; do
2585 for j in 1 2 3; do
86e98048 2586 for k in 1 2 3; do
abb37b6b
FF
2587 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2588 [$i$j$k.expected])
86e98048 2589 done
9975d7be
BP
2590 done
2591done
fcde56f5 2592
0bac7164
BP
2593# Check the MAC bindings against those expected.
2594AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2595])
2596
fcde56f5 2597# Gracefully terminate daemons
7a8f15e0 2598OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2599
9975d7be 2600AT_CLEANUP
685f4dfe
NS
2601
2602# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2603AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
2604AT_SKIP_IF([test $HAVE_PYTHON = no])
2605ovn_start
2606
2607# Create hypervisors hv[123].
2608# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2609# Add all of the vifs to a single logical switch lsw0.
2610# Turn off port security on vifs vif[123]1
2611# Turn on l2 port security on vifs vif[123]2
2612# Turn of l2 and l3 port security on vifs vif[123]3
2613# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 2614ovn-nbctl ls-add lsw0
685f4dfe
NS
2615net_add n1
2616for i in 1 2 3; do
2617 sim_add hv$i
2618 as hv$i
2619 ovs-vsctl add-br br-phys
2620 ovn_attach n1 br-phys 192.168.0.$i
2621
2622 for j in 1 2 3; do
2623 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 2624 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 2625 if test $j = 1; then
31ed1192 2626 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 2627 elif test $j = 2; then
31ed1192
JP
2628 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2629 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
2630 else
2631 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
2632 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2633 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
2634 fi
2635 done
2636done
2637
685f4dfe
NS
2638# Pre-populate the hypervisors' ARP tables so that we don't lose any
2639# packets for ARP resolution (native tunneling doesn't queue packets
2640# for ARP resolution).
2641ovn_populate_arp
2642
2643# Allow some time for ovn-northd and ovn-controller to catch up.
2644# XXX This should be more systematic.
2645sleep 1
685f4dfe
NS
2646
2647# Given the name of a logical port, prints the name of the hypervisor
2648# on which it is located.
2649vif_to_hv() {
2650 echo hv${1%?}
2651}
2652
685f4dfe
NS
2653for i in 1 2 3; do
2654 for j in 1 2 3; do
2655 : > $i$j.expected
2656 done
2657done
2658
2659# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2660#
2661# This shell function causes an ip packet to be received on INPORT.
2662# The packet's content has Ethernet destination DST and source SRC
2663# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2664# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2665# be received. INPORT and the OUTPORTs are specified as logical switch
2666# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2667test_ip() {
2668 # This packet has bad checksums but logical L3 routing doesn't check.
2669 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 2670 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
2671 shift; shift; shift; shift; shift
2672 hv=`vif_to_hv $inport`
2673 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2674 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2675 for outport; do
e4543cfe 2676 echo $packet >> $outport.expected
685f4dfe
NS
2677 done
2678}
2679
2680# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2681#
2682# Causes a packet to be received on INPORT. The packet is an ARP
2683# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2684# it should be the hardware address of the target to expect to receive in an
2685# ARP reply; otherwise no reply is expected.
2686#
31ed1192 2687# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2688# SHA and REPLY_HA are each 12 hex digits.
2689# SPA and TPA are each 8 hex digits.
2690test_arp() {
2691 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2692 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2693 hv=`vif_to_hv $inport`
2694 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2695 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2696 if test $drop != 1; then
e137131a 2697 if test X$reply_ha = X; then
685f4dfe
NS
2698 # Expect to receive the broadcast ARP on the other logical switch ports
2699 # if no reply is expected.
2700 local i j
2701 for i in 1 2 3; do
2702 for j in 1 2 3; do
2703 if test $i$j != $inport; then
2704 echo $request >> $i$j.expected
2705 fi
2706 done
2707 done
2708 else
2709 # Expect to receive the reply, if any.
2710 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2711 echo $reply >> $inport.expected
2712 fi
2713 fi
2714}
2715
2716# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2717# This function is similar to test_ip() except that it sends
2718# ipv6 packet
2719test_ipv6() {
2720 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2721 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2722 shift; shift; shift; shift; shift
2723 hv=`vif_to_hv $inport`
2724 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2725 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2726 for outport; do
e4543cfe 2727 echo $packet >> $outport.expected
685f4dfe
NS
2728 done
2729}
2730
9e687b23
DL
2731# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2732# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2733# of the test packet
2734test_icmpv6() {
2735 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2736 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2737 shift; shift; shift; shift; shift; shift
2738 hv=`vif_to_hv $inport`
2739 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2740 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2741 for outport; do
e4543cfe 2742 echo $packet >> $outport.expected
9e687b23
DL
2743 done
2744}
2745
685f4dfe
NS
2746ip_to_hex() {
2747 printf "%02x%02x%02x%02x" "$@"
2748}
2749
2750# no port security
2751sip=`ip_to_hex 192 168 0 12`
2752tip=`ip_to_hex 192 168 0 13`
2753# the arp packet should be allowed even if lp[123]1 is
2754# not configured with mac f00000000023 and ip 192.168.0.12
2755for i in 1 2 3; do
2756 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2757 for j in 1 2 3; do
2758 if test $i != $j; then
2759 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2760 fi
2761 done
2762done
2763
2764# l2 port security
2765sip=`ip_to_hex 192 168 0 12`
2766tip=`ip_to_hex 192 168 0 13`
2767
2768# arp packet should be allowed since lp22 is configured with
2769# mac f00000000022
2770test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2771
2772# arp packet should not be allowed since lp32 is not configured with
2773# mac f00000000021
2774test_arp 32 f00000000021 f00000000021 $sip $tip 1
2775
2776# arp packet with sha set to f00000000021 should not be allowed
2777# for lp12
2778test_arp 12 f00000000012 f00000000021 $sip $tip 1
2779
2780# ip packets should be allowed and received since lp[123]2 do not
2781# have l3 port security
2782sip=`ip_to_hex 192 168 0 55`
2783tip=`ip_to_hex 192 168 0 66`
2784for i in 1 2 3; do
2785 for j in 1 2 3; do
2786 if test $i != $j; then
2787 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2788 fi
2789 done
2790done
2791
2792# ipv6 packets should be received by lp[123]2
2793# lp[123]1 can send ipv6 traffic as there is no port security
2794sip=fe800000000000000000000000000000
2795tip=ff020000000000000000000000000000
2796
2797for i in 1 2 3; do
2798 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2799done
2800
2801
2802# l2 and l3 port security
2803sip=`ip_to_hex 192 168 0 13`
2804tip=`ip_to_hex 192 168 0 22`
2805# arp packet should be allowed since lp13 is configured with
2806# f00000000013 and 192.168.0.13
2807test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2808
2809# the arp packet should be dropped because lp23 is not configured
2810# with mac f00000000022
2811sip=`ip_to_hex 192 168 0 13`
2812tip=`ip_to_hex 192 168 0 22`
2813test_arp 23 f00000000022 f00000000022 $sip $tip 1
2814
2815# the arp packet should be dropped because lp33 is not configured
2816# with ip 192.168.0.55
2817spa=`ip_to_hex 192 168 0 55`
2818tpa=`ip_to_hex 192 168 0 22`
2819test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2820
2821# ip packets should not be received by lp[123]3 since
2822# l3 port security is enabled
2823sip=`ip_to_hex 192 168 0 55`
2824tip=`ip_to_hex 192 168 0 66`
2825for i in 1 2 3; do
2826 for j in 1 2 3; do
2827 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2828 done
2829done
2830
2831# ipv6 packets should be dropped for lp[123]3 since
2832# it is configured with only ipv4 address
2833sip=fe800000000000000000000000000000
2834tip=ff020000000000000000000000000000
2835
2836for i in 1 2 3; do
2837 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2838done
2839
2840# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2841# lp[123]1 can send ipv6 traffic as there is no port security
2842for i in 1 2 3; do
2843 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2844done
2845
2846# lp13 has extra port security with mac f0000000113 and ipv6 addr
2847# fe80::ea2a:eaff:fe28:0012
2848
2849# ipv4 packet should be dropped for lp13 with mac f0000000113
2850sip=`ip_to_hex 192 168 0 13`
2851tip=`ip_to_hex 192 168 0 23`
2852test_ip 13 f00000000113 f00000000023 $sip $tip
2853
6d53e8a9
BP
2854# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2855# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
2856# lp11 can send ipv6 traffic as there is no port security
2857sip=ee800000000000000000000000000000
2858for i in 1 2 3; do
6d53e8a9
BP
2859 tip=fe80000000000000ea2aeafffe2800${i}3
2860 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
2861done
2862
2863
2864# ipv6 packet should not be received by lp33 with mac f0000000333
2865# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2866# configured with fe80::ea2a:eaff:fe28:0033
2867# lp11 can send ipv6 traffic as there is no port security
2868
2869sip=ee800000000000000000000000000000
2870tip=fe80000000000000ea2aeafffe280023
2871test_ipv6 11 f00000000011 f00000000333 $sip $tip
2872
6d53e8a9
BP
2873# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2874# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
2875# and should be dropped for any other ip6.src
2876# lp21 can receive ipv6 traffic as there is no port security
2877
2878tip=ee800000000000000000000000000000
2879for i in 1 2 3; do
2880 sip=fe80000000000000ea2aeafffe2800${i}3
2881 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2882
9e687b23 2883 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 2884 sip=00000000000000000000000000000000
9e687b23
DL
2885 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2886 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2887 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2888 # Traffic to non-multicast traffic should be dropped
2889 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2890 # Traffic of other ICMPv6 types should be dropped
2891 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
2892
2893 # should be dropped
2894 sip=ae80000000000000ea2aeafffe2800aa
2895 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2896done
2897
31ed1192
JP
2898# configure lsp13 to send and received IPv4 packets with an address range
2899ovn-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 2900
8ff5a966
NS
2901sleep 2
2902
7d9d86ad
NS
2903sip=`ip_to_hex 10 0 0 13`
2904tip=`ip_to_hex 192 168 0 22`
31ed1192 2905# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
2906test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2907
2908sip=`ip_to_hex 10 0 0 14`
2909tip=`ip_to_hex 192 168 0 23`
31ed1192 2910# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
2911# with dst ip 192.168.0.23 should be allowed
2912test_ip 13 f00000000013 f00000000023 $sip $tip 23
2913
2914sip=`ip_to_hex 192 168 0 33`
2915tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
2916# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2917# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
2918test_ip 33 f00000000033 f00000000013 $sip $tip 13
2919
2920sip=`ip_to_hex 192 168 0 33`
2921tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
2922# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2923# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
2924test_ip 33 f00000000033 f00000000013 $sip $tip 13
2925
2926sip=`ip_to_hex 192 168 0 33`
2927tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
2928# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2929# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
2930test_ip 33 f00000000033 f00000000013 $sip $tip
2931
2932sip=`ip_to_hex 192 168 0 33`
2933tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
2934# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2935# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
2936test_ip 33 f00000000033 f00000000013 $sip $tip 13
2937
2938sip=`ip_to_hex 192 168 0 33`
2939tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
2940# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2941# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
2942test_ip 33 f00000000033 f00000000013 $sip $tip
2943
2944sip=`ip_to_hex 192 168 0 33`
2945tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
2946# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2947# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 2948test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 2949
bb0c41d3
RM
2950#dump information including flow counters
2951ovn-nbctl show
2952ovn-sbctl dump-flows -- list multicast_group
2953
2954echo "------ hv1 dump ------"
2955as hv1 ovs-vsctl show
6195e2e7 2956as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2957as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2958
2959echo "------ hv2 dump ------"
2960as hv2 ovs-vsctl show
6195e2e7 2961as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2962as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2963
2964echo "------ hv3 dump ------"
2965as hv3 ovs-vsctl show
6195e2e7 2966as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2967as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2968
685f4dfe
NS
2969# Now check the packets actually received against the ones expected.
2970for i in 1 2 3; do
2971 for j in 1 2 3; do
49d7c759 2972 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
2973 done
2974done
2975
7a8f15e0 2976OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 2977
685f4dfe 2978AT_CLEANUP
509afdc3
GS
2979
2980AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
2981AT_SKIP_IF([test $HAVE_PYTHON = no])
2982ovn_start
2983
2984# Logical network:
2985# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2986# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2987# R2 has ls2 (172.16.1.0/24) connected to it.
2988
3c1ae70a
JP
2989ls1_lp1_mac="f0:00:00:01:02:03"
2990rp_ls1_mac="00:00:00:01:02:03"
2991rp_ls2_mac="00:00:00:01:02:04"
2992ls2_lp1_mac="f0:00:00:01:02:04"
2993
2994ls1_lp1_ip="192.168.1.2"
2995ls2_lp1_ip="172.16.1.2"
2996
fa2a27b2
JP
2997ovn-nbctl lr-add R1
2998ovn-nbctl lr-add R2
509afdc3 2999
ea46a4e9
JP
3000ovn-nbctl ls-add ls1
3001ovn-nbctl ls-add ls2
509afdc3
GS
3002
3003# Connect ls1 to R1
3c1ae70a 3004ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
509afdc3 3005
31ed1192 3006ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3c1ae70a 3007 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
509afdc3
GS
3008
3009# Connect ls2 to R2
3c1ae70a 3010ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
509afdc3 3011
31ed1192 3012ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3c1ae70a 3013 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
509afdc3
GS
3014
3015# Connect R1 to R2
4685e523
JP
3016ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3017ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 3018
6d9ecfa9
JP
3019ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3020ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
3021
3022# Create logical port ls1-lp1 in ls1
31ed1192 3023ovn-nbctl lsp-add ls1 ls1-lp1 \
3c1ae70a 3024-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
509afdc3
GS
3025
3026# Create logical port ls2-lp1 in ls2
31ed1192 3027ovn-nbctl lsp-add ls2 ls2-lp1 \
3c1ae70a 3028-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
509afdc3
GS
3029
3030# Create two hypervisor and create OVS ports corresponding to logical ports.
3031net_add n1
3032
3033sim_add hv1
3034as hv1
3035ovs-vsctl add-br br-phys
3036ovn_attach n1 br-phys 192.168.0.1
3037ovs-vsctl -- add-port br-int hv1-vif1 -- \
3038 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3039 options:tx_pcap=hv1/vif1-tx.pcap \
3040 options:rxq_pcap=hv1/vif1-rx.pcap \
3041 ofport-request=1
3042
3043sim_add hv2
3044as hv2
3045ovs-vsctl add-br br-phys
3046ovn_attach n1 br-phys 192.168.0.2
3047ovs-vsctl -- add-port br-int hv2-vif1 -- \
3048 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3049 options:tx_pcap=hv2/vif1-tx.pcap \
3050 options:rxq_pcap=hv2/vif1-rx.pcap \
3051 ofport-request=1
3052
3053
3054# Pre-populate the hypervisors' ARP tables so that we don't lose any
3055# packets for ARP resolution (native tunneling doesn't queue packets
3056# for ARP resolution).
3057ovn_populate_arp
3058
3059# Allow some time for ovn-northd and ovn-controller to catch up.
3060# XXX This should be more systematic.
3061sleep 1
3062
509afdc3 3063# Packet to send.
3c1ae70a
JP
3064packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3065 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3066 udp && udp.src==53 && udp.dst==4369"
3067as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
509afdc3
GS
3068
3069
3070echo "---------NB dump-----"
3071ovn-nbctl show
3072echo "---------------------"
3073ovn-nbctl list logical_router
3074echo "---------------------"
3075ovn-nbctl list logical_router_port
3076echo "---------------------"
3077
3078echo "---------SB dump-----"
3079ovn-sbctl list datapath_binding
3080echo "---------------------"
3081ovn-sbctl list port_binding
3082echo "---------------------"
3083
3084echo "------ hv1 dump ----------"
8dab1022 3085as hv1 ovs-ofctl show br-int
509afdc3
GS
3086as hv1 ovs-ofctl dump-flows br-int
3087echo "------ hv2 dump ----------"
8dab1022 3088as hv2 ovs-ofctl show br-int
509afdc3
GS
3089as hv2 ovs-ofctl dump-flows br-int
3090
3091# Packet to Expect
3c1ae70a
JP
3092# The TTL should be decremented by 2.
3093packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3094 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3095 udp && udp.src==53 && udp.dst==4369"
3096echo $packet | ovstest test-ovn expr-to-packets > expected
509afdc3 3097
49d7c759 3098OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 3099
7ebfcd3d
NS
3100AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3101grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3102])
3103
3104# Disable the ls2-lp1 port.
3105ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3106
3107AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3108grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3109])
3110
3111# Generate the packet destined for ls2-lp1 and it should not be delivered.
3112# Packet to send.
3113packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3114 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3115 udp && udp.src==53 && udp.dst==4369"
3116
3117as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3118# The 2nd packet sent shound not be received.
3119OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3120
7a8f15e0 3121OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
3122
3123AT_CLEANUP
5412db30
J
3124
3125
4685e523
JP
3126AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3127AT_KEYWORDS([router-admin-state])
3128AT_SKIP_IF([test $HAVE_PYTHON = no])
3129ovn_start
3130
3131# Logical network:
3132# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3133# and 172.16.1.0/24) connected to it.
3134
3135ovn-nbctl lr-add R1
3136
3137ovn-nbctl ls-add ls1
3138
3139# Connect ls1 to R1
bf44c2cd 3140ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
3141ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3142 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3143
3144# Create logical port ls1-lp1 in ls1
3145ovn-nbctl lsp-add ls1 ls1-lp1 \
3146 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3147
3148# Create logical port ls1-lp2 in ls1
3149ovn-nbctl lsp-add ls1 ls1-lp2 \
3150 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3151
3152# Create one hypervisor and create OVS ports corresponding to logical ports.
3153net_add n1
3154
3155sim_add hv1
3156as hv1
3157ovs-vsctl add-br br-phys
3158ovn_attach n1 br-phys 192.168.0.1
3159ovs-vsctl -- add-port br-int vif1 -- \
3160 set interface vif1 external-ids:iface-id=ls1-lp1 \
3161 options:tx_pcap=hv1/vif1-tx.pcap \
3162 options:rxq_pcap=hv1/vif1-rx.pcap \
3163 ofport-request=1
3164
3165ovs-vsctl -- add-port br-int vif2 -- \
3166 set interface vif2 external-ids:iface-id=ls1-lp2 \
3167 options:tx_pcap=hv1/vif2-tx.pcap \
3168 options:rxq_pcap=hv1/vif2-rx.pcap \
3169 ofport-request=1
3170
3171
3172# Allow some time for ovn-northd and ovn-controller to catch up.
3173# XXX This should be more systematic.
3174sleep 1
3175
3176# Send ip packets between the two ports.
3177ip_to_hex() {
3178 printf "%02x%02x%02x%02x" "$@"
3179}
4685e523
JP
3180
3181# Packet to send.
3182src_mac="f00000010203"
3183dst_mac="000000010203"
3184src_ip=`ip_to_hex 192 168 1 2`
3185dst_ip=`ip_to_hex 172 16 1 2`
3186packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3187as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3188
3189
3190echo "---------NB dump-----"
3191ovn-nbctl show
3192echo "---------------------"
3193ovn-nbctl list logical_router
3194echo "---------------------"
3195ovn-nbctl list logical_router_port
3196echo "---------------------"
3197
3198echo "---------SB dump-----"
3199ovn-sbctl list datapath_binding
3200echo "---------------------"
3201ovn-sbctl list logical_flow
3202echo "---------------------"
3203
3204echo "------ hv1 dump ----------"
3205as hv1 ovs-ofctl dump-flows br-int
3206
3207
3208#Disable router R1
3209ovn-nbctl set Logical_Router R1 enabled=false
3210
3b8cd0ea
BP
3211# Allow some time for ovn-northd and ovn-controller to catch up.
3212# XXX This should be more systematic.
3213sleep 1
3214
4685e523
JP
3215echo "---------SB dump-----"
3216ovn-sbctl list datapath_binding
3217echo "---------------------"
3218ovn-sbctl list logical_flow
3219echo "---------------------"
3220
3221echo "------ hv1 dump ----------"
3222as hv1 ovs-ofctl dump-flows br-int
3223
3224as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3225
3226# Packet to Expect
3227expect_src_mac="000000010203"
3228expect_dst_mac="f00000010204"
49d7c759 3229echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3230
49d7c759 3231OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
3232
3233
3234as hv1
3235OVS_APP_EXIT_AND_WAIT([ovn-controller])
3236OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3237OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3238
3239as ovn-sb
3240OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3241
3242as ovn-nb
3243OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3244
3245as northd
3246OVS_APP_EXIT_AND_WAIT([ovn-northd])
3247
3248as main
3249OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3250OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3251
3252AT_CLEANUP
3253
3254
3255AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3256AT_KEYWORDS([router-admin-state])
3257AT_SKIP_IF([test $HAVE_PYTHON = no])
3258ovn_start
3259
3260# Logical network:
3261# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3262# and has switch ls2 (172.16.1.0/24) connected to it.
3263
fa2a27b2 3264ovn-nbctl lr-add R1
5412db30 3265
ea46a4e9
JP
3266ovn-nbctl ls-add ls1
3267ovn-nbctl ls-add ls2
5412db30
J
3268
3269# Connect ls1 to R1
bf44c2cd 3270ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3271ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3272 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3273
3274# Connect ls2 to R1
bf44c2cd 3275ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3276ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3277 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3278
3279# Create logical port ls1-lp1 in ls1
31ed1192
JP
3280ovn-nbctl lsp-add ls1 ls1-lp1 \
3281-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3282
3283# Create logical port ls2-lp1 in ls2
31ed1192
JP
3284ovn-nbctl lsp-add ls2 ls2-lp1 \
3285-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3286
3287# Create one hypervisor and create OVS ports corresponding to logical ports.
3288net_add n1
3289
3290sim_add hv1
3291as hv1
3292ovs-vsctl add-br br-phys
3293ovn_attach n1 br-phys 192.168.0.1
3294ovs-vsctl -- add-port br-int vif1 -- \
3295 set interface vif1 external-ids:iface-id=ls1-lp1 \
3296 options:tx_pcap=hv1/vif1-tx.pcap \
3297 options:rxq_pcap=hv1/vif1-rx.pcap \
3298 ofport-request=1
3299
3300ovs-vsctl -- add-port br-int vif2 -- \
3301 set interface vif2 external-ids:iface-id=ls2-lp1 \
3302 options:tx_pcap=hv1/vif2-tx.pcap \
3303 options:rxq_pcap=hv1/vif2-rx.pcap \
3304 ofport-request=1
3305
3306
3307# Allow some time for ovn-northd and ovn-controller to catch up.
3308# XXX This should be more systematic.
3309sleep 1
3310
3311# Send ip packets between the two ports.
3312ip_to_hex() {
3313 printf "%02x%02x%02x%02x" "$@"
3314}
5412db30
J
3315
3316# Packet to send.
3317src_mac="f00000010203"
3318dst_mac="000000010203"
3319src_ip=`ip_to_hex 192 168 1 2`
3320dst_ip=`ip_to_hex 172 16 1 2`
3321packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3322as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3323
3324
3325echo "---------NB dump-----"
3326ovn-nbctl show
3327echo "---------------------"
3328ovn-nbctl list logical_router
3329echo "---------------------"
3330ovn-nbctl list logical_router_port
3331echo "---------------------"
3332
3333echo "---------SB dump-----"
3334ovn-sbctl list datapath_binding
3335echo "---------------------"
3336ovn-sbctl list logical_flow
3337echo "---------------------"
3338
3339echo "------ hv1 dump ----------"
3340as hv1 ovs-ofctl dump-flows br-int
3341
5412db30
J
3342#Disable router R1
3343ovn-nbctl set Logical_Router R1 enabled=false
3344
3345echo "---------SB dump-----"
3346ovn-sbctl list datapath_binding
3347echo "---------------------"
3348ovn-sbctl list logical_flow
3349echo "---------------------"
3350
3351echo "------ hv1 dump ----------"
3352as hv1 ovs-ofctl dump-flows br-int
3353
a1361a6e
LR
3354# Allow some time for the disabling of logical router R1 to propagate.
3355# XXX This should be more systematic.
3356sleep 1
3357
5412db30
J
3358as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3359
3360# Packet to Expect
3361expect_src_mac="000000010204"
3362expect_dst_mac="f00000010204"
49d7c759 3363echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3364
49d7c759 3365OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3366
7a8f15e0 3367OVN_CLEANUP([hv1])
5412db30
J
3368
3369AT_CLEANUP
3370
28dc3fe9 3371AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3372AT_SKIP_IF([test $HAVE_PYTHON = no])
3373ovn_start
3374
3375# Logical network:
3376# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3377# network. R1 has switchess foo (192.168.1.0/24)
3378# connected to it.
3379# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3380
fa2a27b2
JP
3381ovn-nbctl lr-add R1
3382ovn-nbctl lr-add R2
28dc3fe9 3383
ea46a4e9
JP
3384ovn-nbctl ls-add foo
3385ovn-nbctl ls-add alice
3386ovn-nbctl ls-add bob
28dc3fe9
SR
3387
3388# Connect foo to R1
bf44c2cd 3389ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3390ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3391 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3392
3393# Connect alice to R2
bf44c2cd 3394ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3395ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3396 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3397
3398# Connect bob to R2
bf44c2cd 3399ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3400ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3401 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3402
3403# Connect R1 to R2
4685e523
JP
3404ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3405ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3406
3407#install static routes
e48ccf3c
JP
3408ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3409ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3410ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3411
3412# Create logical port foo1 in foo
31ed1192
JP
3413ovn-nbctl lsp-add foo foo1 \
3414-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3415
3416# Create logical port alice1 in alice
31ed1192
JP
3417ovn-nbctl lsp-add alice alice1 \
3418-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3419
3420# Create logical port bob1 in bob
31ed1192
JP
3421ovn-nbctl lsp-add bob bob1 \
3422-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3423
3424# Create two hypervisor and create OVS ports corresponding to logical ports.
3425net_add n1
3426
3427sim_add hv1
3428as hv1
3429ovs-vsctl add-br br-phys
3430ovn_attach n1 br-phys 192.168.0.1
3431ovs-vsctl -- add-port br-int hv1-vif1 -- \
3432 set interface hv1-vif1 external-ids:iface-id=foo1 \
3433 options:tx_pcap=hv1/vif1-tx.pcap \
3434 options:rxq_pcap=hv1/vif1-rx.pcap \
3435 ofport-request=1
3436
3437ovs-vsctl -- add-port br-int hv1-vif2 -- \
3438 set interface hv1-vif2 external-ids:iface-id=alice1 \
3439 options:tx_pcap=hv1/vif2-tx.pcap \
3440 options:rxq_pcap=hv1/vif2-rx.pcap \
3441 ofport-request=2
3442
3443sim_add hv2
3444as hv2
3445ovs-vsctl add-br br-phys
3446ovn_attach n1 br-phys 192.168.0.2
3447ovs-vsctl -- add-port br-int hv2-vif1 -- \
3448 set interface hv2-vif1 external-ids:iface-id=bob1 \
3449 options:tx_pcap=hv2/vif1-tx.pcap \
3450 options:rxq_pcap=hv2/vif1-rx.pcap \
3451 ofport-request=1
3452
3453
3454# Pre-populate the hypervisors' ARP tables so that we don't lose any
3455# packets for ARP resolution (native tunneling doesn't queue packets
3456# for ARP resolution).
3457ovn_populate_arp
3458
3459# Allow some time for ovn-northd and ovn-controller to catch up.
3460# XXX This should be more systematic.
3461sleep 1
3462
3463ip_to_hex() {
3464 printf "%02x%02x%02x%02x" "$@"
3465}
28dc3fe9
SR
3466
3467# Send ip packets between foo1 and alice1
3468src_mac="f00000010203"
3469dst_mac="000000010203"
3470src_ip=`ip_to_hex 192 168 1 2`
3471dst_ip=`ip_to_hex 172 16 1 2`
3472packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3473as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3474
3475# Send ip packets between foo1 and bob1
3476src_mac="f00000010203"
3477dst_mac="000000010203"
3478src_ip=`ip_to_hex 192 168 1 2`
3479dst_ip=`ip_to_hex 172 16 2 2`
3480packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3481as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3482
3483echo "---------NB dump-----"
3484ovn-nbctl show
3485echo "---------------------"
3486ovn-nbctl list logical_router
3487echo "---------------------"
3488ovn-nbctl list logical_router_port
3489echo "---------------------"
3490
3491echo "---------SB dump-----"
3492ovn-sbctl list datapath_binding
3493echo "---------------------"
3494ovn-sbctl list port_binding
3495echo "---------------------"
3496
3497echo "------ hv1 dump ----------"
3498as hv1 ovs-ofctl dump-flows br-int
3499echo "------ hv2 dump ----------"
3500as hv2 ovs-ofctl dump-flows br-int
3501
3502# Packet to Expect at bob1
3503src_mac="000000010205"
3504dst_mac="f00000010205"
3505src_ip=`ip_to_hex 192 168 1 2`
3506dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3507echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3508
49d7c759 3509OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3510
3511# Packet to Expect at alice1
3512src_mac="000000010204"
3513dst_mac="f00000010204"
3514src_ip=`ip_to_hex 192 168 1 2`
3515dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3516echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3517
49d7c759 3518OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3519
7a8f15e0 3520OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3521
3522AT_CLEANUP
5412db30 3523
0ee8aaf6 3524AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3525AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3526ovn_start
ea46a4e9 3527ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3528net_add n1
3529sim_add hv
3530as hv
3531ovs-vsctl \
3532 -- add-br br-phys \
3533 -- add-br br-eth0
3534
3535ovn_attach n1 br-phys 192.168.0.1
3536
3537AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3538AT_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])
3539
3540# Create a vif.
31ed1192
JP
3541AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3542AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3543AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3544
3545# Create a localnet port.
31ed1192
JP
3546AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3547AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3548AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3549AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3550
3551AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3552
3553# Wait for packet to be received.
49d7c759
BP
3554echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3555OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6
RR
3556
3557# Delete the localnet ports.
3558AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3559AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3560
7a8f15e0 3561OVN_CLEANUP([hv])
0ee8aaf6
RR
3562
3563AT_CLEANUP
75cf9d2b
GS
3564
3565AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
3566AT_SKIP_IF([test $HAVE_PYTHON = no])
3567ovn_start
3568
3569# Logical network:
3570# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3571# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3572# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3573# connected to it.
3574
fa2a27b2
JP
3575ovn-nbctl lr-add R1
3576ovn-nbctl lr-add R2
3577ovn-nbctl lr-add R3
75cf9d2b 3578
ea46a4e9
JP
3579ovn-nbctl ls-add foo
3580ovn-nbctl ls-add alice
3581ovn-nbctl ls-add bob
3582ovn-nbctl ls-add join
75cf9d2b
GS
3583
3584# Connect foo to R1
31114af7 3585ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3586ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3587 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
3588
3589# Connect alice to R2
31114af7 3590ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3591ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3592 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
3593
3594# Connect bob to R3
31114af7 3595ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 3596ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 3597 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
3598
3599# Connect R1 to join
31114af7 3600ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3601ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3602 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
3603
3604# Connect R2 to join
31114af7 3605ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3606ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3607 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
3608
3609# Connect R3 to join
31114af7 3610ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 3611ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 3612 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
3613
3614#install static routes
e48ccf3c
JP
3615ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3616ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 3617
e48ccf3c
JP
3618ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3619ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 3620
e48ccf3c
JP
3621ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3622ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
3623
3624# Create logical port foo1 in foo
31ed1192
JP
3625ovn-nbctl lsp-add foo foo1 \
3626-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
3627
3628# Create logical port alice1 in alice
31ed1192
JP
3629ovn-nbctl lsp-add alice alice1 \
3630-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
3631
3632# Create logical port bob1 in bob
31ed1192
JP
3633ovn-nbctl lsp-add bob bob1 \
3634-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
3635
3636# Create two hypervisor and create OVS ports corresponding to logical ports.
3637net_add n1
3638
3639sim_add hv1
3640as hv1
3641ovs-vsctl add-br br-phys
3642ovn_attach n1 br-phys 192.168.0.1
3643ovs-vsctl -- add-port br-int hv1-vif1 -- \
3644 set interface hv1-vif1 external-ids:iface-id=foo1 \
3645 options:tx_pcap=hv1/vif1-tx.pcap \
3646 options:rxq_pcap=hv1/vif1-rx.pcap \
3647 ofport-request=1
3648
3649ovs-vsctl -- add-port br-int hv1-vif2 -- \
3650 set interface hv1-vif2 external-ids:iface-id=alice1 \
3651 options:tx_pcap=hv1/vif2-tx.pcap \
3652 options:rxq_pcap=hv1/vif2-rx.pcap \
3653 ofport-request=2
3654
3655sim_add hv2
3656as hv2
3657ovs-vsctl add-br br-phys
3658ovn_attach n1 br-phys 192.168.0.2
3659ovs-vsctl -- add-port br-int hv2-vif1 -- \
3660 set interface hv2-vif1 external-ids:iface-id=bob1 \
3661 options:tx_pcap=hv2/vif1-tx.pcap \
3662 options:rxq_pcap=hv2/vif1-rx.pcap \
3663 ofport-request=1
3664
3665
3666# Pre-populate the hypervisors' ARP tables so that we don't lose any
3667# packets for ARP resolution (native tunneling doesn't queue packets
3668# for ARP resolution).
3669ovn_populate_arp
3670
3671# Allow some time for ovn-northd and ovn-controller to catch up.
3672# XXX This should be more systematic.
3673sleep 1
3674
3675ip_to_hex() {
3676 printf "%02x%02x%02x%02x" "$@"
3677}
75cf9d2b
GS
3678
3679# Send ip packets between foo1 and alice1
3680src_mac="f00000010203"
3681dst_mac="000001010203"
3682src_ip=`ip_to_hex 192 168 1 2`
3683dst_ip=`ip_to_hex 172 16 1 2`
3684packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3685as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3686as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3687
3688# Send ip packets between foo1 and bob1
3689src_mac="f00000010203"
3690dst_mac="000001010203"
3691src_ip=`ip_to_hex 192 168 1 2`
3692dst_ip=`ip_to_hex 10 32 1 2`
3693packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3694as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3695
3696echo "---------NB dump-----"
3697ovn-nbctl show
3698echo "---------------------"
3699ovn-nbctl list logical_router
3700echo "---------------------"
3701ovn-nbctl list logical_router_port
3702echo "---------------------"
3703
3704echo "---------SB dump-----"
3705ovn-sbctl list datapath_binding
3706echo "---------------------"
3707ovn-sbctl list port_binding
3708echo "---------------------"
3709ovn-sbctl dump-flows
3710echo "---------------------"
3711
3712echo "------ hv1 dump ----------"
3713as hv1 ovs-ofctl show br-int
3714as hv1 ovs-ofctl dump-flows br-int
3715echo "------ hv2 dump ----------"
3716as hv2 ovs-ofctl show br-int
3717as hv2 ovs-ofctl dump-flows br-int
3718echo "----------------------------"
3719
3720# Packet to Expect at bob1
3721src_mac="000003010203"
3722dst_mac="f00000010205"
3723src_ip=`ip_to_hex 192 168 1 2`
3724dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 3725echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3726
49d7c759 3727OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
3728
3729# Packet to Expect at alice1
3730src_mac="000002010203"
3731dst_mac="f00000010204"
3732src_ip=`ip_to_hex 192 168 1 2`
3733dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3734echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3735
49d7c759 3736OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 3737
7a8f15e0 3738OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
3739
3740AT_CLEANUP
c1645003 3741
281977f7 3742AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
3743AT_SKIP_IF([test $HAVE_PYTHON = no])
3744ovn_start
3745
3746ovn-nbctl ls-add ls1
3747
3748ovn-nbctl lsp-add ls1 ls1-lp1 \
3749-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3750
3751ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3752
3753ovn-nbctl lsp-add ls1 ls1-lp2 \
3754-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3755
3756ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3757
3758ovn-nbctl ls-add ls2
3759ovn-nbctl lsp-add ls2 ls2-lp1 \
3760-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3761ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3762ovn-nbctl lsp-add ls2 ls2-lp2 \
3763-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3764ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3765
9060fc9a 3766d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
281977f7 3767options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
9060fc9a 3768\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
281977f7 3769
9060fc9a
MM
3770ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3771ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3772
3773d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
281977f7 3774options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
9060fc9a
MM
3775\"lease_time\"=\"3600\"")"
3776
3777ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
281977f7
NS
3778
3779net_add n1
3780sim_add hv1
3781
3782as hv1
3783ovs-vsctl add-br br-phys
3784ovn_attach n1 br-phys 192.168.0.1
3785ovs-vsctl -- add-port br-int hv1-vif1 -- \
3786 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3787 options:tx_pcap=hv1/vif1-tx.pcap \
3788 options:rxq_pcap=hv1/vif1-rx.pcap \
3789 ofport-request=1
3790
3791ovs-vsctl -- add-port br-int hv1-vif2 -- \
3792 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3793 options:tx_pcap=hv1/vif2-tx.pcap \
3794 options:rxq_pcap=hv1/vif2-rx.pcap \
3795 ofport-request=2
3796
3797ovs-vsctl -- add-port br-int hv1-vif3 -- \
3798 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3799 options:tx_pcap=hv1/vif3-tx.pcap \
3800 options:rxq_pcap=hv1/vif3-rx.pcap \
3801 ofport-request=3
3802
3803ovs-vsctl -- add-port br-int hv1-vif4 -- \
3804 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3805 options:tx_pcap=hv1/vif4-tx.pcap \
3806 options:rxq_pcap=hv1/vif4-rx.pcap \
3807 ofport-request=4
3808
3809ovn_populate_arp
3810
3811sleep 2
3812
3813as hv1 ovs-vsctl show
3814
281977f7
NS
3815# This shell function sends a DHCP request packet
3816# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3817test_dhcp() {
213615b3
NS
3818 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3819 shift; shift; shift; shift; shift;
3820 if test $use_ip != 0; then
3821 src_ip=$1
3822 dst_ip=$2
3823 shift; shift;
3824 else
3825 src_ip=`ip_to_hex 0 0 0 0`
3826 dst_ip=`ip_to_hex 255 255 255 255`
3827 fi
3828 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
281977f7 3829 # udp header and dhcp header
ab187e7e
BP
3830 request=${request}0044004300fc0000
3831 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 3832 # client hardware padding
ab187e7e 3833 request=${request}00000000000000000000
281977f7 3834 # server hostname
ab187e7e
BP
3835 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3836 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3837 # boot file name
ab187e7e
BP
3838 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3839 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3840 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3841 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3842 # dhcp magic cookie
ab187e7e 3843 request=${request}63825363
281977f7 3844 # dhcp message type
ab187e7e 3845 request=${request}3501${dhcp_type}ff
281977f7
NS
3846
3847 if test $offer_ip != 0; then
213615b3 3848 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
281977f7
NS
3849 # total IP length will be the IP length of the request packet
3850 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3851 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3852 udp_len=`expr $ip_len - 20`
04d60f6e
YT
3853 ip_len=$(printf "%x" $ip_len)
3854 udp_len=$(printf "%x" $udp_len)
281977f7
NS
3855 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3856 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3857 # udp header and dhcp header.
3858 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 3859 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 3860 # your ip address
ab187e7e 3861 reply=${reply}${offer_ip}
281977f7 3862 # next server ip address, relay agent ip address, client mac address
ab187e7e 3863 reply=${reply}0000000000000000${src_mac}
281977f7 3864 # client hardware padding
ab187e7e 3865 reply=${reply}00000000000000000000
281977f7 3866 # server hostname
ab187e7e
BP
3867 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3868 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3869 # boot file name
ab187e7e
BP
3870 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3871 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3872 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3873 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3874 # dhcp magic cookie
ab187e7e 3875 reply=${reply}63825363
281977f7
NS
3876 # dhcp message type
3877 local dhcp_reply_type=02
3878 if test $dhcp_type = 03; then
3879 dhcp_reply_type=05
3880 fi
ab187e7e 3881 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
3882 echo $reply >> $inport.expected
3883 else
281977f7 3884 for outport; do
e4543cfe 3885 echo $request >> $outport.expected
281977f7
NS
3886 done
3887 fi
3888 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3889}
3890
3891reset_pcap_file() {
3892 local iface=$1
3893 local pcap_file=$2
3894 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3895options:rxq_pcap=dummy-rx.pcap
3896 rm -f ${pcap_file}*.pcap
3897 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3898options:rxq_pcap=${pcap_file}-rx.pcap
3899}
3900
3901ip_to_hex() {
3902 printf "%02x%02x%02x%02x" "$@"
3903}
3904
3905AT_CAPTURE_FILE([ofctl_monitor0.log])
3906as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3907--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3908
3909echo "---------NB dump-----"
3910ovn-nbctl show
3911echo "---------------------"
3912echo "---------SB dump-----"
3913ovn-sbctl list datapath_binding
3914echo "---------------------"
3915ovn-sbctl list logical_flow
3916echo "---------------------"
3917
3918echo "---------------------"
3919ovn-sbctl dump-flows
3920echo "---------------------"
3921
3922echo "------ hv1 dump ----------"
3923as hv1 ovs-ofctl dump-flows br-int
3924
3925# Send DHCPDISCOVER.
3926offer_ip=`ip_to_hex 10 0 0 4`
3927server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 3928expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 3929test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
3930
3931# NXT_RESUMEs should be 1.
3932OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3933
3934$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3935cat 1.expected | cut -c -48 > expout
3936AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3937# Skipping the IPv4 checksum.
3938cat 1.expected | cut -c 53- > expout
3939AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3940
3941# ovs-ofctl also resumes the packets and this causes other ports to receive
3942# the DHCP request packet. So reset the pcap files so that its easier to test.
3943reset_pcap_file hv1-vif1 hv1/vif1
3944reset_pcap_file hv1-vif2 hv1/vif2
3945rm -f 1.expected
3946rm -f 2.expected
3947
3948# Send DHCPREQUEST.
3949offer_ip=`ip_to_hex 10 0 0 6`
3950server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 3951expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 3952test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
3953
3954# NXT_RESUMEs should be 2.
3955OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3956
3957$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3958cat 2.expected | cut -c -48 > expout
3959AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3960# Skipping the IPv4 checksum.
3961cat 2.expected | cut -c 53- > expout
3962AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3963
3964reset_pcap_file hv1-vif1 hv1/vif1
3965reset_pcap_file hv1-vif2 hv1/vif2
3966rm -f 1.expected
3967rm -f 2.expected
3968
3969# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3970# but should be resumed without the reply.
3971# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3972# one from ovn-controller and the other from "ovs-ofctl resume."
3973offer_ip=0
213615b3 3974test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
281977f7
NS
3975
3976# NXT_RESUMEs should be 3.
3977OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3978
3979# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 3980OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
3981
3982reset_pcap_file hv1-vif1 hv1/vif1
3983reset_pcap_file hv1-vif2 hv1/vif2
3984rm -f 1.expected
3985rm -f 2.expected
3986
3987# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3988# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3989
213615b3 3990test_dhcp 3 f00000000003 01 0 4 0
281977f7
NS
3991
3992# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3993# this lport.
213615b3 3994test_dhcp 4 f00000000004 01 0 3 0
281977f7
NS
3995
3996# NXT_RESUMEs should be 3.
3997OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3998
49d7c759
BP
3999OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4000OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 4001
213615b3
NS
4002# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4003offer_ip=`ip_to_hex 10 0 0 6`
4004server_ip=`ip_to_hex 10 0 0 1`
4005expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4006src_ip=$offer_ip
4007dst_ip=$server_ip
4008test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4009
4010# NXT_RESUMEs should be 4.
4011OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4012
4013$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4014cat 2.expected | cut -c -48 > expout
4015AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4016# Skipping the IPv4 checksum.
4017cat 2.expected | cut -c 53- > expout
4018AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4019
4020reset_pcap_file hv1-vif1 hv1/vif1
4021reset_pcap_file hv1-vif2 hv1/vif2
4022rm -f 1.expected
4023rm -f 2.expected
4024
4025# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4026offer_ip=`ip_to_hex 10 0 0 6`
4027server_ip=`ip_to_hex 10 0 0 1`
4028expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4029src_ip=$offer_ip
4030dst_ip=`ip_to_hex 255 255 255 255`
4031test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4032
4033# NXT_RESUMEs should be 5.
4034OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4035
4036$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4037cat 2.expected | cut -c -48 > expout
4038AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4039# Skipping the IPv4 checksum.
4040cat 2.expected | cut -c 53- > expout
4041AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4042
4043reset_pcap_file hv1-vif1 hv1/vif1
4044reset_pcap_file hv1-vif2 hv1/vif2
4045rm -f 1.expected
4046rm -f 2.expected
4047
4048# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4049# The packet should not be received by ovn-controller.
4050src_ip=`ip_to_hex 10 0 0 6`
4051dst_ip=`ip_to_hex 10 0 0 4`
4052test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4053
4054# NXT_RESUMEs should be 5.
4055OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4056
4057# vif1-tx.pcap should have received the DHCPv4 request packet
4058OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4059
281977f7 4060as hv1
33ac3c83
NS
4061OVS_APP_EXIT_AND_WAIT([ovn-controller])
4062OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4063OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4064
4065as ovn-sb
4066OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4067
4068as ovn-nb
4069OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4070
4071as northd
4072OVS_APP_EXIT_AND_WAIT([ovn-northd])
4073
4074as main
4075OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4076OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4077
4078AT_CLEANUP
4079
40df4566 4080AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
4081AT_SKIP_IF([test $HAVE_PYTHON = no])
4082ovn_start
4083
4084ovn-nbctl ls-add ls1
4085ovn-nbctl lsp-add ls1 ls1-lp1 \
4086-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4087
4088ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4089
4090ovn-nbctl lsp-add ls1 ls1-lp2 \
4091-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4092
4093ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4094
40df4566
ZKL
4095ovn-nbctl lsp-add ls1 ls1-lp3 \
4096-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4097
4098ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4099
9060fc9a
MM
4100d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4101options="\"server_id\"=\"00:00:00:10:00:01\"")"
4102
4103ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4104ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4105
4106d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4107options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
33ac3c83 4108
9060fc9a 4109ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
40df4566 4110
33ac3c83
NS
4111ovn-nbctl ls-add ls2
4112ovn-nbctl lsp-add ls2 ls2-lp1 \
4113-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4114ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4115ovn-nbctl lsp-add ls2 ls2-lp2 \
4116-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4117ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4118
4119net_add n1
4120sim_add hv1
4121
4122as hv1
4123ovs-vsctl add-br br-phys
4124ovn_attach n1 br-phys 192.168.0.1
4125ovs-vsctl -- add-port br-int hv1-vif1 -- \
4126 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4127 options:tx_pcap=hv1/vif1-tx.pcap \
4128 options:rxq_pcap=hv1/vif1-rx.pcap \
4129 ofport-request=1
4130
4131ovs-vsctl -- add-port br-int hv1-vif2 -- \
4132 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4133 options:tx_pcap=hv1/vif2-tx.pcap \
4134 options:rxq_pcap=hv1/vif2-rx.pcap \
4135 ofport-request=2
4136
4137ovs-vsctl -- add-port br-int hv1-vif3 -- \
4138 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4139 options:tx_pcap=hv1/vif3-tx.pcap \
4140 options:rxq_pcap=hv1/vif3-rx.pcap \
4141 ofport-request=3
4142
4143ovs-vsctl -- add-port br-int hv1-vif4 -- \
4144 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4145 options:tx_pcap=hv1/vif4-tx.pcap \
4146 options:rxq_pcap=hv1/vif4-rx.pcap \
4147 ofport-request=4
4148
40df4566
ZKL
4149ovs-vsctl -- add-port br-int hv1-vif5 -- \
4150 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4151 options:tx_pcap=hv1/vif5-tx.pcap \
4152 options:rxq_pcap=hv1/vif5-rx.pcap \
4153 ofport-request=5
4154
33ac3c83
NS
4155ovn_populate_arp
4156
4157sleep 2
4158
4159trim_zeros() {
4160 sed 's/\(00\)\{1,\}$//'
4161}
4162
4163# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4164# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4165# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4166# packet should be received twice (one from ovn-controller and the other
4167# from the "ovs-ofctl monitor br-int resume"
4168test_dhcpv6() {
4169 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4170 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4171 # dst ip ff02::1:2
ab187e7e 4172 request=${request}ff020000000000000000000000010002
33ac3c83 4173 # udp header and dhcpv6 header
ab187e7e 4174 request=${request}02220223002affff${msg_code}010203
33ac3c83 4175 # Client identifier
ab187e7e 4176 request=${request}0001000a00030001${src_mac}
33ac3c83 4177 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 4178 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
4179 shift; shift; shift; shift; shift;
4180 if test $offer_ip != 0; then
4181 local server_mac=000000100001
4182 local server_lla=fe80000000000000020000fffe100001
4183 local reply_code=07
4184 if test $msg_code = 01; then
4185 reply_code=02
4186 fi
40df4566
ZKL
4187 local msg_len=54
4188 if test $offer_ip = 1; then
4189 msg_len=28
4190 fi
4191 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4192 # udp header and dhcpv6 header
ab187e7e 4193 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4194 # Client identifier
ab187e7e 4195 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4196 # IA-NA
40df4566 4197 if test $offer_ip != 1; then
ab187e7e 4198 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4199 fi
33ac3c83 4200 # Server identifier
ab187e7e 4201 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4202 echo $reply | trim_zeros >> $inport.expected
4203 else
4204 for outport; do
4205 echo $request | trim_zeros >> $outport.expected
4206 done
4207 fi
4208
4209 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4210}
4211
4212reset_pcap_file() {
4213 local iface=$1
4214 local pcap_file=$2
4215 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4216options:rxq_pcap=dummy-rx.pcap
4217 rm -f ${pcap_file}*.pcap
4218 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4219options:rxq_pcap=${pcap_file}-rx.pcap
4220}
4221
4222AT_CAPTURE_FILE([ofctl_monitor0.log])
4223as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4224--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4225
4226echo "---------NB dump-----"
4227ovn-nbctl show
4228echo "---------------------"
4229echo "---------SB dump-----"
4230ovn-sbctl list datapath_binding
4231echo "---------------------"
4232ovn-sbctl list logical_flow
4233echo "---------------------"
4234
4235echo "---------------------"
4236ovn-sbctl dump-flows
4237echo "---------------------"
4238
4239echo "------ hv1 dump ----------"
4240as hv1 ovs-ofctl dump-flows br-int
4241
4242src_mac=f00000000001
4243src_lla=fe80000000000000f20000fffe000001
4244offer_ip=ae700000000000000000000000000004
4245test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4246
4247# NXT_RESUMEs should be 1.
4248OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4249
4250$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4251# cat 1.expected | trim_zeros > expout
4252cat 1.expected | cut -c -120 > expout
4253AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4254# Skipping the UDP checksum
4255cat 1.expected | cut -c 125- > expout
4256AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4257
4258rm 1.expected
4259
4260# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4261# without any modifications and the packet should be received by ls1-lp1.
4262# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4263# resume and the other from ovs-ofctl monitor resume.
4264
4265reset_pcap_file hv1-vif1 hv1/vif1
4266reset_pcap_file hv1-vif2 hv1/vif2
4267
4268src_mac=f00000000002
4269src_lla=fe80000000000000f20000fffe000002
4270offer_ip=ae700000000000000000000000000005
4271# Set invalid msg_type
4272
4273test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4274
4275# NXT_RESUMEs should be 2.
4276OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4277
4278# vif2-tx.pcap should not have received the DHCPv6 reply packet
4279rm 2.packets
4280$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4281AT_CHECK([cat 2.packets], [0], [])
4282
4283# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4284$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4285cat 1.expected > expout
4286AT_CHECK([cat 1.packets], [0], [expout])
4287
4288# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4289# There should be no DHCPv6 reply from ovn-controller and the request packet
4290# should be received by ls2-lp2.
4291
4292src_mac=f00000000003
4293src_lla=fe80000000000000f20000fffe000003
4294test_dhcpv6 3 $src_mac $src_lla 01 0 4
4295
4296# NXT_RESUMEs should be 2 only.
4297OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4298
4299# vif3-tx.pcap should not have received the DHCPv6 reply packet
4300$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4301AT_CHECK([cat 3.packets], [0], [])
4302
4303# vif4-tx.pcap should have received the DHCPv6 request packet
4304$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4305cat 4.expected > expout
4306AT_CHECK([cat 4.packets], [0], [expout])
4307
40df4566
ZKL
4308# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4309# The DHCPv6 reply should doesn't contian offer_ip.
4310src_mac=f00000000022
4311src_lla=fe80000000000000f20000fffe000022
4312reset_pcap_file hv1-vif5 hv1/vif5
4313test_dhcpv6 5 $src_mac $src_lla 01 1 5
4314
4315# NXT_RESUMEs should be 3.
4316OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4317
4318$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4319# Skipping the UDP checksum
4320cat 5.expected | cut -c 1-120,125- > expout
4321AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4322
33ac3c83 4323as hv1
281977f7
NS
4324OVS_APP_EXIT_AND_WAIT([ovn-controller])
4325OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4326OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4327
4328as ovn-sb
4329OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4330
4331as ovn-nb
4332OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4333
4334as northd
4335OVS_APP_EXIT_AND_WAIT([ovn-northd])
4336
4337as main
4338OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4339OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4340
4341AT_CLEANUP
4342
c1645003 4343AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4344AT_SKIP_IF([test $HAVE_PYTHON = no])
4345ovn_start
4346
4347# Logical network:
4348# Two LRs - R1 and R2 that are connected to each other via LS "join"
4349# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4350# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4351# R2 is a gateway router.
4352
4353
4354
4355# Create two hypervisor and create OVS ports corresponding to logical ports.
4356net_add n1
4357
4358sim_add hv1
4359as hv1
4360ovs-vsctl add-br br-phys
4361ovn_attach n1 br-phys 192.168.0.1
4362ovs-vsctl -- add-port br-int hv1-vif1 -- \
4363 set interface hv1-vif1 external-ids:iface-id=foo1 \
4364 options:tx_pcap=hv1/vif1-tx.pcap \
4365 options:rxq_pcap=hv1/vif1-rx.pcap \
4366 ofport-request=1
4367
4368
4369sim_add hv2
4370as hv2
4371ovs-vsctl add-br br-phys
4372ovn_attach n1 br-phys 192.168.0.2
4373ovs-vsctl -- add-port br-int hv2-vif1 -- \
4374 set interface hv2-vif1 external-ids:iface-id=alice1 \
4375 options:tx_pcap=hv2/vif1-tx.pcap \
4376 options:rxq_pcap=hv2/vif1-rx.pcap \
4377 ofport-request=1
4378
4379# Pre-populate the hypervisors' ARP tables so that we don't lose any
4380# packets for ARP resolution (native tunneling doesn't queue packets
4381# for ARP resolution).
4382ovn_populate_arp
4383
4384ovn-nbctl create Logical_Router name=R1
4385ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4386
ea46a4e9
JP
4387ovn-nbctl ls-add foo
4388ovn-nbctl ls-add alice
4389ovn-nbctl ls-add join
c1645003
GS
4390
4391# Connect foo to R1
31114af7 4392ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4393ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4394 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4395
4396# Connect alice to R2
31114af7 4397ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4398ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4399 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4400
4401# Connect R1 to join
31114af7 4402ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4403ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4404 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4405
4406# Connect R2 to join
31114af7 4407ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4408ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4409 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4410
4411
4412#install static routes
4413ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4414ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4415R1 static_routes @lrt
4416
4417ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4418ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4419R2 static_routes @lrt
4420
4421# Create logical port foo1 in foo
31ed1192
JP
4422ovn-nbctl lsp-add foo foo1 \
4423-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4424
4425# Create logical port alice1 in alice
31ed1192
JP
4426ovn-nbctl lsp-add alice alice1 \
4427-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4428
4429
4430# Allow some time for ovn-northd and ovn-controller to catch up.
4431# XXX This should be more systematic.
4432sleep 2
4433
4434ip_to_hex() {
4435 printf "%02x%02x%02x%02x" "$@"
4436}
c1645003
GS
4437
4438# Send ip packets between foo1 and alice1
4439src_mac="f00000010203"
4440dst_mac="000001010203"
4441src_ip=`ip_to_hex 192 168 1 2`
4442dst_ip=`ip_to_hex 172 16 1 2`
4443packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4444
4445echo "---------NB dump-----"
4446ovn-nbctl show
4447echo "---------------------"
4448ovn-nbctl list logical_router
4449echo "---------------------"
4450ovn-nbctl list logical_router_port
4451echo "---------------------"
4452
4453echo "---------SB dump-----"
4454ovn-sbctl list datapath_binding
4455echo "---------------------"
4456ovn-sbctl list port_binding
4457echo "---------------------"
4458ovn-sbctl dump-flows
4459echo "---------------------"
4460ovn-sbctl list chassis
4461ovn-sbctl list encap
4462echo "---------------------"
4463
c1645003
GS
4464# Packet to Expect at alice1
4465src_mac="000002010203"
4466dst_mac="f00000010204"
4467src_ip=`ip_to_hex 192 168 1 2`
4468dst_ip=`ip_to_hex 172 16 1 2`
4469expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4470
4471
4472as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4473as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4474
ab39371d
RM
4475echo "------ hv1 dump after packet 1 ----------"
4476as hv1 ovs-ofctl show br-int
4477as hv1 ovs-ofctl dump-flows br-int
4478echo "------ hv2 dump after packet 1 ----------"
4479as hv2 ovs-ofctl show br-int
4480as hv2 ovs-ofctl dump-flows br-int
4481echo "----------------------------"
4482
49d7c759
BP
4483echo $expected > expected
4484OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4485
34114cf8
GS
4486# Delete the router and re-create it. Things should work as before.
4487ovn-nbctl lr-del R2
4488ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4489# Connect alice to R2
4490ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4491# Connect R2 to join
4492ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4493
4494ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4495ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4496R2 static_routes @lrt
4497
4498# Wait for ovn-controller to catch up.
4499sleep 1
4500
4501# Send the packet again.
4502as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4503
4504echo "------ hv1 dump after packet 2 ----------"
4505as hv1 ovs-ofctl show br-int
4506as hv1 ovs-ofctl dump-flows br-int
4507echo "------ hv2 dump after packet 2 ----------"
4508as hv2 ovs-ofctl show br-int
4509as hv2 ovs-ofctl dump-flows br-int
4510echo "----------------------------"
4511
49d7c759
BP
4512echo $expected >> expected
4513OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4514
7a8f15e0 4515OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4516
4517AT_CLEANUP
bb3c4568
FF
4518
4519AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4520AT_KEYWORDS([router-icmp-reply])
4521AT_SKIP_IF([test $HAVE_PYTHON = no])
4522ovn_start
4523
4524# Logical network:
4525# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4526# and has switch ls2 (172.16.1.0/24) connected to it.
4527
fa2a27b2 4528ovn-nbctl lr-add R1
bb3c4568 4529
ea46a4e9
JP
4530ovn-nbctl ls-add ls1
4531ovn-nbctl ls-add ls2
bb3c4568
FF
4532
4533# Connect ls1 to R1
31114af7 4534ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4535ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4536 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4537
4538# Connect ls2 to R1
31114af7 4539ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4540ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4541 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4542
4543# Create logical port ls1-lp1 in ls1
31ed1192
JP
4544ovn-nbctl lsp-add ls1 ls1-lp1 \
4545-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4546
4547# Create logical port ls2-lp1 in ls2
31ed1192
JP
4548ovn-nbctl lsp-add ls2 ls2-lp1 \
4549-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4550
4551# Create one hypervisor and create OVS ports corresponding to logical ports.
4552net_add n1
4553
4554sim_add hv1
4555as hv1
4556ovs-vsctl add-br br-phys
4557ovn_attach n1 br-phys 192.168.0.1
4558ovs-vsctl -- add-port br-int vif1 -- \
4559 set interface vif1 external-ids:iface-id=ls1-lp1 \
4560 options:tx_pcap=hv1/vif1-tx.pcap \
4561 options:rxq_pcap=hv1/vif1-rx.pcap \
4562 ofport-request=1
4563
4564ovs-vsctl -- add-port br-int vif2 -- \
4565 set interface vif2 external-ids:iface-id=ls2-lp1 \
4566 options:tx_pcap=hv1/vif2-tx.pcap \
4567 options:rxq_pcap=hv1/vif2-rx.pcap \
4568 ofport-request=1
4569
4570
4571# Allow some time for ovn-northd and ovn-controller to catch up.
4572# XXX This should be more systematic.
4573sleep 1
4574
4575
4576ip_to_hex() {
4577 printf "%02x%02x%02x%02x" "$@"
4578}
bb3c4568
FF
4579for i in 1 2; do
4580 : > vif$i.expected
4581done
4582# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4583#
4584# Causes a packet to be received on INPORT. The packet is an ICMPv4
4585# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4586# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4587# provided, then it should be the ip and icmp checksums of the packet
4588# responded; otherwise, no reply is expected.
4589# In the absence of an ip checksum calculation helpers, this relies
4590# on the caller to provide the checksums for the ip and icmp headers.
4591# XXX This should be more systematic.
4592#
4593# INPORT is an lport number, e.g. 11 for vif11.
4594# ETH_SRC and ETH_DST are each 12 hex digits.
4595# IPV4_SRC and IPV4_DST are each 8 hex digits.
4596# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4597# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4598test_ipv4_icmp_request() {
4599 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4600 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4601 shift; shift; shift; shift; shift; shift; shift
4602 shift; shift
4603
4604 # Use ttl to exercise section 4.2.2.9 of RFC1812
4605 local ip_ttl=01
4606 local icmp_id=5fbf
4607 local icmp_seq=0001
4608 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4609 local icmp_type_code_request=0800
4610 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4611 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4612
4613 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4614 if test X$exp_icmp_chksum != X; then
4615 # Expect to receive the reply, if any. In same port where packet was sent.
4616 # Note: src and dst fields are expected to be reversed.
4617 local icmp_type_code_response=0000
4618 local reply_icmp_ttl=fe
4619 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4620 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4621 echo $reply >> vif$inport.expected
4622 fi
4623}
4624
4625# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4626rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4627rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4628l1_ip=$(ip_to_hex 192 168 1 2)
4629l2_ip=$(ip_to_hex 172 16 1 2)
4630
4631# Ping router ip address that is on same subnet as the logical port
4632test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4633test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4634
4635# Ping router ip address that is on the other side of the logical ports
4636test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4637test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4638
4639echo "---------NB dump-----"
4640ovn-nbctl show
4641echo "---------------------"
4642ovn-nbctl list logical_router
4643echo "---------------------"
4644ovn-nbctl list logical_router_port
4645echo "---------------------"
4646
4647echo "---------SB dump-----"
4648ovn-sbctl list datapath_binding
4649echo "---------------------"
4650ovn-sbctl list logical_flow
4651echo "---------------------"
4652
4653echo "------ hv1 dump ----------"
4654as hv1 ovs-ofctl dump-flows br-int
4655
4656# Now check the packets actually received against the ones expected.
4657for inport in 1 2; do
49d7c759 4658 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4659done
4660
7a8f15e0 4661OVN_CLEANUP([hv1])
bb3c4568
FF
4662
4663AT_CLEANUP
94f79fcb
RB
4664
4665# 1 hypervisor, 1 port
4666# make sure that the port state is properly set to up and back down
4667# when created and deleted.
4668AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
4669ovn_start
4670
4671ovn-nbctl ls-add ls1
4672ovn-nbctl lsp-add ls1 lp1
4673ovn-nbctl lsp-set-addresses lp1 unknown
4674
4675net_add n1
4676sim_add hv1
4677as hv1 ovs-vsctl add-br br-phys
4678as hv1 ovn_attach n1 br-phys 192.168.0.1
4679
4680as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4681OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4682
4683as hv1 ovs-vsctl del-port br-int vif1
4684OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4685
7a8f15e0 4686OVN_CLEANUP([hv1])
94f79fcb 4687
94f79fcb 4688AT_CLEANUP
e75451fe 4689
ccc6e1db
FF
4690# 1 hypervisor, 1 port
4691# make sure that the OF rules created to support a datapath are added/cleared
4692# when logical switch is created and removed.
4693AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 4694AT_KEYWORDS([cleanup])
ccc6e1db
FF
4695ovn_start
4696
4697net_add n1
4698sim_add hv1
4699as hv1 ovs-vsctl add-br br-phys
4700as hv1 ovn_attach n1 br-phys 192.168.0.1
4701
4702# This shell function checks if OF rules in br-int have clauses
4703# related to OVN datapaths. The caller determines if it should find
4704# a match in the output, or not.
4705#
4706# EXPECT_DATAPATH param determines whether flows that refer to
4707# datapath to should be present or not. 0 means
4708# they should not be.
4709# STAGE_INFO param is a simple string to help identify the stage
4710# in the test when this function was invoked.
4711test_datapath_in_of_rules() {
4712 local expect_datapath=$1 stage_info=$2
4713 echo "------ ovn-nbctl show ${stage_info} ------"
4714 ovn-nbctl show
4715 echo "------ ovn-sbctl show ${stage_info} ------"
4716 ovn-sbctl show
4717 echo "------ OF rules ${stage_info} ------"
4718 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4719 # if there is a datapath mentioned in the output, check for the
4720 # magic keyword that represents one, based on the exit status of
4721 # a quiet grep
4722 if test $expect_datapath != 0; then
4618b102 4723 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 4724 else
4618b102 4725 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
4726 fi
4727}
4728
4729test_datapath_in_of_rules 0 "before ls+port create"
4730
4731ovn-nbctl ls-add ls1
4732ovn-nbctl lsp-add ls1 lp1
4733ovn-nbctl lsp-set-addresses lp1 unknown
4734
4735as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4736OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4737
4738test_datapath_in_of_rules 1 "after port is bound"
4739
4740as hv1 ovs-vsctl del-port br-int vif1
4741OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4742
4743ovn-nbctl lsp-set-addresses lp1
4744ovn-nbctl lsp-del lp1
4745ovn-nbctl ls-del ls1
4746
4747# wait for earlier changes to take effect
4748AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4749
4750# ensure OF rules are no longer present. There used to be a bug here.
4751test_datapath_in_of_rules 0 "after lport+ls removal"
4752
4753OVN_CLEANUP([hv1])
4754
4755AT_CLEANUP
4756
f8a8db39 4757AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
4758AT_SKIP_IF([test $HAVE_PYTHON = no])
4759ovn_start
4760
4761#TODO: since patch port for IPv6 logical router port is not ready not,
4762# so we are not going to test vifs on different lswitches cases. Try
4763# to update for that once relevant stuff implemented.
4764
4765# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4766# with. NS packet we test, from one VIF for another VIF, will be replied
4767# by local ovn-controller, but not by target VIF.
4768
4769# Create hypervisors and logical switch lsw0.
4770ovn-nbctl ls-add lsw0
4771net_add n1
4772sim_add hv1
4773as hv1
4774ovs-vsctl add-br br-phys
4775ovn_attach n1 br-phys 192.168.0.2
4776
4777# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4778ovs-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
4779ovn-nbctl lsp-add lsw0 lp1
4780ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4781ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4782
4783# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4784ovs-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
4785ovn-nbctl lsp-add lsw0 lp2
4786ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4787ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4788
4789# Add ACL rule for ICMPv6 on lsw0
4790ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4791ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4792ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4793
4794# Allow some time for ovn-northd and ovn-controller to catch up.
4795# XXX This should be more systematic.
4796sleep 1
4797
4798# Given the name of a logical port, prints the name of the hypervisor
4799# on which it is located.
4800vif_to_hv() {
4801 echo hv1${1%?}
4802}
e75451fe
ZKL
4803for i in 1 2; do
4804 : > $i.expected
4805done
4806
4807# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4808# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4809# vif2 will not receive NS packet, since ovn-controller will reply for it.
4810ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4811na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4812
4813as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 4814echo $na_packet >> 1.expected
e75451fe 4815
e75451fe
ZKL
4816echo "------ hv1 dump ------"
4817as hv1 ovs-vsctl show
4818as hv1 ovs-ofctl -O OpenFlow13 show br-int
4819as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4820
4821for i in 1 2; do
49d7c759 4822 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
4823done
4824
7a8f15e0 4825OVN_CLEANUP([hv1])
e75451fe
ZKL
4826
4827AT_CLEANUP
7417d147
RM
4828
4829AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
4830ovn_start
4831
4832net_add n1
4833
4834sim_add hv1
4835as hv1
4836ovs-vsctl add-br br-phys
4837ovn_attach n1 br-phys 192.168.0.1
4838
4839row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4840ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4841ovn-nbctl destroy Address_Set $row
4842
4843sleep 1
4844
4845# A bug previously existed in the address set support code
4846# that caused ovn-controller to crash after an address set
4847# was updated and then removed. This test case ensures
4848# that ovn-controller is at least still running after
4849# creating, updating, and deleting an address set.
4850AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4851
4852OVN_CLEANUP([hv1])
4853
4854AT_CLEANUP
8639f9be
ND
4855
4856AT_SETUP([ovn -- ipam])
8639f9be
ND
4857AT_SKIP_IF([test $HAVE_PYTHON = no])
4858ovn_start
4859
4860# Add a port to a switch that does not have a subnet set, then set the
4861# subnet which should result in an address being allocated for the port.
4862ovn-nbctl ls-add sw0
4863ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 4864ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
4865AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4866 ["0a:00:00:00:00:01 192.168.1.2"
4867])
4868
4869# Add 9 more ports to sw0, addresses should all be unique.
4870for n in `seq 1 9`; do
11547f85 4871 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4872done
4873AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4874 ["0a:00:00:00:00:02 192.168.1.3"
4875])
4876AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4877 ["0a:00:00:00:00:03 192.168.1.4"
4878])
4879AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4880 ["0a:00:00:00:00:04 192.168.1.5"
4881])
4882AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4883 ["0a:00:00:00:00:05 192.168.1.6"
4884])
4885AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4886 ["0a:00:00:00:00:06 192.168.1.7"
4887])
4888AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4889 ["0a:00:00:00:00:07 192.168.1.8"
4890])
4891AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4892 ["0a:00:00:00:00:08 192.168.1.9"
4893])
4894AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4895 ["0a:00:00:00:00:09 192.168.1.10"
4896])
4897AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4898 ["0a:00:00:00:00:0a 192.168.1.11"
4899])
4900
4901# Trying similar tests with a second switch. MAC addresses should be unique
4902# across both switches but IP's only need to be unique within the same switch.
4903ovn-nbctl ls-add sw1
4904ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 4905ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
4906AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4907 ["0a:00:00:00:00:0b 192.168.1.2"
4908])
4909
4910for n in `seq 11 19`; do
11547f85 4911 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4912done
4913AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4914 ["0a:00:00:00:00:0c 192.168.1.3"
4915])
4916AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4917 ["0a:00:00:00:00:0d 192.168.1.4"
4918])
4919AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4920 ["0a:00:00:00:00:0e 192.168.1.5"
4921])
4922AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4923 ["0a:00:00:00:00:0f 192.168.1.6"
4924])
4925AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4926 ["0a:00:00:00:00:10 192.168.1.7"
4927])
4928AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4929 ["0a:00:00:00:00:11 192.168.1.8"
4930])
4931AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4932 ["0a:00:00:00:00:12 192.168.1.9"
4933])
4934AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4935 ["0a:00:00:00:00:13 192.168.1.10"
4936])
4937AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4938 ["0a:00:00:00:00:14 192.168.1.11"
4939])
4940
4941# Change a port's address to test for multiple ip's for a single address entry
4942# and addresses set by the user.
4943ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
11547f85 4944ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
4945AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4946 ["0a:00:00:00:00:16 192.168.1.13"
4947])
4948
4949# Test for logical router port address management.
4950ovn-nbctl create Logical_Router name=R1
4951ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4952network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4953-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4954-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 4955ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
4956AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4957 ["0a:00:00:00:00:18 192.168.1.15"
4958])
4959
4960# Test for address reuse after logical port is deleted.
4961ovn-nbctl lsp-del p0
11547f85 4962ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
4963AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4964 ["0a:00:00:00:00:19 192.168.1.2"
4965])
4966
4967# Test for multiple addresses to one logical port.
4968ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4969"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 4970ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
4971AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4972 ["0a:00:00:00:00:1c 192.168.1.16"
4973])
4974
4975# Test for exhausting subnet address space.
4976ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 4977ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
4978AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4979 ["0a:00:00:00:00:1d 172.16.1.2"
4980])
4981
11547f85 4982ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 4983AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
7cc0741e 4984 ["0a:00:00:00:00:1e"
8639f9be
ND
4985])
4986
4987# Test that address management does not add duplicate MAC for lsp/lrp peers.
4988ovn-nbctl create Logical_Router name=R2
4989ovn-nbctl ls-add sw3
4990ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
7cc0741e 4991"0a:00:00:00:00:1f"
8639f9be
ND
4992ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4993network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4994-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4995-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 4996ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
4997AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4998 ["0a:00:00:00:00:20 192.168.1.17"
4999])
5000
6374d518
LR
5001# Test static MAC address with dynamically allocated IP
5002ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5003"fe:dc:ba:98:76:54 dynamic"
5004AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5005 ["fe:dc:ba:98:76:54 192.168.1.18"
5006])
5007
6c4f7a8a
NS
5008# Update the static MAC address with dynamically allocated IP and check
5009# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5010ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5011ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5012
5013AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5014 ["fe:dc:ba:98:76:55 192.168.1.18"
5015])
5016
5017ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5018AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5019 ["fe:dc:ba:98:76:55 192.168.1.18"
5020])
5021
5022ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5023AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5024 ["fe:dc:ba:98:76:56 192.168.1.18"
5025])
5026
161ea2c8
NS
5027
5028# Test the exclude_ips from the IPAM list
5029ovn-nbctl --wait=sb set logical_switch sw0 \
5030other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5031
5032ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5033"dynamic"
5034# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5035AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5036 ["0a:00:00:00:00:21 192.168.1.20"
5037])
5038
5039ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5040"dynamic"
5041# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5042AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5043 ["0a:00:00:00:00:22 192.168.1.22"
5044])
5045
5046ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5047"dynamic"
5048# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5049AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5050 ["0a:00:00:00:00:23 192.168.1.51"
5051])
5052
5053# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5054ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5055ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5056"dynamic"
5057AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5058 ["0a:00:00:00:00:24 192.168.1.19"
5059])
5060
5061# Set invalid data in exclude_ips list. It should be ignored.
5062ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5063ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5064"dynamic"
5065# 192.168.1.21 should be assigned as that's the next free one.
5066AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5067 ["0a:00:00:00:00:25 192.168.1.21"
5068])
5069
5070# Clear the dynamic addresses assignment request.
5071ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5072AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5073 [[[]]
5074])
5075
7cc0741e
NS
5076# Set IPv6 prefix
5077ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5078ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5079"dynamic"
5080
5081# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5082# - aef0::800:ff:fe00:26 (EUI64)
5083AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5084 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5085])
5086
5087ovn-nbctl --wait=sb ls-add sw4
5088ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5089ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5090"dynamic"
5091
5092AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5093 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5094])
5095
5096ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5097"f0:00:00:00:10:12 dynamic"
5098
5099AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5100 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5101])
5102
5103# Clear the other_config for sw4. No dynamic ip should be assigned.
5104ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5105ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5106"dynamic"
5107
5108AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5109 [[[]]
5110])
5111
5112# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5113ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5114-- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5115
5116# Now p40 should be assigned with dynamic addresses.
5117AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5118 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5119])
5120
5121ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5122"dynamic"
5123# p41 should not have IPv4 address (as the pool is exhausted).
5124AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5125 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5126])
5127
8639f9be
ND
5128as ovn-sb
5129OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5130
5131as ovn-nb
5132OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5133
5134as northd
5135OVS_APP_EXIT_AND_WAIT([ovn-northd])
5136
5137AT_CLEANUP
5138
5139AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5140AT_SKIP_IF([test $HAVE_PYTHON = no])
5141ovn_start
5142
5143ovn-nbctl lr-add R1
5144
5145# Test for a ping using dynamically allocated addresses.
5146ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5147ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5148
5149# Connect foo to R1
5150ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5151ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5152 options:router-port=foo \
5153 -- lsp-set-addresses rp-foo router
8639f9be
ND
5154
5155# Connect alice to R1
5156ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5157ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5158 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5159
5160# Create logical port foo1 in foo
fd3b31e9 5161ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5162-- lsp-set-addresses foo1 "dynamic"
8bc2c143 5163AT_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
5164
5165# Create logical port alice1 in alice
fd3b31e9 5166ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5167-- lsp-set-addresses alice1 "dynamic"
8bc2c143 5168AT_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
5169
5170# Create logical port foo2 in foo
fd3b31e9 5171ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5172-- lsp-set-addresses foo2 "dynamic"
8bc2c143 5173AT_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
5174
5175# Create a hypervisor and create OVS ports corresponding to logical ports.
5176net_add n1
5177
5178sim_add hv1
5179as hv1
5180ovs-vsctl add-br br-phys
5181ovn_attach n1 br-phys 192.168.0.1
5182ovs-vsctl -- add-port br-int hv1-vif1 -- \
5183 set interface hv1-vif1 external-ids:iface-id=foo1 \
5184 options:tx_pcap=hv1/vif1-tx.pcap \
5185 options:rxq_pcap=hv1/vif1-rx.pcap \
5186 ofport-request=1
5187
5188ovs-vsctl -- add-port br-int hv1-vif2 -- \
5189 set interface hv1-vif2 external-ids:iface-id=foo2 \
5190 options:tx_pcap=hv1/vif2-tx.pcap \
5191 options:rxq_pcap=hv1/vif2-rx.pcap \
5192 ofport-request=2
5193
5194ovs-vsctl -- add-port br-int hv1-vif3 -- \
5195 set interface hv1-vif3 external-ids:iface-id=alice1 \
5196 options:tx_pcap=hv1/vif3-tx.pcap \
5197 options:rxq_pcap=hv1/vif3-rx.pcap \
5198 ofport-request=3
5199
5200# Allow some time for ovn-northd and ovn-controller to catch up.
5201# XXX This should be more systematic.
5202sleep 1
5203
5204ip_to_hex() {
5205 printf "%02x%02x%02x%02x" "$@"
5206}
8639f9be
ND
5207
5208# Send ip packets between foo1 and foo2
5209src_mac="0a0000000001"
5210dst_mac="0a0000000003"
5211src_ip=`ip_to_hex 192 168 1 2`
5212dst_ip=`ip_to_hex 192 168 1 3`
5213packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5214as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5215
5216# Send ip packets between foo1 and alice1
5217src_mac="0a0000000001"
5218dst_mac="000000010203"
5219src_ip=`ip_to_hex 192 168 1 2`
5220dst_ip=`ip_to_hex 192 168 2 2`
5221packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5222as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5223
5224echo "---------NB dump-----"
5225ovn-nbctl show
5226echo "---------------------"
5227ovn-nbctl list logical_router
5228echo "---------------------"
5229ovn-nbctl list logical_router_port
5230echo "---------------------"
5231
5232echo "---------SB dump-----"
5233ovn-sbctl list datapath_binding
5234echo "---------------------"
5235ovn-sbctl list port_binding
5236echo "---------------------"
5237
5238echo "------ hv1 dump ----------"
5239as hv1 ovs-ofctl dump-flows br-int
5240
5241# Packet to Expect at foo2
5242src_mac="0a0000000001"
5243dst_mac="0a0000000003"
5244src_ip=`ip_to_hex 192 168 1 2`
5245dst_ip=`ip_to_hex 192 168 1 3`
5246expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5247
e4543cfe
DDP
5248$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5249echo $expected > expout
8639f9be
ND
5250AT_CHECK([cat received1.packets], [0], [expout])
5251
5252# Packet to Expect at alice1
5253src_mac="000000010204"
5254dst_mac="0a0000000002"
5255src_ip=`ip_to_hex 192 168 1 2`
5256dst_ip=`ip_to_hex 192 168 2 2`
5257expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5258
e4543cfe
DDP
5259$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5260echo $expected > expout
8639f9be
ND
5261AT_CHECK([cat received2.packets], [0], [expout])
5262
5263OVN_CLEANUP([hv1])
5264
5265AT_CLEANUP
f5792c3f
NS
5266
5267AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5268AT_KEYWORDS([vswitchd])
f5792c3f
NS
5269AT_SKIP_IF([test $HAVE_PYTHON = no])
5270ovn_start
5271
5272ovn-nbctl ls-add ls1
5273
5274ovn-nbctl lsp-add ls1 ls1-lp1 \
5275-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5276
5277ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5278
5279net_add n1
5280sim_add hv1
5281
5282as hv1
5283ovs-vsctl add-br br-phys
5284ovn_attach n1 br-phys 192.168.0.1
5285ovs-vsctl -- add-port br-int hv1-vif1 -- \
5286 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5287 options:tx_pcap=hv1/vif1-tx.pcap \
5288 options:rxq_pcap=hv1/vif1-rx.pcap \
5289 ofport-request=1
5290
5291ovn_populate_arp
5292sleep 2
5293
5294as hv1 ovs-vsctl show
5295
5296echo "---------------------"
5297ovn-sbctl dump-flows
5298echo "---------------------"
5299
5300echo "------ hv1 dump ----------"
5301as hv1 ovs-ofctl dump-flows br-int
5302total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5303
5304echo "Total flows before vswitchd restart = " $total_flows
5305
5306# Code taken from ovs-save utility
5307save_flows () {
5308 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5309 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5310 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5311 echo "EOF" >> restore_flows.sh
5312}
5313
5314restart_vswitchd () {
5315 restore_flows=$1
5316
5317 if test $restore_flows = true; then
5318 save_flows
5319 fi
5320
5321 as hv1
5322 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5323
5324 if test $restore_flows = true; then
5325 as hv1
5326 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5327 fi
5328
5329 as hv1
5330 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5331 ovs-ofctl dump-flows br-int
5332
5333 if test $restore_flows = true; then
5334 sh ./restore_flows.sh
5335 echo "Flows after restore"
5336 as hv1
5337 ovs-ofctl dump-flows br-int
5338 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5339 flow-restore-wait="true"
5340 fi
5341}
5342
5343# Save the flows, restart vswitchd and restore the flows
5344restart_vswitchd true
5345OVS_WAIT_UNTIL([
5346 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5347 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5348 test "${total_flows}" = "${total_flows_after_restart}"
5349])
5350
5351# Restart vswitchd without restoring
5352restart_vswitchd false
5353OVS_WAIT_UNTIL([
5354 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5355 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5356 test "${total_flows}" = "${total_flows_after_restart}"
5357])
5358
5359OVN_CLEANUP([hv1])
5360AT_CLEANUP
47021598
CSV
5361
5362AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5363AT_SKIP_IF([test $HAVE_PYTHON = no])
5364ovn_start
5365
5366# Topology: Two LSs - ls1 and ls2 are connected via router r0
5367
5368# Create logical switches
5369ovn-nbctl ls-add ls1
5370ovn-nbctl ls-add ls2
5371
5372# Create router
5373ovn-nbctl create Logical_Router name=lr0
5374
5375# Add router ls1p1 port to gateway router
5376ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5377ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5378 type=router options:router-port=lrp-ls1lp1 \
5379 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5380
5381# Add router ls2p2 port to gateway router
5382ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5383ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5384 type=router options:router-port=lrp-ls2lp1 \
5385 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5386
5387# Set default gateway (nexthop) to 192.168.1.254
5388ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5389
5390# Create logical port ls1lp2 in ls1
5391ovn-nbctl lsp-add ls1 ls1lp2 \
5392-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5393
5394# Create logical port ls2lp2 in ls2
5395ovn-nbctl lsp-add ls2 ls2lp2 \
5396-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5397
5398net_add n1
5399sim_add hv1
5400as hv1
5401ovs-vsctl add-br br-phys
5402ovn_attach n1 br-phys 192.168.0.1
5403ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5404 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5405 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5406 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5407 ofport-request=1
5408ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5409 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5410 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5411 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5412 ofport-request=2
5413
5414# Allow some time for ovn-northd and ovn-controller to catch up.
5415# XXX This should be more systematic.
5416sleep 1
5417
5418echo "---------NB dump-----"
5419ovn-nbctl show
5420echo "---------------------"
5421ovn-nbctl list logical_router
5422echo "---------------------"
5423ovn-nbctl list logical_router_port
5424echo "---------------------"
5425
5426echo "---------SB dump-----"
5427ovn-sbctl list datapath_binding
5428echo "---------------------"
5429ovn-sbctl list port_binding
5430echo "---------------------"
5431ovn-sbctl dump-flows
5432echo "---------------------"
5433ovn-sbctl list chassis
5434ovn-sbctl list encap
5435echo "---------------------"
5436
5437echo "------Flows dump-----"
5438as hv1
5439ovs-ofctl dump-flows
5440echo "---------------------"
5441
5442ip_to_hex() {
5443 printf "%02x%02x%02x%02x" "$@"
5444}
5445
5446src_mac="f00000000003"
5447dst_mac="f00000000001"
5448src_ip=`ip_to_hex 192 168 0 2`
5449dst_ip=`ip_to_hex 8 8 8 8`
5450packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5451
5452# Send IP packet destined to 8.8.8.8 from lsp1lp2
5453as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5454
5455trim_zeros() {
5456 sed 's/\(00\)\{1,\}$//'
5457}
5458
5459# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5460# not 8.8.8.8
5461
5462$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5463expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5464echo $expected > expout
5465AT_CHECK([cat packets], [0], [expout])
5466cat packets
5467
5468OVN_CLEANUP([hv1])
5469
5470AT_CLEANUP
8439c2eb
CSV
5471
5472AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5473AT_SKIP_IF([test $HAVE_PYTHON = no])
5474ovn_start
5475# Create logical switch
5476ovn-nbctl ls-add ls0
5477# Create gateway router
5478ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5479# Add router port to gateway router
5480ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5481ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5482 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
5483# Add nat-address option
5484ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5485
5486net_add n1
5487sim_add hv1
5488as hv1
5489ovs-vsctl \
5490 -- add-br br-phys \
5491 -- add-br br-eth0
5492
5493ovn_attach n1 br-phys 192.168.0.1
5494
5495AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5496AT_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])
5497
5498# Create a localnet port.
5499AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5500AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5501AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5502AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5503
5504
5505# Wait for packet to be received.
5506OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5507trim_zeros() {
5508 sed 's/\(00\)\{1,\}$//'
5509}
5510$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5511expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5512echo $expected > expout
5513AT_CHECK([sort packets], [0], [expout])
5514cat packets
5515
5516OVN_CLEANUP([hv1])
5517
5518AT_CLEANUP
6e31816f 5519
e914fb54
MS
5520AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5521AT_SKIP_IF([test $HAVE_PYTHON = no])
5522ovn_start
5523# Create logical switch
5524ovn-nbctl ls-add ls0
5525# Create gateway router
5526ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5527# Add router port to gateway router
5528ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5529ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5530 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
5531# Add nat-address option
5532ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5533# Add NAT rules
5534AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5535AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5536# Add load balancers
5537AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5538AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5539AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5540AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5541
5542net_add n1
5543sim_add hv1
5544as hv1
5545ovs-vsctl \
5546 -- add-br br-phys \
5547 -- add-br br-eth0
5548
5549ovn_attach n1 br-phys 192.168.0.1
5550
5551AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5552AT_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])
5553
5554# Create a localnet port.
5555AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5556AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5557AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5558AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5559
5560
5561# Wait for packet to be received.
5562OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5563trim_zeros() {
5564 sed 's/\(00\)\{1,\}$//'
5565}
5566$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5567expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5568echo $expected > expout
5569expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5570echo $expected >> expout
5571expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5572echo $expected >> expout
5573AT_CHECK([sort packets], [0], [expout])
5574cat packets
5575
5576OVN_CLEANUP([hv1])
5577
5578AT_CLEANUP
5579
6e31816f 5580AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
5581ovn_start
5582net_add n1
5583sim_add hv1
5584as hv1
5585ovs-vsctl -- add-br br-phys
5586ovn_attach n1 br-phys 192.168.0.1
5587# Create logical switch ls0
5588ovn-nbctl ls-add ls0
5589# Create ports lp0, lp1 in ls0
5590ovn-nbctl lsp-add ls0 lp0
5591ovn-nbctl lsp-add ls0 lp1
5592ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5593ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5594dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5595ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5596ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5597ovn-sbctl find MAC_Binding
093aa761 5598# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5599ovn-nbctl lsp-del lp0
5600ovn-sbctl find MAC_Binding
093aa761
BP
5601OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5602# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5603ovn-nbctl ls-del ls0
5604ovn-sbctl find MAC_Binding
093aa761 5605OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
5606
5607OVN_CLEANUP([hv1])
5608
5609AT_CLEANUP
926c34fd
RM
5610
5611AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
5612AT_SKIP_IF([test $HAVE_PYTHON = no])
5613ovn_start
5614
5615# Logical network:
5616# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5617# connected to a router R1.
5618# foo has foo1 to act as a client.
5619# bar has bar1, bar2, bar3 to act as servers.
5620
5621net_add n1
5622
5623sim_add hv1
5624as hv1
5625ovs-vsctl add-br br-phys
5626ovn_attach n1 br-phys 192.168.0.1
5627for i in foo1 bar1 bar2 bar3; do
5628 ovs-vsctl -- add-port br-int $i -- \
5629 set interface $i external-ids:iface-id=$i \
5630 options:tx_pcap=hv1/$i-tx.pcap \
5631 options:rxq_pcap=hv1/$i-rx.pcap
5632done
5633
5634ovn-nbctl create Logical_Router name=R1
5635ovn-nbctl ls-add foo
5636ovn-nbctl ls-add bar
5637
5638# Connect foo to R1
5639ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5640ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5641 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5642
5643# Connect bar to R1
5644ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5645ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5646 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5647
5648# Create logical port foo1 in foo
5649ovn-nbctl lsp-add foo foo1 \
5650-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5651
5652# Create logical port bar1, bar2 and bar3 in bar
5653for i in `seq 1 3`; do
5654 ip=`expr $i + 1`
5655 ovn-nbctl lsp-add bar bar$i \
5656 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5657done
5658
5659OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5660
5661OVN_CLEANUP([hv1])
5662
5663AT_CLEANUP
b511690b
GS
5664
5665AT_SETUP([ovn -- tag allocation])
b511690b
GS
5666ovn_start
5667
5668AT_CHECK([ovn-nbctl ls-add ls0])
5669AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5670AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5671AT_CHECK([ovn-nbctl ls-add ls1])
5672
5673dnl When a tag is provided, no allocation is done
5674AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5675AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5676])
5677dnl The same 'tag' gets created in southbound database.
5678AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5679logical_port="c0"], [0], [3
5680])
5681
5682dnl Allocate tags and see it getting created in both NB and SB
5683AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5684AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5685])
5686AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5687logical_port="c1"], [0], [1
5688])
5689
5690AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5691AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5692])
5693AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5694logical_port="c2"], [0], [2
5695])
5696AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5697AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5698])
5699AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5700logical_port="c3"], [0], [4
5701])
5702
5703dnl A different parent.
5704AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5705AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5706])
5707AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5708logical_port="c4"], [0], [1
5709])
5710
5711AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5712AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5713])
5714AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5715logical_port="c5"], [0], [2
5716])
5717
5718dnl Delete a logical port and create a new one.
5719AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5720AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5721AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5722])
5723AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5724logical_port="c6"], [0], [1
5725])
5726
5727dnl Restart northd to see that the same allocation remains.
5728as northd
5729OVS_APP_EXIT_AND_WAIT([ovn-northd])
5730start_daemon ovn-northd \
5731 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5732 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5733
5734dnl Create a switch to make sure that ovn-northd has run through the main loop.
5735AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5736AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5737])
5738AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5739])
5740AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5741])
5742AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5743])
5744AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5745])
5746AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5747])
5748
5749dnl Create a switch port with a tag that has already been allocated.
5750dnl It should go through fine with a duplicate tag.
5751AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5752AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5753])
5754AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5755logical_port="c7"], [0], [2
5756])
5757AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5758])
5759
5760AT_CHECK([ovn-nbctl ls-add ls2])
5761dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5762dnl gets copied to 'tag'
5763AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5764AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
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="local0"], [0], [25
5769])
5770dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5771AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5772AT_CHECK([ovn-nbctl lsp-get-tag local1])
5773dnl change the tag_request.
5774AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5775AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5776])
5777
5778AT_CLEANUP
57afd0c0
RR
5779
5780AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
5781ovn_start
5782ovn-nbctl ls-add lsw0
5783net_add n1
5784for i in 1 2; do
5785 sim_add hv$i
5786 as hv$i
5787 ovs-vsctl add-br br-phys
5788 ovn_attach n1 br-phys 192.168.0.$i
5789 ovs-vsctl add-br br-eth0
5790 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5791done
5792
5793# Create a localnet port.
5794AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5795AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5796AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5797AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5798
5799
5800# Create 3 vifs.
5801AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5802AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5803AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5804AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5805AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5806AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5807AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5808AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5809AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5810
5811# Bind the localvif1 to hv1.
5812as hv1
5813AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5814
5815# On hv1, check that there are no flows outputting bcast to tunnel
5816OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5817
1ea9b847 5818# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 5819as hv2
1ea9b847 5820OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
5821
5822# Now bind vif2 on hv2.
5823AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5824
5825# At this point, the broadcast flow on vif2 should be deleted.
5826# because, there is now a localnet vif bound (table=32 programming logic)
5827OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5828
5829# Verify that the local net patch port exists on hv2.
5830OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5831
5832# Now bind vif3 on hv2.
5833AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5834
5835# Verify that the local net patch port still exists on hv2
5836OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5837
5838# Delete localvif2
5839AT_CHECK([ovn-nbctl lsp-del localvif2])
5840
5841# Verify that the local net patch port still exists on hv2,
5842# because, localvif3 is still bound.
5843OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5844
57afd0c0 5845OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
5846
5847AT_CLEANUP
5848
d383eed5
JP
5849
5850AT_SETUP([ovn -- ACL logging])
5851AT_KEYWORDS([ovn])
5852ovn_start
5853
5854net_add n1
5855
5856sim_add hv
5857as hv
5858ovs-vsctl add-br br-phys
5859ovn_attach n1 br-phys 192.168.0.1
5860for i in lp1 lp2; do
5861 ovs-vsctl -- add-port br-int $i -- \
5862 set interface $i external-ids:iface-id=$i \
5863 options:tx_pcap=hv/$i-tx.pcap \
5864 options:rxq_pcap=hv/$i-rx.pcap
5865done
5866
5867lp1_mac="f0:00:00:00:00:01"
5868lp1_ip="192.168.1.2"
5869
5870lp2_mac="f0:00:00:00:00:02"
5871lp2_ip="192.168.1.3"
5872
5873ovn-nbctl ls-add lsw0
5874ovn-nbctl --wait=sb lsp-add lsw0 lp1
5875ovn-nbctl --wait=sb lsp-add lsw0 lp2
5876ovn-nbctl lsp-set-addresses lp1 $lp1_mac
5877ovn-nbctl lsp-set-addresses lp2 $lp2_mac
5878ovn-nbctl --wait=sb sync
5879
5880ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
5881ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
5882
5883ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
5884ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
5885
5886ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
5887ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
5888
5889ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
5890ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
5891
5892ovn-sbctl dump-flows
5893
5894
5895# Send packet that should be dropped without logging.
5896packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5897 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5898 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
5899as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5900
5901# Send packet that should be dropped with logging.
5902packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5903 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5904 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
5905as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5906
5907# Send packet that should be allowed without logging.
5908packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5909 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5910 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
5911as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5912
5913# Send packet that should be allowed with logging.
5914packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5915 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5916 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
5917as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5918
5919# Send packet that should allow related flows without logging.
5920packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5921 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5922 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
5923as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5924
5925# Send packet that should allow related flows with logging.
5926packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5927 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5928 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
5929as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5930
df48cfc7 5931# Send packet that should be rejected without logging.
d383eed5
JP
5932packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5933 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5934 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
5935as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5936
df48cfc7 5937# Send packet that should be rejected with logging.
d383eed5
JP
5938packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5939 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5940 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
5941as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5942
c1f272f9
NS
5943OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
5944
d383eed5
JP
5945AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
5946name="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
5947name="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
5948name="<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
5949name="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
5950])
5951
5952OVN_CLEANUP([hv])
5953AT_CLEANUP
5954
5955
1a03fc7d
BS
5956AT_SETUP([ovn -- DSCP marking check])
5957AT_KEYWORDS([ovn])
5958ovn_start
5959
5960ovn-nbctl ls-add lsw0
5961ovn-nbctl --wait=sb lsp-add lsw0 lp1
5962ovn-nbctl --wait=sb lsp-add lsw0 lp2
5963ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5964ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5965ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5966ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5967ovn-nbctl --wait=sb sync
5968net_add n1
5969sim_add hv
5970as hv
5971ovs-vsctl add-br br-phys
5972ovn_attach n1 br-phys 192.168.0.1
5973ovs-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
5974ovs-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
5975
5976AT_CAPTURE_FILE([trace])
5977ovn_trace () {
5978 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5979}
5980
5981# Extracts nw_tos from the final flow from ofproto/trace output and prints
5982# it on stdout. Prints "none" if no nw_tos was included.
5983get_final_nw_tos() {
5984 if flow=$(grep '^Final flow:' stdout); then :; else
5985 # The output didn't have a final flow.
5986 return 99
5987 fi
5988
5989 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5990 case $tos in
5991 '') echo none ;;
5992 *) echo $tos ;;
5993 esac
5994}
5995
5996# check_tos TOS
5997#
5998# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
5999check_tos() {
6000 # First check with ovn-trace for logical flows.
6001 echo "checking for tos $1"
6002 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6003 echo 'output("lp2");') > expout
6004 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])
6005
6006 # Then re-check with ofproto/trace for a physical packet.
6007 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])
6008 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6009])
6010}
6011
6012# check at L2
6013AT_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");
6014])
6015AT_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])
6016AT_CHECK([get_final_nw_tos], [0], [none
6017])
6018
6019# check at L3 without dscp marking
6020check_tos 0
6021
6022# Mark DSCP with a valid value
6023qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
6024check_tos 48
6025
6026# Update the DSCP marking
6027ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6028check_tos 63
6029
6030ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6031check_tos 63
6032
6033# Disable DSCP marking
6034ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
6035check_tos 0
6036
6037OVN_CLEANUP([hv])
57afd0c0 6038AT_CLEANUP
7fff4eb7
LR
6039
6040AT_SETUP([ovn -- read-only sb db:ptcp access])
6041AT_SKIP_IF([test $HAVE_PYTHON = no])
6042
6043: > .$1.db.~lock~
6044ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6045
6046# Add read-only remote to sb ovsdb-server
6047AT_CHECK(
6048 [ovsdb-tool transact ovn-sb.db \
6049 ['["OVN_Southbound",
6050 {"op": "insert",
6051 "table": "SB_Global",
6052 "row": {
6053 "connections": ["set", [["named-uuid", "xyz"]]]}},
6054 {"op": "insert",
6055 "table": "Connection",
6056 "uuid-name": "xyz",
6057 "row": {"target": "ptcp:0:127.0.0.1",
6058 "read_only": true}}]']], [0], [ignore], [ignore])
6059
6060start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6061
6062PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6063
6064# read-only accesses should succeed
6065AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6066AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6067
6068# write access should fail
6069AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6070[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6071])
6072
6073OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6074AT_CLEANUP
6075
6076AT_SETUP([ovn -- read-only sb db:pssl access])
6077AT_SKIP_IF([test $HAVE_PYTHON = no])
6078AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6079PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6080AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6081\\]"])
6082
6083: > .$1.db.~lock~
6084ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6085
6086# Add read-only remote to sb ovsdb-server
6087AT_CHECK(
6088 [ovsdb-tool transact ovn-sb.db \
6089 ['["OVN_Southbound",
6090 {"op": "insert",
6091 "table": "SB_Global",
6092 "row": {
6093 "connections": ["set", [["named-uuid", "xyz"]]]}},
6094 {"op": "insert",
6095 "table": "Connection",
6096 "uuid-name": "xyz",
6097 "row": {"target": "pssl:0:127.0.0.1",
6098 "read_only": true}}]']], [0], [ignore], [ignore])
6099
6100start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6101 --remote=db:OVN_Southbound,SB_Global,connections \
6102 --private-key="$PKIDIR/testpki-privkey2.pem" \
6103 --certificate="$PKIDIR/testpki-cert2.pem" \
6104 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6105 ovn-sb.db
6106
6107PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6108
6109# read-only accesses should succeed
6110AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6111 --private-key=$PKIDIR/testpki-privkey.pem \
6112 --certificate=$PKIDIR/testpki-cert.pem \
6113 --ca-cert=$PKIDIR/testpki-cacert.pem \
6114 list SB_Global], [0], [stdout], [ignore])
6115AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6116 --private-key=$PKIDIR/testpki-privkey.pem \
6117 --certificate=$PKIDIR/testpki-cert.pem \
6118 --ca-cert=$PKIDIR/testpki-cacert.pem \
6119 list Connection], [0], [stdout], [ignore])
6120
6121# write access should fail
6122AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6123 --private-key=$PKIDIR/testpki-privkey.pem \
6124 --certificate=$PKIDIR/testpki-cert.pem \
6125 --ca-cert=$PKIDIR/testpki-cacert.pem \
6126 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6127[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6128])
6129
6130OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6131AT_CLEANUP
6132
821302cf
LR
6133AT_SETUP([ovn -- nb connection/ssl commands])
6134AT_SKIP_IF([test $HAVE_PYTHON = no])
6135AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6136PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6137AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6138\\]"])
6139
6140: > .$1.db.~lock~
6141ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6142
6143# Start nb db server using db connection/ssl entries (unpopulated initially)
6144start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6145 --remote=db:OVN_Northbound,NB_Global,connections \
6146 --private-key=db:OVN_Northbound,SSL,private_key \
6147 --certificate=db:OVN_Northbound,SSL,certificate \
6148 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6149 ovn-nb.db
6150
6151# Populate SSL configuration entries in nb db
6152AT_CHECK(
6153 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6154 $PKIDIR/testpki-cert.pem \
6155 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6156
6157# Populate a passive SSL connection in nb db
6158AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6159
6160PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6161
6162# Verify SSL connetivity to nb db server
6163AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6164 --private-key=$PKIDIR/testpki-privkey.pem \
6165 --certificate=$PKIDIR/testpki-cert.pem \
6166 --ca-cert=$PKIDIR/testpki-cacert.pem \
6167 list NB_Global],
6168 [0], [stdout], [ignore])
6169AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6170 --private-key=$PKIDIR/testpki-privkey.pem \
6171 --certificate=$PKIDIR/testpki-cert.pem \
6172 --ca-cert=$PKIDIR/testpki-cacert.pem \
6173 list Connection],
6174 [0], [stdout], [ignore])
6175AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6176 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6177 --certificate=$PKIDIR/testpki-cert.pem \
6178 --ca-cert=$PKIDIR/testpki-cacert.pem \
6179 get-connection],
6180 [0], [stdout], [ignore])
6181
6182OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6183AT_CLEANUP
6184
6185AT_SETUP([ovn -- sb connection/ssl commands])
6186AT_SKIP_IF([test $HAVE_PYTHON = no])
6187AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6188PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6189AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6190\\]"])
6191
6192: > .$1.db.~lock~
6193ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6194
6195# Start sb db server using db connection/ssl entries (unpopulated initially)
6196start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6197 --remote=db:OVN_Southbound,SB_Global,connections \
6198 --private-key=db:OVN_Southbound,SSL,private_key \
6199 --certificate=db:OVN_Southbound,SSL,certificate \
6200 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6201 ovn-sb.db
6202
6203# Populate SSL configuration entries in sb db
6204AT_CHECK(
6205 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6206 $PKIDIR/testpki-cert.pem \
6207 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6208
6209# Populate a passive SSL connection in sb db
6210AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6211
6212PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6213
6214# Verify SSL connetivity to sb db server
6215AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6216 --private-key=$PKIDIR/testpki-privkey.pem \
6217 --certificate=$PKIDIR/testpki-cert.pem \
6218 --ca-cert=$PKIDIR/testpki-cacert.pem \
6219 list SB_Global],
6220 [0], [stdout], [ignore])
6221AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6222 --private-key=$PKIDIR/testpki-privkey.pem \
6223 --certificate=$PKIDIR/testpki-cert.pem \
6224 --ca-cert=$PKIDIR/testpki-cacert.pem \
6225 list Connection],
6226 [0], [stdout], [ignore])
6227AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6228 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
6229 --certificate=$PKIDIR/testpki-cert.pem \
6230 --ca-cert=$PKIDIR/testpki-cacert.pem \
6231 get-connection],
6232 [0], [stdout], [ignore])
6233
6234OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6235AT_CLEANUP
6236
75fd74f8
GS
6237AT_SETUP([ovn -- nested containers])
6238ovn_start
6239
6240# Physical network:
6241# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6242
6243# Logical network:
6244# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6245# and "bar" (192.168.2.0/24). They are all connected to router R1.
6246
6247ovn-nbctl lr-add R1
6248ovn-nbctl ls-add mgmt
6249ovn-nbctl ls-add foo
6250ovn-nbctl ls-add bar
6251
6252# Connect mgmt to R1
6253ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6254ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6255 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6256
6257# Connect foo to R1
6258ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6259ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6260 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6261
6262# Connect bar to R1
6263ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6264ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6265 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6266
6267# "mgmt" has VM1 and VM2 connected
6268ovn-nbctl lsp-add mgmt vm1 \
6269-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6270
6271ovn-nbctl lsp-add mgmt vm2 \
6272-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6273
6274# "foo1" and "foo2" are containers belonging to switch "foo"
6275# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6276ovn-nbctl lsp-add foo foo1 vm1 1 \
6277-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6278
6279ovn-nbctl lsp-add foo foo2 vm2 2 \
6280-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6281
6282# "bar1" and "bar2" are containers belonging to switch "bar"
6283# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6284ovn-nbctl lsp-add bar bar1 vm1 2 \
6285-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6286
6287ovn-nbctl lsp-add bar bar2 vm2 1 \
6288-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6289
6290# bar3 is a standalone VM belonging to switch "bar"
6291ovn-nbctl lsp-add bar bar3 \
6292-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6293
6294# Create two hypervisor and create OVS ports corresponding to logical ports.
6295net_add n1
6296
6297sim_add hv1
6298as hv1
6299ovs-vsctl add-br br-phys
6300ovn_attach n1 br-phys 192.168.0.1
6301ovs-vsctl -- add-port br-int vm1 -- \
6302 set interface vm1 external-ids:iface-id=vm1 \
6303 options:tx_pcap=hv1/vm1-tx.pcap \
6304 options:rxq_pcap=hv1/vm1-rx.pcap \
6305 ofport-request=1
6306
6307ovs-vsctl -- add-port br-int bar3 -- \
6308 set interface bar3 external-ids:iface-id=bar3 \
6309 options:tx_pcap=hv1/bar3-tx.pcap \
6310 options:rxq_pcap=hv1/bar3-rx.pcap \
6311 ofport-request=2
6312
6313sim_add hv2
6314as hv2
6315ovs-vsctl add-br br-phys
6316ovn_attach n1 br-phys 192.168.0.2
6317ovs-vsctl -- add-port br-int vm2 -- \
6318 set interface vm2 external-ids:iface-id=vm2 \
6319 options:tx_pcap=hv2/vm2-tx.pcap \
6320 options:rxq_pcap=hv2/vm2-rx.pcap \
6321 ofport-request=1
6322
6323# Pre-populate the hypervisors' ARP tables so that we don't lose any
6324# packets for ARP resolution (native tunneling doesn't queue packets
6325# for ARP resolution).
6326ovn_populate_arp
6327
6328# Allow some time for ovn-northd and ovn-controller to catch up.
6329# XXX This should be more systematic.
6330sleep 1
6331
6332ip_to_hex() {
6333 printf "%02x%02x%02x%02x" "$@"
6334}
6335
6336# Send ip packets between foo1 and foo2 (same switch, different HVs and
6337# different VLAN tags).
6338src_mac="f00000010205"
6339dst_mac="f00000010206"
6340src_ip=`ip_to_hex 192 168 1 2`
6341dst_ip=`ip_to_hex 192 168 1 3`
6342packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6343as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6344
6345# expected packet at foo2
6346packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6347echo $packet > expected
6348OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6349
6350# Send ip packets between foo1 and bar2 (different switch, different HV)
6351src_mac="f00000010205"
6352dst_mac="000000010203"
6353src_ip=`ip_to_hex 192 168 1 2`
6354dst_ip=`ip_to_hex 192 168 2 3`
6355packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6356as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6357
6358# expected packet at bar2
6359src_mac="000000010204"
6360dst_mac="f00000010208"
6361packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6362echo $packet >> expected
6363OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6364
6365# Send ip packets between foo1 and bar1
6366# (different switch, loopback to same vm but different tag)
6367src_mac="f00000010205"
6368dst_mac="000000010203"
6369src_ip=`ip_to_hex 192 168 1 2`
6370dst_ip=`ip_to_hex 192 168 2 2`
6371packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6372as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6373
6374# expected packet at bar1
6375src_mac="000000010204"
6376dst_mac="f00000010207"
6377packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6378echo $packet > expected1
6379OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6380
6381# Send ip packets between bar1 and bar3
6382# (same switch. But one is container and another is a standalone VM)
6383src_mac="f00000010207"
6384dst_mac="f00000010209"
6385src_ip=`ip_to_hex 192 168 2 2`
6386dst_ip=`ip_to_hex 192 168 2 3`
6387packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6388as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6389
6390# expected packet at bar3
6391packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6392echo $packet > expected
6393OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6394
6395# Send ip packets between foo1 and vm1.
6396(different switch, container to the VM hosting it.)
6397src_mac="f00000010205"
6398dst_mac="000000010203"
6399src_ip=`ip_to_hex 192 168 1 2`
6400dst_ip=`ip_to_hex 172 16 1 2`
6401packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6402as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6403
6404# expected packet at vm1
6405src_mac="000000010202"
6406dst_mac="f00000010203"
6407packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6408echo $packet >> expected1
6409OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6410
6411# Send packets from vm1 to bar1.
6412(different switch, A hosting VM to a container inside it)
6413src_mac="f00000010203"
6414dst_mac="000000010202"
6415src_ip=`ip_to_hex 172 16 1 2`
6416dst_ip=`ip_to_hex 192 168 2 2`
6417packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6418as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6419
6420# expected packet at vm1
6421src_mac="000000010204"
6422dst_mac="f00000010207"
6423packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6424echo $packet >> expected1
6425OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6426
6427OVN_CLEANUP([hv1],[hv2])
6428
6429AT_CLEANUP
440a9f4b
GS
6430
6431AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6432AT_SKIP_IF([test $HAVE_PYTHON = no])
6433ovn_start
6434
6435# Logical network:
6436# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6437# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6438# (192.168.2.0/24) connected to it.
6439#
6440# R2 and R3 are gateway routers.
6441# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6442# connected to it. Note how both alice and bob have the same subnet behind it.
6443# We are trying to simulate external network via those 2 switches. In real
6444# world the switch ports of these switches will have addresses set as "unknown"
6445# to make them learning switches. Or those switches will be "localnet" ones.
6446
6447# Create three hypervisors and create OVS ports corresponding to logical ports.
6448net_add n1
6449
6450sim_add hv1
6451as hv1
6452ovs-vsctl add-br br-phys
6453ovn_attach n1 br-phys 192.168.0.1
6454ovs-vsctl -- add-port br-int hv1-vif1 -- \
6455 set interface hv1-vif1 external-ids:iface-id=foo1 \
6456 options:tx_pcap=hv1/vif1-tx.pcap \
6457 options:rxq_pcap=hv1/vif1-rx.pcap \
6458 ofport-request=1
6459
6460ovs-vsctl -- add-port br-int hv1-vif2 -- \
6461 set interface hv1-vif2 external-ids:iface-id=bar1 \
6462 options:tx_pcap=hv1/vif2-tx.pcap \
6463 options:rxq_pcap=hv1/vif2-rx.pcap \
6464 ofport-request=2
6465
6466sim_add hv2
6467as hv2
6468ovs-vsctl add-br br-phys
6469ovn_attach n1 br-phys 192.168.0.2
6470ovs-vsctl -- add-port br-int hv2-vif1 -- \
6471 set interface hv2-vif1 external-ids:iface-id=alice1 \
6472 options:tx_pcap=hv2/vif1-tx.pcap \
6473 options:rxq_pcap=hv2/vif1-rx.pcap \
6474 ofport-request=1
6475
6476sim_add hv3
6477as hv3
6478ovs-vsctl add-br br-phys
6479ovn_attach n1 br-phys 192.168.0.3
6480ovs-vsctl -- add-port br-int hv3-vif1 -- \
6481 set interface hv3-vif1 external-ids:iface-id=bob1 \
6482 options:tx_pcap=hv3/vif1-tx.pcap \
6483 options:rxq_pcap=hv3/vif1-rx.pcap \
6484 ofport-request=1
6485
6486
6487ovn-nbctl create Logical_Router name=R1
6488ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6489ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6490
6491ovn-nbctl ls-add foo
6492ovn-nbctl ls-add bar
6493ovn-nbctl ls-add alice
6494ovn-nbctl ls-add bob
6495ovn-nbctl ls-add join
6496
6497# Connect foo to R1
6498ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6499ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6500 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6501
6502# Connect bar to R1
6503ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6504ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6505 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6506
6507# Connect alice to R2
6508ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6509ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6510 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6511
6512# Connect bob to R3
6513ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6514ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6515 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6516
6517# Connect R1 to join
6518ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6519ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6520 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6521
6522# Connect R2 to join
6523ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6524ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6525 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6526
6527# Connect R3 to join
6528ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6529ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6530 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6531
6532# Install static routes with source ip address as the policy for routing.
6533# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6534ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6535ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6536
6537# Install static routes with destination ip address as the policy for routing.
6538ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6539
6540ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6541
6542# Create logical port foo1 in foo
6543ovn-nbctl lsp-add foo foo1 \
6544-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6545
6546# Create logical port bar1 in bar
6547ovn-nbctl lsp-add bar bar1 \
6548-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6549
6550# Create logical port alice1 in alice
6551ovn-nbctl lsp-add alice alice1 \
6552-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6553
6554# Create logical port bob1 in bob
6555ovn-nbctl lsp-add bob bob1 \
6556-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6557
6558# Pre-populate the hypervisors' ARP tables so that we don't lose any
6559# packets for ARP resolution (native tunneling doesn't queue packets
6560# for ARP resolution).
6561ovn_populate_arp
6562
6563# Allow some time for ovn-northd and ovn-controller to catch up.
6564# XXX This should be more systematic.
6565sleep 1
6566
6567ip_to_hex() {
6568 printf "%02x%02x%02x%02x" "$@"
6569}
6570trim_zeros() {
6571 sed 's/\(00\)\{1,\}$//'
6572}
6573
6574# Send ip packets between foo1 and bar1
6575# (East-west traffic should flow normally)
6576src_mac="f00000010203"
6577dst_mac="000001010203"
6578src_ip=`ip_to_hex 192 168 1 2`
6579dst_ip=`ip_to_hex 192 168 2 2`
6580packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6581as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6582
6583# Send ip packets between foo1 and alice1
6584src_mac="f00000010203"
6585dst_mac="000001010203"
6586src_ip=`ip_to_hex 192 168 1 2`
6587dst_ip=`ip_to_hex 172 16 1 3`
6588packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6589as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 6590as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
6591
6592# Send ip packets between bar1 and bob1
6593src_mac="f00000010204"
6594dst_mac="000001010204"
6595src_ip=`ip_to_hex 192 168 2 2`
6596dst_ip=`ip_to_hex 172 16 1 4`
6597packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6598as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6599#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6600
6601# Packet to expect at bar1
6602src_mac="000001010204"
6603dst_mac="f00000010204"
6604src_ip=`ip_to_hex 192 168 1 2`
6605dst_ip=`ip_to_hex 192 168 2 2`
6606expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6607echo $expected > expected
6608OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6609
6610# Packet to Expect at alice1
6611src_mac="000002010203"
6612dst_mac="f00000010205"
6613src_ip=`ip_to_hex 192 168 1 2`
6614dst_ip=`ip_to_hex 172 16 1 3`
6615expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6616echo $expected > expected
6617OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6618
6619# Packet to Expect at bob1
6620src_mac="000003010203"
6621dst_mac="f00000010206"
6622src_ip=`ip_to_hex 192 168 2 2`
6623dst_ip=`ip_to_hex 172 16 1 4`
6624expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6625echo $expected > expected
6626OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6627
6628for sim in hv1 hv2 hv3; do
6629 as $sim
6630 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6631 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6632 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6633done
6634
6635as ovn-sb
6636OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6637
6638as ovn-nb
6639OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6640
6641as northd
6642OVS_APP_EXIT_AND_WAIT([ovn-northd])
6643
6644as main
6645OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6646OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6647
6648AT_CLEANUP
41a15b71 6649
302eda27
NS
6650AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6651AT_SKIP_IF([test $HAVE_PYTHON = no])
6652ovn_start
6653
6654ovn-nbctl ls-add ls1
6655
6656ovn-nbctl lsp-add ls1 ls1-lp1 \
6657-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6658
6659ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6660
6661ovn-nbctl lsp-add ls1 ls1-lp2 \
6662-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6663
6664ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6665
6666DNS1=`ovn-nbctl create DNS records={}`
6667DNS2=`ovn-nbctl create DNS records={}`
6668
6669ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6670ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6671ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6672
6673ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6674
6675net_add n1
6676sim_add hv1
6677
6678as hv1
6679ovs-vsctl add-br br-phys
6680ovn_attach n1 br-phys 192.168.0.1
6681ovs-vsctl -- add-port br-int hv1-vif1 -- \
6682 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6683 options:tx_pcap=hv1/vif1-tx.pcap \
6684 options:rxq_pcap=hv1/vif1-rx.pcap \
6685 ofport-request=1
6686
6687ovs-vsctl -- add-port br-int hv1-vif2 -- \
6688 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6689 options:tx_pcap=hv1/vif2-tx.pcap \
6690 options:rxq_pcap=hv1/vif2-rx.pcap \
6691 ofport-request=2
6692
6693ovn_populate_arp
6694sleep 2
6695as hv1 ovs-vsctl show
6696
6697echo "*************************"
6698ovn-sbctl list DNS
6699echo "*************************"
6700
6701ip_to_hex() {
6702 printf "%02x%02x%02x%02x" "$@"
6703}
6704
6705reset_pcap_file() {
6706 local iface=$1
6707 local pcap_file=$2
6708 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6709options:rxq_pcap=dummy-rx.pcap
6710 rm -f ${pcap_file}*.pcap
6711 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6712options:rxq_pcap=${pcap_file}-rx.pcap
6713}
6714
6715# set_dns_params host_name
6716# Sets the dns_req_data and dns_resp_data
6717set_dns_params() {
6718 local hname=$1
6719 local ttl=00000e10
6720 an_count=0001
6721 type=0001
6722 case $hname in
6723 vm1)
6724 # vm1.ovn.org
6725 query_name=03766d31036f766e036f726700
6726 # IPv4 address - 10.0.0.4
6727 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6728 ;;
6729 vm2)
6730 # vm2.ovn.org
6731 query_name=03766d32036f766e036f726700
6732 # IPv4 address - 10.0.0.6
6733 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6734 # IPv4 address - 20.0.0.4
6735 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6736 an_count=0002
6737 ;;
6738 vm3)
6739 # vm3.ovn.org
6740 query_name=03766d33036f766e036f726700
6741 # IPv4 address - 40.0.0.4
6742 expected_dns_answer=${query_name}00010001${ttl}000428000004
6743 ;;
6744 vm1_ipv6_only)
6745 # vm1.ovn.org
6746 query_name=03766d31036f766e036f726700
6747 # IPv6 address - aef0::4
6748 type=001c
6749 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6750 ;;
6751 vm1_ipv4_v6)
6752 # vm1.ovn.org
6753 query_name=03766d31036f766e036f726700
6754 type=00ff
6755 an_count=0002
6756 # IPv4 address - 10.0.0.4
6757 # IPv6 address - aef0::4
6758 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6759 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
6760 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
6761 ;;
6762 vm1_invalid_type)
6763 # vm1.ovn.org
6764 query_name=03766d31036f766e036f726700
6765 # IPv6 address - aef0::4
6766 type=0002
6767 ;;
6768 vm1_incomplete)
6769 # set type to none
6770 type=''
6771 esac
6772 # TTL - 3600
6773 local dns_req_header=010201200001000000000000
6774 local dns_resp_header=010281200001${an_count}00000000
6775 dns_req_data=${dns_req_header}${query_name}${type}0001
6776 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
6777}
6778
6779# This shell function sends a DNS request packet
6780# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
6781test_dns() {
6782 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6783 local dns_query_data=$7
6784 shift; shift; shift; shift; shift; shift; shift;
6785 # Packet size => IPv4 header (20) + UDP header (8) +
6786 # DNS data (header + query)
6787 ip_len=`expr 28 + ${#dns_query_data} / 2`
6788 udp_len=`expr $ip_len - 20`
6789 ip_len=$(printf "%x" $ip_len)
6790 udp_len=$(printf "%x" $udp_len)
6791 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
6792 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
6793 # dns data
6794 request=${request}${dns_query_data}
6795
6796 if test $dns_reply != 0; then
6797 local dns_reply=$1
6798 ip_len=`expr 28 + ${#dns_reply} / 2`
6799 udp_len=`expr $ip_len - 20`
6800 ip_len=$(printf "%x" $ip_len)
6801 udp_len=$(printf "%x" $udp_len)
6802 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
6803 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
6804 echo $reply >> $inport.expected
6805 else
6806 for outport; do
6807 echo $request >> $outport.expected
6808 done
6809 fi
6810 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6811}
6812
6813AT_CAPTURE_FILE([ofctl_monitor0.log])
6814as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
6815--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
6816
6817set_dns_params vm2
6818src_ip=`ip_to_hex 10 0 0 4`
6819dst_ip=`ip_to_hex 10 0 0 1`
6820dns_reply=1
6821test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6822
6823# NXT_RESUMEs should be 1.
6824OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6825
6826$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6827cat 1.expected | cut -c -48 > expout
6828AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6829# Skipping the IPv4 checksum.
6830cat 1.expected | cut -c 53- > expout
6831AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6832
6833reset_pcap_file hv1-vif1 hv1/vif1
6834reset_pcap_file hv1-vif2 hv1/vif2
6835rm -f 1.expected
6836rm -f 2.expected
6837
6838set_dns_params vm1
6839src_ip=`ip_to_hex 10 0 0 6`
6840dst_ip=`ip_to_hex 10 0 0 1`
6841dns_reply=1
6842test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6843
6844# NXT_RESUMEs should be 2.
6845OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6846
6847$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6848cat 2.expected | cut -c -48 > expout
6849AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6850# Skipping the IPv4 checksum.
6851cat 2.expected | cut -c 53- > expout
6852AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6853
6854reset_pcap_file hv1-vif1 hv1/vif1
6855reset_pcap_file hv1-vif2 hv1/vif2
6856rm -f 1.expected
6857rm -f 2.expected
6858
6859# Clear the query name options for ls1-lp2
6860ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
6861
6862set_dns_params vm2
6863src_ip=`ip_to_hex 10 0 0 4`
6864dst_ip=`ip_to_hex 10 0 0 1`
6865dns_reply=0
6866test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
6867
6868# NXT_RESUMEs should be 3.
6869OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6870
6871$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6872AT_CHECK([cat 1.packets], [0], [])
6873
6874reset_pcap_file hv1-vif1 hv1/vif1
6875reset_pcap_file hv1-vif2 hv1/vif2
6876rm -f 1.expected
6877rm -f 2.expected
6878
6879# Clear the query name for ls1-lp1
6880# Since ls1 has no query names configued,
6881# ovn-northd should not add the DNS flows.
6882ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
6883
6884set_dns_params vm1
6885src_ip=`ip_to_hex 10 0 0 6`
6886dst_ip=`ip_to_hex 10 0 0 1`
6887dns_reply=0
6888test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6889
6890# NXT_RESUMEs should be 3 only.
6891OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6892
6893$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6894AT_CHECK([cat 2.packets], [0], [])
6895
6896reset_pcap_file hv1-vif1 hv1/vif1
6897reset_pcap_file hv1-vif2 hv1/vif2
6898rm -f 1.expected
6899rm -f 2.expected
6900
6901# Test IPv6 (AAAA records) using IPv4 packet.
6902# Add back the DNS options for ls1-lp1.
6903ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6904
6905set_dns_params vm1_ipv6_only
6906src_ip=`ip_to_hex 10 0 0 6`
6907dst_ip=`ip_to_hex 10 0 0 1`
6908dns_reply=1
6909test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6910
6911# NXT_RESUMEs should be 4.
6912OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6913
6914$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6915cat 2.expected | cut -c -48 > expout
6916AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6917# Skipping the IPv4 checksum.
6918cat 2.expected | cut -c 53- > expout
6919AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6920
6921reset_pcap_file hv1-vif1 hv1/vif1
6922reset_pcap_file hv1-vif2 hv1/vif2
6923rm -f 1.expected
6924rm -f 2.expected
6925
6926# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
6927set_dns_params vm1_ipv4_v6
6928src_ip=`ip_to_hex 10 0 0 6`
6929dst_ip=`ip_to_hex 10 0 0 1`
6930dns_reply=1
6931test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6932
6933# NXT_RESUMEs should be 5.
6934OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6935
6936$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6937cat 2.expected | cut -c -48 > expout
6938AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6939# Skipping the IPv4 checksum.
6940cat 2.expected | cut -c 53- > expout
6941AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6942
6943reset_pcap_file hv1-vif1 hv1/vif1
6944reset_pcap_file hv1-vif2 hv1/vif2
6945rm -f 1.expected
6946rm -f 2.expected
6947
6948# Invalid type.
6949set_dns_params vm1_invalid_type
6950src_ip=`ip_to_hex 10 0 0 6`
6951dst_ip=`ip_to_hex 10 0 0 1`
6952dns_reply=0
6953test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6954
6955# NXT_RESUMEs should be 6.
6956OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6957
6958$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6959AT_CHECK([cat 2.packets], [0], [])
6960
6961reset_pcap_file hv1-vif1 hv1/vif1
6962reset_pcap_file hv1-vif2 hv1/vif2
6963rm -f 1.expected
6964rm -f 2.expected
6965
6966# Incomplete DNS packet.
6967set_dns_params vm1_incomplete
6968src_ip=`ip_to_hex 10 0 0 6`
6969dst_ip=`ip_to_hex 10 0 0 1`
6970dns_reply=0
6971test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6972
6973# NXT_RESUMEs should be 7.
6974OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6975
6976$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6977AT_CHECK([cat 2.packets], [0], [])
6978
6979reset_pcap_file hv1-vif1 hv1/vif1
6980reset_pcap_file hv1-vif2 hv1/vif2
6981rm -f 1.expected
6982rm -f 2.expected
6983
6984# Add one more DNS record to the ls1.
6985ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
6986
6987set_dns_params vm3
6988src_ip=`ip_to_hex 10 0 0 4`
6989dst_ip=`ip_to_hex 10 0 0 1`
6990dns_reply=1
6991test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6992
6993# NXT_RESUMEs should be 8.
6994OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6995
6996$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6997cat 1.expected | cut -c -48 > expout
6998AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6999# Skipping the IPv4 checksum.
7000cat 1.expected | cut -c 53- > expout
7001AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7002
7003reset_pcap_file hv1-vif1 hv1/vif1
7004reset_pcap_file hv1-vif2 hv1/vif2
7005rm -f 1.expected
7006rm -f 2.expected
7007
7008as hv1
7009 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7010OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7011OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7012
7013as ovn-sb
7014OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7015
7016as ovn-nb
7017OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7018
7019as northd
7020OVS_APP_EXIT_AND_WAIT([ovn-northd])
7021
7022as main
7023OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7024OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7025AT_CLEANUP
7026
75f9e007 7027AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 7028AT_SKIP_IF([test $HAVE_PYTHON = no])
7029ovn_start
7030
7031net_add n1
7032
7033sim_add hv1
7034as hv1
7035ovs-vsctl add-br br-phys
7036ovn_attach n1 br-phys 192.168.0.1
7037ovs-vsctl -- add-port br-int hv1-vif1 -- \
7038 set interface hv1-vif1 external-ids:iface-id=foo1 \
7039 options:tx_pcap=hv1/vif1-tx.pcap \
7040 options:rxq_pcap=hv1/vif1-rx.pcap \
7041 ofport-request=1
7042
7043sim_add gw1
7044as gw1
7045ovs-vsctl add-br br-phys
7046ovn_attach n1 br-phys 192.168.0.2
7047
7048sim_add gw2
7049as gw2
7050ovs-vsctl add-br br-phys
7051ovn_attach n1 br-phys 192.168.0.4
7052
7053sim_add ext1
7054as ext1
7055ovs-vsctl add-br br-phys
7056ovn_attach n1 br-phys 192.168.0.3
7057ovs-vsctl -- add-port br-int ext1-vif1 -- \
7058 set interface ext1-vif1 external-ids:iface-id=outside1 \
7059 options:tx_pcap=ext1/vif1-tx.pcap \
7060 options:rxq_pcap=ext1/vif1-rx.pcap \
7061 ofport-request=1
7062
7063# Pre-populate the hypervisors' ARP tables so that we don't lose any
7064# packets for ARP resolution (native tunneling doesn't queue packets
7065# for ARP resolution).
7066ovn_populate_arp
7067
7068ovn-nbctl create Logical_Router name=R1
7069
7070ovn-nbctl ls-add foo
7071ovn-nbctl ls-add alice
7072ovn-nbctl ls-add outside
7073
7074# Connect foo to R1
7075ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7076ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7077 type=router options:router-port=foo \
7078 -- lsp-set-addresses rp-foo router
7079
7080# Connect alice to R1 as distributed router gateway port on gw1
7081ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7082
7083ovn-nbctl \
7084 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7085 chassis_name=gw1 \
7086 priority=20 -- \
7087 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7088 chassis_name=gw2 \
7089 priority=10 -- \
7090 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7091
7092ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7093 type=router options:router-port=alice \
7094 -- lsp-set-addresses rp-alice router
7095
7096# Create logical port foo1 in foo
7097ovn-nbctl lsp-add foo foo1 \
7098-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7099
7100# Create logical port outside1 in outside
7101ovn-nbctl lsp-add outside outside1 \
7102-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7103
7104# Create localnet port in alice
7105ovn-nbctl lsp-add alice ln-alice
7106ovn-nbctl lsp-set-addresses ln-alice unknown
7107ovn-nbctl lsp-set-type ln-alice localnet
7108ovn-nbctl lsp-set-options ln-alice network_name=phys
7109
7110# Create localnet port in outside
7111ovn-nbctl lsp-add outside ln-outside
7112ovn-nbctl lsp-set-addresses ln-outside unknown
7113ovn-nbctl lsp-set-type ln-outside localnet
7114ovn-nbctl lsp-set-options ln-outside network_name=phys
7115
7116# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7117# mapping to the external network, is the one generating packets
7118as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7119as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7120as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7121
7122AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7123
7124# Allow some time for ovn-northd and ovn-controller to catch up.
7125# XXX This should be more systematic.
7126sleep 2
7127
7128ip_to_hex() {
7129 printf "%02x%02x%02x%02x" "$@"
7130}
7131
7132reset_pcap_file() {
7133 local iface=$1
7134 local pcap_file=$2
7135 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7136options:rxq_pcap=dummy-rx.pcap
7137 rm -f ${pcap_file}*.pcap
7138 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7139options:rxq_pcap=${pcap_file}-rx.pcap
7140}
7141
7142test_ip_packet()
7143{
7144 local active_gw=$1
7145 local backup_gw=$2
7146
7147 # Send ip packet between foo1 and outside1
7148 src_mac="f00000010203" # foo1 mac
7149 dst_mac="000001010203" # rp-foo mac (internal router leg)
7150 src_ip=`ip_to_hex 192 168 1 2`
7151 dst_ip=`ip_to_hex 172 16 1 3`
7152 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7153
7154 # ARP request packet to expect at outside1
7155 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7156
7157 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7158
7159 # Send ARP reply from outside1 back to the router
7160 # XXX: note, we could avoid this if we plug this port into a netns
7161 # and setup the IP address into the port, so the kernel would simply reply
7162 src_mac="000002010203"
7163 reply_mac="f00000010204"
7164 dst_ip=`ip_to_hex 172 16 1 3`
7165 src_ip=`ip_to_hex 172 16 1 1`
7166 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7167
7168 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7169
7170 # Packet to Expect at ext1 chassis, outside1 port
7171 src_mac="000002010203"
7172 dst_mac="f00000010204"
7173 src_ip=`ip_to_hex 192 168 1 2`
7174 dst_ip=`ip_to_hex 172 16 1 3`
7175 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7176 echo $expected > ext1-vif1.expected
7177
7178 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7179 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7180 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7181
7182 # Resend packet from foo1 to outside1
7183 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7184
7185 sleep 1
7186
7187 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7188 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7189 AT_CHECK([grep $expected packets | sort], [0], [expout])
7190 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7191 AT_CHECK([grep $expected packets | sort], [0], [])
7192}
7193
7194test_ip_packet gw1 gw2
7195
75f9e007
GZ
7196ovn-nbctl --timeout=3 --wait=hv \
7197 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7198 chassis_name=gw1 \
7199 priority=10 -- \
7200 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7201 chassis_name=gw2 \
7202 priority=20 -- \
7203 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7204
7205test_ip_packet gw2 gw1
7206
7207OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7208AT_CLEANUP
7209
7210AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7211AT_SKIP_IF([test $HAVE_PYTHON = no])
7212ovn_start
7213
7214net_add n1
7215
7216sim_add hv1
7217as hv1
7218ovs-vsctl add-br br-phys
7219ovn_attach n1 br-phys 192.168.0.1
7220ovs-vsctl -- add-port br-int hv1-vif1 -- \
7221 set interface hv1-vif1 external-ids:iface-id=foo1 \
7222 options:tx_pcap=hv1/vif1-tx.pcap \
7223 options:rxq_pcap=hv1/vif1-rx.pcap \
7224 ofport-request=1
7225
7226sim_add gw1
7227as gw1
7228ovs-vsctl add-br br-phys
7229ovn_attach n1 br-phys 192.168.0.2
7230
7231sim_add gw2
7232as gw2
7233ovs-vsctl add-br br-phys
7234ovn_attach n1 br-phys 192.168.0.4
7235
7236sim_add ext1
7237as ext1
7238ovs-vsctl add-br br-phys
7239ovn_attach n1 br-phys 192.168.0.3
7240ovs-vsctl -- add-port br-int ext1-vif1 -- \
7241 set interface ext1-vif1 external-ids:iface-id=outside1 \
7242 options:tx_pcap=ext1/vif1-tx.pcap \
7243 options:rxq_pcap=ext1/vif1-rx.pcap \
7244 ofport-request=1
7245
7246# Pre-populate the hypervisors' ARP tables so that we don't lose any
7247# packets for ARP resolution (native tunneling doesn't queue packets
7248# for ARP resolution).
7249ovn_populate_arp
7250
7251ovn-nbctl create Logical_Router name=R0
7252ovn-nbctl create Logical_Router name=R1
7253
7254ovn-nbctl ls-add foo
7255ovn-nbctl ls-add join
7256ovn-nbctl ls-add alice
7257ovn-nbctl ls-add outside
7258
7259#Connect foo to R0
7260ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7261ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7262 type=router options:router-port=R0-foo \
7263 -- lsp-set-addresses foo-R0 router
7264
7265#Connect R0 to join
7266ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7267ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7268 type=router options:router-port=R0-join \
7269 -- lsp-set-addresses join-R0 router
7270
7271#Connect join to R1
7272ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7273ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7274 type=router options:router-port=R1-join \
7275 -- lsp-set-addresses join-R1 router
7276
7277#add route rules
7278ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7279ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7280
7281# Connect alice to R1 as distributed router gateway port on gw1
7282ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7283
7284ovn-nbctl \
7285 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7286 chassis_name=gw1 \
7287 priority=20 -- \
7288 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7289 chassis_name=gw2 \
7290 priority=10 -- \
7291 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7292
7293ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7294 type=router options:router-port=alice \
7295 -- lsp-set-addresses rp-alice router
7296
7297# Create logical port foo1 in foo
7298ovn-nbctl lsp-add foo foo1 \
7299-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7300
7301# Create logical port outside1 in outside
7302ovn-nbctl lsp-add outside outside1 \
7303-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7304
7305# Create localnet port in alice
7306ovn-nbctl lsp-add alice ln-alice
7307ovn-nbctl lsp-set-addresses ln-alice unknown
7308ovn-nbctl lsp-set-type ln-alice localnet
7309ovn-nbctl lsp-set-options ln-alice network_name=phys
7310
7311# Create localnet port in outside
7312ovn-nbctl lsp-add outside ln-outside
7313ovn-nbctl lsp-set-addresses ln-outside unknown
7314ovn-nbctl lsp-set-type ln-outside localnet
7315ovn-nbctl lsp-set-options ln-outside network_name=phys
7316
7317# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7318# mapping to the external network, is the one generating packets
7319as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7320as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7321as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7322
7323AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7324
7325# Allow some time for ovn-northd and ovn-controller to catch up.
7326# XXX This should be more systematic.
7327sleep 2
7328
7329ip_to_hex() {
7330 printf "%02x%02x%02x%02x" "$@"
7331}
7332
7333reset_pcap_file() {
7334 local iface=$1
7335 local pcap_file=$2
7336 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7337options:rxq_pcap=dummy-rx.pcap
7338 rm -f ${pcap_file}*.pcap
7339 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7340options:rxq_pcap=${pcap_file}-rx.pcap
7341}
7342
7343test_ip_packet()
7344{
7345 local active_gw=$1
7346 local backup_gw=$2
7347
7348 # Send ip packet between foo1 and outside1
7349 src_mac="f00000010203" # foo1 mac
7350 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7351 src_ip=`ip_to_hex 192 168 1 2`
7352 dst_ip=`ip_to_hex 172 16 1 3`
7353 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7354
7355 # ARP request packet to expect at outside1
7356 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7357
7358 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7359
7360 # Send ARP reply from outside1 back to the router
7361 # XXX: note, we could avoid this if we plug this port into a netns
7362 # and setup the IP address into the port, so the kernel would simply reply
7363 src_mac="000002010203"
7364 reply_mac="f00000010204"
7365 dst_ip=`ip_to_hex 172 16 1 3`
7366 src_ip=`ip_to_hex 172 16 1 1`
7367 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7368
7369 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7370
7371 # Packet to Expect at ext1 chassis, outside1 port
7372 src_mac="000002010203"
7373 dst_mac="f00000010204"
7374 src_ip=`ip_to_hex 192 168 1 2`
7375 dst_ip=`ip_to_hex 172 16 1 3`
7376 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7377 echo $expected > ext1-vif1.expected
7378
7379 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7380 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7381 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7382
7383 # Resend packet from foo1 to outside1
7384 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7385
7386 sleep 1
7387
7388 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7389 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7390 AT_CHECK([grep $expected packets | sort], [0], [expout])
7391 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7392 AT_CHECK([grep $expected packets | sort], [0], [])
7393}
7394
7395test_ip_packet gw1 gw2
7396
8e1d9349 7397ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 7398 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7399 chassis_name=gw1 \
7400 priority=10 -- \
7401 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7402 chassis_name=gw2 \
7403 priority=20 -- \
7404 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7405
7406test_ip_packet gw2 gw1
7407
7408OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7409AT_CLEANUP
7410
41a15b71
MS
7411AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7412AT_SKIP_IF([test $HAVE_PYTHON = no])
7413ovn_start
7414
7415# Logical network:
7416# One LR R1 that has switches foo (192.168.1.0/24) and
7417# alice (172.16.1.0/24) connected to it. The logical port
7418# between R1 and alice has a "redirect-chassis" specified,
7419# i.e. it is the distributed router gateway port.
7420# Switch alice also has a localnet port defined.
7421# An additional switch outside has a localnet port and the
7422# same subnet as alice (172.16.1.0/24).
7423
7424# Physical network:
7425# Three hypervisors hv[123].
7426# hv1 hosts vif foo1.
7427# hv2 is the "redirect-chassis" that hosts the distributed
7428# router gateway port.
7429# hv3 hosts vif outside1.
7430# In order to show that connectivity works only through hv2,
7431# an initial round of tests is run without any bridge-mapping
7432# defined for the localnet on hv2. These tests are expected
7433# to fail.
7434# Subsequent tests are run after defining the bridge-mapping
7435# for the localnet on hv2. These tests are expected to succeed.
7436
7437# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 7438# to logical ports.
41a15b71
MS
7439net_add n1
7440
7441sim_add hv1
7442as hv1
7443ovs-vsctl add-br br-phys
7444ovn_attach n1 br-phys 192.168.0.1
7445ovs-vsctl -- add-port br-int hv1-vif1 -- \
7446 set interface hv1-vif1 external-ids:iface-id=foo1 \
7447 options:tx_pcap=hv1/vif1-tx.pcap \
7448 options:rxq_pcap=hv1/vif1-rx.pcap \
7449 ofport-request=1
7450
7451sim_add hv2
7452as hv2
7453ovs-vsctl add-br br-phys
7454ovn_attach n1 br-phys 192.168.0.2
7455
7456sim_add hv3
7457as hv3
7458ovs-vsctl add-br br-phys
7459ovn_attach n1 br-phys 192.168.0.3
7460ovs-vsctl -- add-port br-int hv3-vif1 -- \
7461 set interface hv3-vif1 external-ids:iface-id=outside1 \
7462 options:tx_pcap=hv3/vif1-tx.pcap \
7463 options:rxq_pcap=hv3/vif1-rx.pcap \
7464 ofport-request=1
7465
7466# Pre-populate the hypervisors' ARP tables so that we don't lose any
7467# packets for ARP resolution (native tunneling doesn't queue packets
7468# for ARP resolution).
7469ovn_populate_arp
7470
7471ovn-nbctl create Logical_Router name=R1
7472
7473ovn-nbctl ls-add foo
7474ovn-nbctl ls-add alice
7475ovn-nbctl ls-add outside
7476
7477# Connect foo to R1
7478ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7479ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7480 type=router options:router-port=foo \
7481 -- lsp-set-addresses rp-foo router
7482
7483# Connect alice to R1 as distributed router gateway port on hv2
7484ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7485 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7486ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7487 type=router options:router-port=alice \
7488 -- lsp-set-addresses rp-alice router
7489
7490# Create logical port foo1 in foo
7491ovn-nbctl lsp-add foo foo1 \
7492-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7493
7494# Create logical port outside1 in outside
7495ovn-nbctl lsp-add outside outside1 \
7496-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7497
7498# Create localnet port in alice
7499ovn-nbctl lsp-add alice ln-alice
7500ovn-nbctl lsp-set-addresses ln-alice unknown
7501ovn-nbctl lsp-set-type ln-alice localnet
7502ovn-nbctl lsp-set-options ln-alice network_name=phys
7503
7504# Create localnet port in outside
7505ovn-nbctl lsp-add outside ln-outside
7506ovn-nbctl lsp-set-addresses ln-outside unknown
7507ovn-nbctl lsp-set-type ln-outside localnet
7508ovn-nbctl lsp-set-options ln-outside network_name=phys
7509
7510# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7511as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7512as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7513
7514
7515# Allow some time for ovn-northd and ovn-controller to catch up.
7516# XXX This should be more systematic.
7517sleep 2
7518
7519echo "---------NB dump-----"
7520ovn-nbctl show
7521echo "---------------------"
7522ovn-nbctl list logical_router
7523echo "---------------------"
7524ovn-nbctl list logical_router_port
7525echo "---------------------"
7526
7527echo "---------SB dump-----"
7528ovn-sbctl list datapath_binding
7529echo "---------------------"
7530ovn-sbctl list port_binding
7531echo "---------------------"
7532ovn-sbctl dump-flows
7533echo "---------------------"
7534ovn-sbctl list chassis
7535ovn-sbctl list encap
1da17a0b 7536echo "------ Gateway_Chassis dump (SBDB) -------"
7537ovn-sbctl list Gateway_Chassis
7538echo "------ Port_Binding chassisredirect -------"
7539ovn-sbctl find Port_Binding type=chassisredirect
7540echo "-------------------------------------------"
41a15b71
MS
7541
7542echo "------ hv1 dump ----------"
7543as hv1 ovs-ofctl show br-int
7544as hv1 ovs-ofctl dump-flows br-int
7545echo "------ hv2 dump ----------"
7546as hv2 ovs-ofctl show br-int
7547as hv2 ovs-ofctl dump-flows br-int
7548echo "------ hv3 dump ----------"
7549as hv3 ovs-ofctl show br-int
7550as hv3 ovs-ofctl dump-flows br-int
7551echo "--------------------------"
7552
1da17a0b 7553
41a15b71
MS
7554# Check that redirect mapping is programmed only on hv2
7555AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7556])
7557AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7558])
7559# Check that hv1 sends chassisredirect port traffic to hv2
7560AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7561])
7562AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7563])
7564# Check that arp reply on distributed gateway port is only programmed on hv2
7565AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7566])
7567AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7568])
7569
7570
7571ip_to_hex() {
7572 printf "%02x%02x%02x%02x" "$@"
7573}
7574
7575
7576: > hv2-vif1.expected
7577: > hv3-vif1.expected
7578
7579# test_arp INPORT SHA SPA TPA [REPLY_HA]
7580#
7581# Causes a packet to be received on INPORT. The packet is an ARP
7582# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7583# it should be the hardware address of the target to expect to receive in an
7584# ARP reply; otherwise no reply is expected.
7585#
7586# INPORT is an logical switch port number, e.g. 11 for vif11.
7587# SHA and REPLY_HA are each 12 hex digits.
7588# SPA and TPA are each 8 hex digits.
7589test_arp() {
7590 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7591 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7592 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7593
7594 if test X$reply_ha != X; then
7595 # Expect to receive the reply, if any.
7596 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7597 echo $reply >> hv${hv}-vif$inport.expected
7598 fi
7599}
7600
7601rtr_ip=$(ip_to_hex 172 16 1 1)
7602foo_ip=$(ip_to_hex 192 168 1 2)
7603outside_ip=$(ip_to_hex 172 16 1 3)
7604
7605echo $rtr_ip
7606echo $foo_ip
7607echo $outside_ip
7608
7609# ARP for router IP address from outside1, no response expected
7610test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7611
7612# Now check the packets actually received against the ones expected.
7613OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7614
7615# Send ip packet between foo1 and outside1
7616src_mac="f00000010203"
7617dst_mac="000001010203"
7618src_ip=`ip_to_hex 192 168 1 2`
7619dst_ip=`ip_to_hex 172 16 1 3`
7620packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7621
7622# Now check the packets actually received against the ones expected.
7623OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7624
7625# Now add bridge-mappings on hv2, which should make everything work
7626as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7627
7628# Allow some time for ovn-northd and ovn-controller to catch up.
7629# XXX This should be more systematic.
7630sleep 2
7631
7632# ARP for router IP address from outside1
7633test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7634
7635# Now check the packets actually received against the ones expected.
7636OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7637
7638# Send ip packet between foo1 and outside1
7639src_mac="f00000010203"
7640dst_mac="000001010203"
7641src_ip=`ip_to_hex 192 168 1 2`
7642dst_ip=`ip_to_hex 172 16 1 3`
7643packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7644
7645# ARP request packet to expect at outside1
7646src_mac="000002010203"
7647src_ip=`ip_to_hex 172 16 1 1`
7648arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7649
7650as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7651
7652echo $arp_request >> hv3-vif1.expected
7653OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7654
7655# Send ARP reply from outside1 back to the router
7656reply_mac="f00000010204"
7657arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7658
7659as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7660
7661# Allow some time for ovn-northd and ovn-controller to catch up.
7662# XXX This should be more systematic.
7663sleep 1
7664
7665# Packet to Expect at outside1
7666src_mac="000002010203"
7667dst_mac="f00000010204"
7668src_ip=`ip_to_hex 192 168 1 2`
7669dst_ip=`ip_to_hex 172 16 1 3`
7670expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7671
7672# Resend packet from foo1 to outside1
7673as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7674
7675echo "------ hv1 dump ----------"
7676as hv1 ovs-ofctl show br-int
7677as hv1 ovs-ofctl dump-flows br-int
7678echo "------ hv2 dump ----------"
7679as hv2 ovs-ofctl show br-int
7680as hv2 ovs-ofctl dump-flows br-int
7681echo "------ hv3 dump ----------"
7682as hv3 ovs-ofctl show br-int
7683as hv3 ovs-ofctl dump-flows br-int
7684echo "----------------------------"
7685
7686echo $expected >> hv3-vif1.expected
7687OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7688
7689#Check ovn-trace over "chassisredirect" port
7690AT_CAPTURE_FILE([trace])
7691ovn_trace () {
7692 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7693}
7694
7695echo 'ip.ttl--;' > expout
7696echo 'eth.src = 00:00:02:01:02:03;' >> expout
7697echo 'eth.dst = f0:00:00:01:02:04;' >> expout
7698echo 'output("ln-alice");' >> expout
7699AT_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])
7700
7701# Create logical port alice1 in alice on hv1
7702as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7703 set interface hv1-vif2 external-ids:iface-id=alice1 \
7704 options:tx_pcap=hv1/vif2-tx.pcap \
7705 options:rxq_pcap=hv1/vif2-rx.pcap \
7706 ofport-request=1
7707
7708ovn-nbctl lsp-add alice alice1 \
7709-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
7710
7711# Create logical port foo2 in foo on hv2
7712as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7713 set interface hv2-vif1 external-ids:iface-id=foo2 \
7714 options:tx_pcap=hv2/vif1-tx.pcap \
7715 options:rxq_pcap=hv2/vif1-rx.pcap \
7716 ofport-request=1
7717
7718ovn-nbctl lsp-add foo foo2 \
7719-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7720
7721# Allow some time for ovn-northd and ovn-controller to catch up.
7722# XXX This should be more systematic.
7723sleep 1
7724
7725: > hv1-vif2.expected
7726
7727# Send ip packet between alice1 and foo2
7728src_mac="f00000010205"
7729dst_mac="000002010203"
7730src_ip=`ip_to_hex 172 16 1 4`
7731dst_ip=`ip_to_hex 192 168 1 3`
7732packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7733
7734as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7735
7736# Packet to Expect at foo2
7737src_mac="000001010203"
7738dst_mac="f00000010206"
7739src_ip=`ip_to_hex 172 16 1 4`
7740dst_ip=`ip_to_hex 192 168 1 3`
7741expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7742
7743echo $expected >> hv2-vif1.expected
f5f64552 7744OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 7745
0d31e5be 7746AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 7747])
7748
8e1d9349 7749ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 7750
0d31e5be 7751AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 7752])
7753
41a15b71
MS
7754OVN_CLEANUP([hv1],[hv2],[hv3])
7755
7756AT_CLEANUP
26b9e08d
MS
7757
7758AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7759AT_SKIP_IF([test $HAVE_PYTHON = no])
7760ovn_start
7761# Create logical switches
7762ovn-nbctl ls-add ls0
7763ovn-nbctl ls-add ls1
7764# Create distributed router
7765ovn-nbctl create Logical_Router name=lr0
7766# Add distributed gateway port to distributed router
7767ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
7768 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
7769ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
7770 type=router options:router-port=lrp0 addresses="router"
7771# Add router port to ls1
7772ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
7773ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
7774 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
7775# Add logical ports for NAT rules
7776ovn-nbctl lsp-add ls1 foo1 \
7777-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
7778ovn-nbctl lsp-add ls1 foo2 \
7779-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
7780# Add nat-addresses option
7781ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7782# Add NAT rules
7783AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
7784AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
7785AT_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 7786AT_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
7787
7788net_add n1
7789sim_add hv1
7790as hv1
7791ovs-vsctl add-br br-phys
7792ovn_attach n1 br-phys 192.168.0.1
7793
7794AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7795AT_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])
7796
7797sim_add hv2
7798as hv2
7799ovs-vsctl add-br br-phys
7800ovn_attach n1 br-phys 192.168.0.2
7801# Initially test with no bridge-mapping on hv2, expect to receive no packets
7802
f40c5588
MS
7803sim_add hv3
7804as hv3
7805ovs-vsctl add-br br-phys
7806ovn_attach n1 br-phys 192.168.0.3
7807# Initially test with no bridge-mapping on hv3
7808
26b9e08d
MS
7809# Create a localnet port.
7810AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
7811AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7812AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7813AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7814
7815# Allow some time for ovn-northd and ovn-controller to catch up.
7816# XXX This should be more systematic.
7817sleep 2
7818
7819# Expect no packets when hv2 bridge-mapping is not present
7820: > packets
7821OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
7822
7823# Add bridge-mapping on hv2
f40c5588 7824AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
7825
7826# Wait for packets to be received.
7827OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
7828trim_zeros() {
7829 sed 's/\(00\)\{1,\}$//'
7830}
7831$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7832expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
7833echo $expected > expout
7834expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
7835echo $expected >> expout
7836AT_CHECK([sort packets], [0], [expout])
f40c5588 7837sort packets | cat
26b9e08d 7838
f40c5588
MS
7839# Temporarily remove nat-addresses option to avoid race conditions
7840# due to GARP backoff
7841ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
7842
7843reset_pcap_file() {
7844 local iface=$1
7845 local pcap_file=$2
7846 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7847options:rxq_pcap=dummy-rx.pcap
7848 rm -f ${pcap_file}*.pcap
7849 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7850options:rxq_pcap=${pcap_file}-rx.pcap
7851}
7852
7853as hv1 reset_pcap_file snoopvif hv1/snoopvif
7854
7855# Add OVS ports for foo1 and foo2 on hv3
7856ovs-vsctl -- add-port br-int hv3-vif1 -- \
7857 set interface hv3-vif1 external-ids:iface-id=foo1 \
7858 ofport-request=1
7859ovs-vsctl -- add-port br-int hv3-vif2 -- \
7860 set interface hv3-vif2 external-ids:iface-id=foo2 \
7861 ofport-request=2
7862
7863# Add bridge-mapping on hv3
7864AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7865
7866# Re-add nat-addresses option
7867ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7868
7869# Wait for packets to be received.
7870OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
7871trim_zeros() {
7872 sed 's/\(00\)\{1,\}$//'
7873}
7874
7875$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7876expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
7877echo $expected >> expout
7878expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
7879echo $expected >> expout
7880AT_CHECK([sort packets], [0], [expout])
7881sort packets | cat
7882
7883OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
7884
7885AT_CLEANUP
6b785fd8 7886
4364646c
ZKL
7887AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
7888AT_KEYWORDS([ovn-nd_ra])
7889AT_SKIP_IF([test $HAVE_PYTHON = no])
7890ovn_start
7891
7892# In this test case we create 1 lswitch with 3 VIF ports attached,
7893# and a lrouter connected to the lswitch.
7894# We generate the Router solicitation packet and verify the Router Advertisement
7895# reply packet from the ovn-controller.
7896
7897# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
7898# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
7899# 'slaac' to allow lrp0 send RA for SLAAC mode.
7900ovn-nbctl ls-add lsw0
7901ovn-nbctl lr-add lr0
7902ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
7903ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
7904ovn-nbctl \
7905 -- lsp-add lsw0 lsp0 \
7906 -- set Logical_Switch_Port lsp0 type=router \
7907 options:router-port=lrp0 \
7908 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
7909net_add n1
7910sim_add hv1
7911as hv1
7912ovs-vsctl add-br br-phys
7913ovn_attach n1 br-phys 192.168.0.2
7914
7915ovn-nbctl lsp-add lsw0 lp1
7916ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
7917ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
7918
7919ovn-nbctl lsp-add lsw0 lp2
7920ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
7921ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
7922
7923ovn-nbctl lsp-add lsw0 lp3
7924ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
7925ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
7926
7927# Add ACL rule for ICMPv6 on lsw0
7928ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
7929ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
7930ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
7931ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
7932
7933ovs-vsctl -- add-port br-int hv1-vif1 -- \
7934 set interface hv1-vif1 external-ids:iface-id=lp1 \
7935 options:tx_pcap=hv1/vif1-tx.pcap \
7936 options:rxq_pcap=hv1/vif1-rx.pcap \
7937 ofport-request=1
7938
7939ovs-vsctl -- add-port br-int hv1-vif2 -- \
7940 set interface hv1-vif2 external-ids:iface-id=lp2 \
7941 options:tx_pcap=hv1/vif2-tx.pcap \
7942 options:rxq_pcap=hv1/vif2-rx.pcap \
7943 ofport-request=2
7944
7945ovs-vsctl -- add-port br-int hv1-vif3 -- \
7946 set interface hv1-vif3 external-ids:iface-id=lp3 \
7947 options:tx_pcap=hv1/vif3-tx.pcap \
7948 options:rxq_pcap=hv1/vif3-rx.pcap \
7949 ofport-request=3
7950
7951# Allow some time for ovn-northd and ovn-controller to catch up.
7952# XXX This should be more systematic.
7953sleep 1
7954
7955reset_pcap_file() {
7956 local iface=$1
7957 local pcap_file=$2
7958 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7959options:rxq_pcap=dummy-rx.pcap
7960 rm -f ${pcap_file}*.pcap
7961 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7962options:rxq_pcap=${pcap_file}-rx.pcap
7963}
7964
7965# Make sure that ovn-controller has installed the corresponding OF Flow.
7966OVS_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"`])
7967
7968# This shell function sends a Router Solicitation packet.
7969# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
7970test_ipv6_ra() {
7971 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
7972 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
7973
7974 local len=24
7975 local mtu_opt=""
7976 if test $mtu != 0; then
7977 len=`expr $len + 8`
7978 mtu_opt=05010000${mtu}
7979 fi
7980
7981 if test ${#prefix_opt} != 0; then
7982 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
7983 len=`expr $len + ${#prefix_opt} / 2`
7984 fi
7985
7986 len=$(printf "%x" $len)
7987 local lrp_mac=fa163e000001
7988 local lrp_lla=fe80000000000000f8163efffe000001
7989 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
7990 echo $reply >> $inport.expected
7991
7992 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
7993}
7994
7995AT_CAPTURE_FILE([ofctl_monitor0.log])
7996as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7997--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7998
7999# MTU is not set and the address mode is set to slaac
8000addr_mode=00
8001default_prefix_option_config=030440c0ffffffffffffffff00000000
8002src_mac=fa163e000002
8003src_lla=fe80000000000000f8163efffe000002
8004test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8005
8006# NXT_RESUME should be 1.
8007OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8008
8009$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8010
8011cat 1.expected | cut -c -112 > expout
8012AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8013
8014# Skipping the ICMPv6 checksum.
8015cat 1.expected | cut -c 117- > expout
8016AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8017
8018rm -f *.expected
8019reset_pcap_file hv1-vif1 hv1/vif1
8020reset_pcap_file hv1-vif2 hv1/vif2
8021reset_pcap_file hv1-vif3 hv1/vif3
8022
8023# Set the MTU to 1500
8024ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8025
8026# Make sure that ovn-controller has installed the corresponding OF Flow.
8027OVS_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"`])
8028
8029addr_mode=00
8030default_prefix_option_config=030440c0ffffffffffffffff00000000
8031src_mac=fa163e000003
8032src_lla=fe80000000000000f8163efffe000003
8033mtu=000005dc
8034
8035test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8036
8037# NXT_RESUME should be 2.
8038OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8039
8040$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8041
8042cat 2.expected | cut -c -112 > expout
8043AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8044
8045# Skipping the ICMPv6 checksum.
8046cat 2.expected | cut -c 117- > expout
8047AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8048
8049rm -f *.expected
8050reset_pcap_file hv1-vif1 hv1/vif1
8051reset_pcap_file hv1-vif2 hv1/vif2
8052reset_pcap_file hv1-vif3 hv1/vif3
8053
8054# Set the address mode to dhcpv6_stateful
8055ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8056# Make sure that ovn-controller has installed the corresponding OF Flow.
8057OVS_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"`])
8058
8059addr_mode=80
8060default_prefix_option_config=""
8061src_mac=fa163e000004
8062src_lla=fe80000000000000f8163efffe000004
8063mtu=000005dc
8064
8065test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8066
8067# NXT_RESUME should be 3.
8068OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8069
8070$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8071
8072cat 3.expected | cut -c -112 > expout
8073AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8074
8075# Skipping the ICMPv6 checksum.
8076cat 3.expected | cut -c 117- > expout
8077AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8078
8079rm -f *.expected
8080reset_pcap_file hv1-vif1 hv1/vif1
8081reset_pcap_file hv1-vif2 hv1/vif2
8082reset_pcap_file hv1-vif3 hv1/vif3
8083
8084# Set the address mode to dhcpv6_stateless
8085ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8086# Make sure that ovn-controller has installed the corresponding OF Flow.
8087OVS_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"`])
8088
8089addr_mode=40
8090default_prefix_option_config=030440c0ffffffffffffffff00000000
8091src_mac=fa163e000002
8092src_lla=fe80000000000000f8163efffe000002
8093mtu=000005dc
8094
8095test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8096
8097# NXT_RESUME should be 4.
8098OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8099
8100$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8101
8102cat 1.expected | cut -c -112 > expout
8103AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8104
8105# Skipping the ICMPv6 checksum.
8106cat 1.expected | cut -c 117- > expout
8107AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8108
8109rm -f *.expected
8110reset_pcap_file hv1-vif1 hv1/vif1
8111reset_pcap_file hv1-vif2 hv1/vif2
8112reset_pcap_file hv1-vif3 hv1/vif3
8113
8114# Set the address mode to invalid.
8115ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8116# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8117OVS_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"`])
8118
8119addr_mode=40
8120default_prefix_option_config=""
8121src_mac=fa163e000002
8122src_lla=fe80000000000000f8163efffe000002
8123mtu=000005dc
8124
8125test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8126
8127# NXT_RESUME should be 4 only.
8128OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8129
8130$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8131AT_CHECK([cat 1.packets], [0], [])
8132
8133OVN_CLEANUP([hv1])
8134AT_CLEANUP
8135
6b785fd8
GS
8136AT_SETUP([ovn -- /32 router IP address])
8137AT_SKIP_IF([test $HAVE_PYTHON = no])
8138ovn_start
8139
8140# Logical network:
8141# 2 LS 'foo' and 'alice' connected via router R1.
8142# R1 connects to 'alice' with a /32 IP address. We use static routes and
8143# nexthop to push traffic to a logical port in switch 'alice'
8144
8145ovn-nbctl lr-add R1
8146
8147ovn-nbctl ls-add foo
8148ovn-nbctl ls-add alice
8149
8150# Connect foo to R1
8151ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8152ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8153 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8154
8155# Connect alice to R1.
8156ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8157ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8158 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8159
8160# Create logical port foo1 in foo
8161ovn-nbctl lsp-add foo foo1 \
8162-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8163
8164# Create logical port alice1 in alice
8165ovn-nbctl lsp-add alice alice1 \
8166-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8167
8168#install default route in R1 to use alice1's IP address as nexthop
8169ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8170
8171# Create two hypervisor and create OVS ports corresponding to logical ports.
8172net_add n1
8173
8174sim_add hv1
8175as hv1
8176ovs-vsctl add-br br-phys
8177ovn_attach n1 br-phys 192.168.0.1
8178ovs-vsctl -- add-port br-int hv1-vif1 -- \
8179 set interface hv1-vif1 external-ids:iface-id=foo1 \
8180 options:tx_pcap=hv1/vif1-tx.pcap \
8181 options:rxq_pcap=hv1/vif1-rx.pcap \
8182 ofport-request=1
8183
8184sim_add hv2
8185as hv2
8186ovs-vsctl add-br br-phys
8187ovn_attach n1 br-phys 192.168.0.2
8188ovs-vsctl -- add-port br-int hv2-vif1 -- \
8189 set interface hv2-vif1 external-ids:iface-id=alice1 \
8190 options:tx_pcap=hv2/vif1-tx.pcap \
8191 options:rxq_pcap=hv2/vif1-rx.pcap \
8192 ofport-request=1
8193
8194
8195# Pre-populate the hypervisors' ARP tables so that we don't lose any
8196# packets for ARP resolution (native tunneling doesn't queue packets
8197# for ARP resolution).
8198ovn_populate_arp
8199
8200# Allow some time for ovn-northd and ovn-controller to catch up.
8201# XXX This should be more systematic.
8202sleep 1
8203
8204ip_to_hex() {
8205 printf "%02x%02x%02x%02x" "$@"
8206}
8207
8208# Send ip packets between foo1 and alice1
8209src_mac="f00000010203"
8210dst_mac="000000010203"
8211src_ip=`ip_to_hex 192 168 1 2`
8212dst_ip=`ip_to_hex 10 0 0 2`
8213packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8214
8215# Send the first packet to trigger a ARP response and population of
8216# mac_bindings table.
8217as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8218OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8219
8220# Send the second packet to reach the destination.
8221as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8222
8223# Packet to Expect at 'alice1'
8224src_mac="000000010204"
8225dst_mac="f00000010204"
8226src_ip=`ip_to_hex 192 168 1 2`
8227dst_ip=`ip_to_hex 10 0 0 2`
8228echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8229
8230OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8231
8232OVN_CLEANUP([hv1],[hv2])
8233
8234AT_CLEANUP
2a38ef45
DA
8235
8236AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8237AT_SKIP_IF([test $HAVE_PYTHON = no])
8238ovn_start
8239
8240ovn-nbctl ls-add ls1
8241
8242# Add localport to the switch
8243ovn-nbctl lsp-add ls1 lp01
8244ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8245ovn-nbctl lsp-set-type lp01 localport
8246
8247net_add n1
8248
8249for i in 1 2; do
8250 sim_add hv$i
8251 as hv$i
8252 ovs-vsctl add-br br-phys
8253 ovn_attach n1 br-phys 192.168.0.$i
8254 ovs-vsctl add-port br-int vif01 -- \
8255 set Interface vif01 external-ids:iface-id=lp01 \
8256 options:tx_pcap=hv${i}/vif01-tx.pcap \
8257 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8258 ofport-request=${i}0
8259
8260 ovs-vsctl add-port br-int vif${i}1 -- \
8261 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8262 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8263 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8264 ofport-request=${i}1
8265
8266 ovn-nbctl lsp-add ls1 lp${i}1
8267 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8268 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8269
8270 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8271done
8272
8273ovn-nbctl --wait=sb sync
8274ovn-sbctl dump-flows
8275
8276ovn_populate_arp
8277
8278# Given the name of a logical port, prints the name of the hypervisor
8279# on which it is located.
8280vif_to_hv() {
8281 echo hv${1%?}
8282}
8283#
8284# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8285#
8286# This shell function causes a packet to be received on INPORT. The packet's
8287# content has Ethernet destination DST and source SRC (each exactly 12 hex
8288# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8289# logical switch port numbers, e.g. 11 for vif11.
8290#
8291# EOUT is the end-to-end output port, that is, where the packet will end up
8292# after possibly bouncing through one or more localnet ports. LOUT is the
8293# logical output port, which might be a localnet port, as seen by ovn-trace
8294# (which doesn't know what localnet ports are connected to and therefore can't
8295# figure out the end-to-end answer).
8296#
8297# DEFHV is the default hypervisor from where the packet is going to be sent
8298# if the source port is a localport.
8299for i in 1 2; do
8300 for j in 0 1; do
8301 : > $i$j.expected
8302 done
8303done
8304test_packet() {
8305 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8306 echo "$@"
8307
8308 # First try tracing the packet.
8309 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8310 if test $lout != drop; then
8311 echo "output(\"$lout\");"
8312 fi > expout
8313 AT_CAPTURE_FILE([trace])
8314 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8315
8316 # Then actually send a packet, for an end-to-end test.
8317 local packet=$(echo $dst$src | sed 's/://g')${eth}
8318 hv=`vif_to_hv $inport`
8319 # If hypervisor 0 (localport) use the defhv parameter
da88b550 8320 if test $hv = hv0; then
2a38ef45
DA
8321 hv=$defhv
8322 fi
8323 vif=vif$inport
8324 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8325 if test $eout != drop; then
8326 echo $packet >> ${eout#lp}.expected
8327 fi
8328}
8329
8330
8331# lp11 and lp21 are on different hypervisors
8332test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8333test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8334
8335# Both VIFs should be able to reach the localport on their own HV
8336test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8337test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8338
8339# Packet sent from localport on same hv should reach the vif
8340test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8341test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8342
8343# Packet sent from localport on different hv should be dropped
8344test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8345test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8346
8347# Now check the packets actually received against the ones expected.
8348for i in 1 2; do
8349 for j in 0 1; do
8350 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8351 done
8352done
8353
8354OVN_CLEANUP([hv1],[hv2])
8355
8356AT_CLEANUP
1da17a0b 8357
8358AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8359AT_SKIP_IF([test $HAVE_PYTHON = no])
8360ovn_start
8361
8362net_add n1
8363
8364# create gateways with external network connectivity
8365
8366for i in 1 2; do
8367 sim_add gw$i
8368 as gw$i
8369 ovs-vsctl add-br br-phys
8370 ovn_attach n1 br-phys 192.168.0.$i
8371 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8372done
8373
8374ovn-nbctl ls-add inside
8375ovn-nbctl ls-add outside
8376
8377# create hypervisors with a vif port each to an internal network
8378
8379for i in 1 2; do
8380 sim_add hv$i
8381 as hv$i
8382 ovs-vsctl add-br br-phys
8383 ovn_attach n1 br-phys 192.168.0.1$i
8384 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8385 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8386 options:tx_pcap=hv$i/vif1-tx.pcap \
8387 options:rxq_pcap=hv$i/vif1-rx.pcap \
8388 ofport-request=1
8389
8390 ovn-nbctl lsp-add inside inside$i \
8391 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8392
8393done
8394
8395ovn_populate_arp
8396
8397ovn-nbctl create Logical_Router name=R1
8398
8399# Connect inside to R1
8400ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8401ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8402 type=router options:router-port=inside \
8403 -- lsp-set-addresses rp-inside router
8404
8405# Connect outside to R1 as distributed router gateway port on gw1+gw2
8406ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8407
8408ovn-nbctl --id=@gc0 create Gateway_Chassis \
8409 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8410 --id=@gc1 create Gateway_Chassis \
8411 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8412 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8413
8414ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8415 type=router options:router-port=outside \
8416 -- lsp-set-addresses rp-outside router
8417
8418# Create localnet port in outside
8419ovn-nbctl lsp-add outside ln-outside
8420ovn-nbctl lsp-set-addresses ln-outside unknown
8421ovn-nbctl lsp-set-type ln-outside localnet
8422ovn-nbctl lsp-set-options ln-outside network_name=phys
8423
8424# Allow some time for ovn-northd and ovn-controller to catch up.
8425# XXX This should be more systematic.
8e1d9349 8426ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8427
8428echo "---------NB dump-----"
8429ovn-nbctl show
8430echo "---------------------"
8431ovn-nbctl list logical_router
8432echo "---------------------"
8433ovn-nbctl list logical_router_port
8434echo "---------------------"
8435
8436echo "---------SB dump-----"
8437ovn-sbctl list datapath_binding
8438echo "---------------------"
8439ovn-sbctl list port_binding
8440echo "---------------------"
8441ovn-sbctl dump-flows
8442echo "---------------------"
8443ovn-sbctl list chassis
8444ovn-sbctl list encap
8445echo "---------------------"
8446echo "------ Gateway_Chassis dump (SBDB) -------"
8447ovn-sbctl list Gateway_Chassis
8448echo "------ Port_Binding chassisredirect -------"
8449ovn-sbctl find Port_Binding type=chassisredirect
8450echo "-------------------------------------------"
8451
3475695e
VA
8452for chassis in gw1 gw2 hv1 hv2; do
8453 as $chassis
8454 echo "------ $chassis dump ----------"
8455 ovs-ofctl show br-int
8456 ovs-ofctl dump-flows br-int
3475695e
VA
8457 echo "--------------------------"
8458done
508b7f96 8459function bfd_dump() {
8460 for chassis in gw1 gw2 hv1 hv2; do
8461 as $chassis
8462 echo "------ $chassis dump (BFD)----"
8463 echo "BFD (from $chassis):"
8464 # dump BFD config and status to the other chassis
8465 for chassis2 in gw1 gw2 hv1 hv2; do
8466 if [[ "$chassis" != "$chassis2" ]]; then
8467 echo " -> $chassis2:"
8468 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8469 fi
8470 done
8471 echo "--------------------------"
8472 done
8473}
8474
8475bfd_dump
1da17a0b 8476
8477hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8478hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8479hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8480hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8481
8482echo $hv1_gw1_ofport
8483echo $hv1_gw2_ofport
8484echo $hv2_gw1_ofport
8485echo $hv2_gw2_ofport
8486
8487echo "--- hv1 ---"
8488as hv1 ovs-ofctl dump-flows br-int table=32
8489
8490echo "--- hv2 ---"
8491as hv2 ovs-ofctl dump-flows br-int table=32
8492
508b7f96 8493gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8494gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8495
1da17a0b 8496AT_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
8497])
8498
8499AT_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
8500])
8501
508b7f96 8502sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8503
8504# make sure that flows for handling the outside router port reside on gw1
8505AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8506]])
8507AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8508]])
8509
8510# make sure ARP responder flows for outside router port reside on gw1 too
8511AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8512]])
8513AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8514]])
8515
8516
8517
8518# check that the chassis redirect port has been claimed by the gw1 chassis
8519AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8520 [0],[[1
8521]])
8522
8523
8524# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 8525
8526ovn-nbctl --id=@gc0 create Gateway_Chassis \
8527 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8528 --id=@gc1 create Gateway_Chassis \
8529 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8530 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8531
508b7f96 8532
1da17a0b 8533# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 8534ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8535
508b7f96 8536# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 8537AT_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
8538])
8539
8540AT_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
8541])
8542
508b7f96 8543# check that the chassis redirect port has been reclaimed by the gw2 chassis
8544AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8545 [0],[[1
8546]])
1da17a0b 8547
3475695e
VA
8548# check BFD enablement on tunnel ports from gw1 #########
8549as gw1
8550for chassis in gw2 hv1 hv2; do
8551 echo "checking gw1 -> $chassis"
8552 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8553 [[enable=true
8554]])
8555done
8556
8557
8558# check BFD enablement on tunnel ports from gw2 ##########
8559as gw2
8560for chassis in gw1 hv1 hv2; do
8561 echo "checking gw2 -> $chassis"
8562 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8563 [[enable=true
8564]])
8565done
8566
8567# check BFD enablement on tunnel ports from hv1 ###########
8568as hv1
8569for chassis in gw1 gw2; do
8570 echo "checking hv1 -> $chassis"
8571 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8572 [[enable=true
8573]])
8574done
8575# make sure BFD is not enabled to hv2, we don't need it
8576AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8577 [[enable=false
8578]])
8579
8580
8581# check BFD enablement on tunnel ports from hv2 ##########
8582as hv2
8583for chassis in gw1 gw2; do
8584 echo "checking hv2 -> $chassis"
8585 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8586 [[enable=true
8587]])
8588done
8589# make sure BFD is not enabled to hv1, we don't need it
8590AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8591 [[enable=false
8592]])
8593
508b7f96 8594sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8595
8596# make sure that flows for handling the outside router port reside on gw2 now
8597AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8598]])
8599AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8600]])
8601
8602# disconnect GW2 from the network, GW1 should take over
8603as gw2
8604port=${sandbox}_br-phys
8605as main ovs-vsctl del-port n1 $port
8606sleep 4
8607
8608bfd_dump
8609
8610# make sure that flows for handling the outside router port reside on gw2 now
8611AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8612]])
8613AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8614]])
8615
8616# check that the chassis redirect port has been reclaimed by the gw1 chassis
8617AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8618 [0],[[1
8619]])
8620
1da17a0b 8621OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8622
8623AT_CLEANUP
acfc41ff
VAK
8624
8625AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8626AT_SKIP_IF([test $HAVE_PYTHON = no])
8627ovn_start
8628ovn-nbctl ls-add ls0
8629ovn-nbctl ls-add ls1
8630ovn-nbctl create Logical_Router name=lr0
8631ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8632
8633ovn-nbctl --id=@gc0 create Gateway_Chassis \
8634 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8635 --id=@gc1 create Gateway_Chassis \
8636 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8637 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8638
8639ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8640 type=router options:router-port=lrp0 addresses="router"
8641ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8642ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8643 type=router options:router-port=lrp1 addresses="router"
8644
8645# Add NAT rules
8646AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8647
8648net_add n1
8649sim_add hv1
8650as hv1
8651ovs-vsctl add-br br-phys
8652ovn_attach n1 br-phys 192.168.0.1
8653AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8654AT_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])
8655
8656sim_add hv2
8657as hv2
8658ovs-vsctl add-br br-phys
8659ovn_attach n1 br-phys 192.168.0.2
8660AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8661
8662sim_add hv3
8663as hv3
8664ovs-vsctl add-br br-phys
8665ovn_attach n1 br-phys 192.168.0.3
8666AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8667
8668# Create a localnet port.
8669AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8670AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8671AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8672AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8673
8674# wait for earlier changes to take effect
8675AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8676
8677reset_pcap_file() {
8678 local iface=$1
8679 local pcap_file=$2
8680 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8681options:rxq_pcap=dummy-rx.pcap
8682 rm -f ${pcap_file}*.pcap
8683 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8684options:rxq_pcap=${pcap_file}-rx.pcap
8685}
8686
8687as hv1 reset_pcap_file snoopvif hv1/snoopvif
8688as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8689as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8690# add nat-addresses option
8691ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8692
8693# Wait for packets to be received through hv2.
8694OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8695trim_zeros() {
8696 sed 's/\(00\)\{1,\}$//'
8697}
8698
2db7bb2c 8699only_broadcast_from_lrp1() {
8700 grep "fffffffffffff00000000001"
8701}
8702
acfc41ff 8703garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 8704echo $garp > expout
8705
8706$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
8707echo "packets on hv1-snoopvif:"
8708cat hv1_snoop_tx
8709AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 8710$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
8711echo "packets on hv2 br-phys tx"
8712cat hv2_br_phys_tx
8713AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 8714$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
8715echo "packets on hv3 br-phys tx"
8716cat hv3_br_phys_tx
8717AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8718
8719
8720# at this point, we invert the priority of the gw chassis between hv2 and hv3
8721
8722ovn-nbctl --wait=hv \
8723 --id=@gc0 create Gateway_Chassis \
8724 name=outside_gw1 chassis_name=hv2 priority=1 -- \
8725 --id=@gc1 create Gateway_Chassis \
8726 name=outside_gw2 chassis_name=hv3 priority=10 -- \
8727 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8728
8729
8730as hv1 reset_pcap_file snoopvif hv1/snoopvif
8731as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8732as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8733
8734# Wait for packets to be received.
8735OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8736trim_zeros() {
8737 sed 's/\(00\)\{1,\}$//'
8738}
8739
2db7bb2c 8740$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 8741AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 8742$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 8743AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 8744$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 8745AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
8746
8747# change localnet port tag.
8748AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
8749
8750# wait for earlier changes to take effect
8751AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8752
8753# update nat-addresses option
8754ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0
8755ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8756
8757as hv1 reset_pcap_file snoopvif hv1/snoopvif
8758as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8759as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8760
8761# Wait for packets to be received.
8762OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8763trim_zeros() {
8764 sed 's/\(00\)\{1,\}$//'
8765}
8766
8767garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
8768echo $garp > expout
8769
8770$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8771AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8772$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8773AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8774$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8775AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8776
acfc41ff
VAK
8777OVN_CLEANUP([hv1],[hv2],[hv3])
8778
8779AT_CLEANUP
79371ff5 8780
8781AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8782AT_SKIP_IF([test $HAVE_PYTHON = no])
8783ovn_start
8784
8785net_add n1
8786
8787# create two gateways with external network connectivity
8788for i in 1 2; do
8789 sim_add gw$i
8790 as gw$i
8791 ovs-vsctl add-br br-phys
8792 ovn_attach n1 br-phys 192.168.0.$i
8793 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8794done
8795
8796ovn-nbctl ls-add inside
8797ovn-nbctl ls-add outside
8798
8799# create one hypervisors with a vif port the internal network
8800sim_add hv1
8801as hv1
8802ovs-vsctl add-br br-phys
8803ovn_attach n1 br-phys 192.168.0.11
8804ovs-vsctl -- add-port br-int hv1-vif1 -- \
8805 set interface hv1-vif1 external-ids:iface-id=inside1 \
8806 options:tx_pcap=hv1/vif1-tx.pcap \
8807 options:rxq_pcap=hv1/vif1-rx.pcap \
8808 ofport-request=1
8809
8810ovn-nbctl lsp-add inside inside1 \
8811 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
8812
8813
8814ovn_populate_arp
8815
8816ovn-nbctl create Logical_Router name=R1
8817
8818# Connect inside to R1
8819ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8820ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8821 type=router options:router-port=inside \
8822 -- lsp-set-addresses rp-inside router
8823
8824# Connect outside to R1 as distributed router gateway port on gw1+gw2
8825ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8826
8827ovn-nbctl --id=@gc0 create Gateway_Chassis \
8828 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8829 --id=@gc1 create Gateway_Chassis \
8830 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8831 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8832
8833ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8834 type=router options:router-port=outside \
8835 -- lsp-set-addresses rp-outside router
8836
8837# Create localnet port in outside
8838ovn-nbctl lsp-add outside ln-outside
8839ovn-nbctl lsp-set-addresses ln-outside unknown
8840ovn-nbctl lsp-set-type ln-outside localnet
8841ovn-nbctl lsp-set-options ln-outside network_name=phys
8842
8843# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 8844ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 8845
8846# currently when ovn-controller is restarted, the old entry is deleted
8847# and a new one is created, which leaves the Gateway_Chassis with
8848# an empty chassis for a while. NOTE: restarting ovn-controller in tests
8849# doesn't have the same effect because "name" is conserved, and the
8850# Chassis entry is not replaced.
8851
3a0c5805 8852> gw1/ovn-controller.log
325b2b1a 8853
79371ff5 8854gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8855ovn-sbctl destroy Chassis $gw2_chassis
8856
8857# Ensure ovn-controller has processed latest sbdb update
8858# ovn-nbctl --wait=hv sync
8859
8860AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
8861
8862OVN_CLEANUP([gw1],[gw2],[hv1])
8863
8864AT_CLEANUP
63d91afa 8865
b1a3a6a4
NS
8866AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
8867AT_KEYWORDS([ovn-nd_ns for unknown mac])
8868AT_SKIP_IF([test $HAVE_PYTHON = no])
8869ovn_start
8870
8871ovn-nbctl ls-add sw0_ip6
8872ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
8873ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
8874"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
8875
8876ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
8877"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
8878
8879ovn-nbctl lr-add lr0_ip6
847dc1c2 8880ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
8881ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
8882ovn-nbctl lsp-set-type lrp0_ip6-attachment router
8883ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
8884ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
8885ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
8886
8887ovn-nbctl ls-add public
8888ovn-nbctl lsp-add public ln-public
8889ovn-nbctl lsp-set-addresses ln-public unknown
8890ovn-nbctl lsp-set-type ln-public localnet
8891ovn-nbctl lsp-set-options ln-public network_name=phys
8892
8893ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
88942001:db8:1:0:200:02ff:fe01:0204/64 \
8895-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
8896
8897
8898ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
8899rp-ip6_public type=router options:router-port=ip6_public \
8900-- lsp-set-addresses rp-ip6_public router
8901
8902net_add n1
8903sim_add hv1
8904as hv1
8905ovs-vsctl add-br br-phys
8906ovn_attach n1 br-phys 192.168.0.2
8907
8908ovs-vsctl -- add-port br-int hv1-vif1 -- \
8909 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
8910 options:tx_pcap=hv1/vif1-tx.pcap \
8911 options:rxq_pcap=hv1/vif1-rx.pcap \
8912 ofport-request=1
8913ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8914
8915# Allow some time for ovn-northd and ovn-controller to catch up.
8916# XXX This should be more systematic.
8917sleep 1
8918
8919trim_zeros() {
8920 sed 's/\(00\)\{1,\}$//'
8921}
8922
8923# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
8924# addresses. ovn-controller should generate an IPv6 NS request for IPv6
8925# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
8926# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
8927# This function sends ipv6 packet
8928test_ipv6() {
8929 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
8930 dst_ip=20010db800010000020002fffe010205
8931
8932 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
8933 packet=${packet}8000000000000000
8934 shift; shift; shift; shift
8935
8936 dst_mac=3333ff010205
8937 src_mac=000002010204
8938 mcast_node_ip=ff0200000000000000000001ff010205
8939 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
8940 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
8941 expected_packet=${expected_packet}0101${src_mac}
8942
8943 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
8944 echo $expected_packet >> ipv6_ns.expected
8945}
8946
8947src_mac=506400000002
8948dst_mac=00000000af01
8949src_ip=aef0000000000000526400fffe000002
8950# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
8951# should be received by the ports attached to br-phys.
8952test_ipv6 1 $src_mac $dst_mac $src_ip 2
8953
8954$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
8955trim_zeros > 1.packets
8956$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
8957trim_zeros > 2.packets
8958
8959cat ipv6_ns.expected | cut -c -112 > expout
8960AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8961AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8962
8963# Skipping the ICMPv6 checksum
8964cat ipv6_ns.expected | cut -c 117- > expout
8965AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8966AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8967
8968OVN_CLEANUP([hv1])
8969
8970AT_CLEANUP
8971
63d91afa
LR
8972AT_SETUP([ovn -- options:requested-chassis for logical port])
8973ovn_start
8974
8975net_add n1
8976
8977ovn-nbctl ls-add ls0
8978ovn-nbctl lsp-add ls0 lsp0
8979
8980# create two hypervisors, each with one vif port
8981sim_add hv1
8982as hv1
8983ovs-vsctl add-br br-phys
8984ovn_attach n1 br-phys 192.168.0.11
8985ovs-vsctl -- add-port br-int hv1-vif0
8986
8987sim_add hv2
8988as hv2
8989ovs-vsctl add-br br-phys
8990ovn_attach n1 br-phys 192.168.0.12
8991ovs-vsctl -- add-port br-int hv2-vif0
8992
8993# Allow only chassis hv1 to bind logical port lsp0.
8994ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
8995
8996# Allow some time for ovn-northd and ovn-controller to catch up.
8997ovn-nbctl --wait=hv --timeout=3 sync
8998
8999# Retrieve hv1 and hv2 chassis UUIDs from southbound database
9000hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9001hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9002
9003# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9004echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9005as hv2
9006ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9007
9008OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9009AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9010
9011# (2) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9012echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9013as hv1
9014ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9015
9016OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9017AT_CHECK([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv1_uuid"], [0], [])
9018
9019# (3) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9020# the requested chassis for lsp0 is changed from hv1 to hv2.
9021echo "verifying that lsp0 binding moves when requested-chassis is changed"
9022
9023ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9024OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9025OVS_WAIT_UNTIL([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv2_uuid"])
9026
9027OVN_CLEANUP([hv1],[hv2])
9028
9029AT_CLEANUP
bd32425f
RB
9030
9031AT_SETUP([ovn -- options:requested-chassis with hostname])
9032
9033ovn_start
9034
9035ovn-nbctl ls-add ls0
9036ovn-nbctl lsp-add ls0 lsp0
9037
9038net_add n1
9039sim_add hv1
9040as hv1
9041ovs-vsctl add-br br-phys
9042ovn_attach n1 br-phys 192.168.0.11
9043ovs-vsctl -- add-port br-int hv1-vif0
9044
9045hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9046echo "hv1_hostname=${hv1_hostname}"
9047ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9048as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9049
9050hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9051echo "hv1_uuid=${hv1_uuid}"
9052OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9053AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9054
9055ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9056OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9057ovn-nbctl --wait=hv --timeout=3 sync
9058AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9059
9060OVN_CLEANUP([hv1])
9061
9062AT_CLEANUP