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