]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
ovn: Add lsp-set-dhcpv6-options ovn-nbctl operation.
[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
3666ovn-nbctl -- --id=@d1 create DHCP_Options cidr=10.0.0.0/24 \
3667options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3668\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"" \
3669-- add Logical_Switch_Port ls1-lp1 dhcpv4_options @d1 \
3670-- add Logical_Switch_Port ls1-lp2 dhcpv4_options @d1
3671
3672ovn-nbctl -- --id=@d2 create DHCP_Options cidr=30.0.0.0/24 \
3673options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3674\"lease_time\"=\"3600\"" -- add Logical_Switch_Port ls2-lp2 dhcpv4_options @d2
3675
3676net_add n1
3677sim_add hv1
3678
3679as hv1
3680ovs-vsctl add-br br-phys
3681ovn_attach n1 br-phys 192.168.0.1
3682ovs-vsctl -- add-port br-int hv1-vif1 -- \
3683 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3684 options:tx_pcap=hv1/vif1-tx.pcap \
3685 options:rxq_pcap=hv1/vif1-rx.pcap \
3686 ofport-request=1
3687
3688ovs-vsctl -- add-port br-int hv1-vif2 -- \
3689 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3690 options:tx_pcap=hv1/vif2-tx.pcap \
3691 options:rxq_pcap=hv1/vif2-rx.pcap \
3692 ofport-request=2
3693
3694ovs-vsctl -- add-port br-int hv1-vif3 -- \
3695 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3696 options:tx_pcap=hv1/vif3-tx.pcap \
3697 options:rxq_pcap=hv1/vif3-rx.pcap \
3698 ofport-request=3
3699
3700ovs-vsctl -- add-port br-int hv1-vif4 -- \
3701 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3702 options:tx_pcap=hv1/vif4-tx.pcap \
3703 options:rxq_pcap=hv1/vif4-rx.pcap \
3704 ofport-request=4
3705
3706ovn_populate_arp
3707
3708sleep 2
3709
3710as hv1 ovs-vsctl show
3711
281977f7
NS
3712# This shell function sends a DHCP request packet
3713# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3714test_dhcp() {
213615b3
NS
3715 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3716 shift; shift; shift; shift; shift;
3717 if test $use_ip != 0; then
3718 src_ip=$1
3719 dst_ip=$2
3720 shift; shift;
3721 else
3722 src_ip=`ip_to_hex 0 0 0 0`
3723 dst_ip=`ip_to_hex 255 255 255 255`
3724 fi
3725 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
281977f7 3726 # udp header and dhcp header
ab187e7e
BP
3727 request=${request}0044004300fc0000
3728 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 3729 # client hardware padding
ab187e7e 3730 request=${request}00000000000000000000
281977f7 3731 # server hostname
ab187e7e
BP
3732 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3733 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3734 # boot file name
ab187e7e
BP
3735 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3736 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3737 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3738 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3739 # dhcp magic cookie
ab187e7e 3740 request=${request}63825363
281977f7 3741 # dhcp message type
ab187e7e 3742 request=${request}3501${dhcp_type}ff
281977f7
NS
3743
3744 if test $offer_ip != 0; then
213615b3 3745 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
281977f7
NS
3746 # total IP length will be the IP length of the request packet
3747 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3748 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3749 udp_len=`expr $ip_len - 20`
04d60f6e
YT
3750 ip_len=$(printf "%x" $ip_len)
3751 udp_len=$(printf "%x" $udp_len)
281977f7
NS
3752 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3753 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3754 # udp header and dhcp header.
3755 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 3756 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 3757 # your ip address
ab187e7e 3758 reply=${reply}${offer_ip}
281977f7 3759 # next server ip address, relay agent ip address, client mac address
ab187e7e 3760 reply=${reply}0000000000000000${src_mac}
281977f7 3761 # client hardware padding
ab187e7e 3762 reply=${reply}00000000000000000000
281977f7 3763 # server hostname
ab187e7e
BP
3764 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3765 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3766 # boot file name
ab187e7e
BP
3767 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3768 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3769 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3770 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3771 # dhcp magic cookie
ab187e7e 3772 reply=${reply}63825363
281977f7
NS
3773 # dhcp message type
3774 local dhcp_reply_type=02
3775 if test $dhcp_type = 03; then
3776 dhcp_reply_type=05
3777 fi
ab187e7e 3778 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
3779 echo $reply >> $inport.expected
3780 else
281977f7 3781 for outport; do
e4543cfe 3782 echo $request >> $outport.expected
281977f7
NS
3783 done
3784 fi
3785 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3786}
3787
3788reset_pcap_file() {
3789 local iface=$1
3790 local pcap_file=$2
3791 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3792options:rxq_pcap=dummy-rx.pcap
3793 rm -f ${pcap_file}*.pcap
3794 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3795options:rxq_pcap=${pcap_file}-rx.pcap
3796}
3797
3798ip_to_hex() {
3799 printf "%02x%02x%02x%02x" "$@"
3800}
3801
3802AT_CAPTURE_FILE([ofctl_monitor0.log])
3803as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3804--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3805
3806echo "---------NB dump-----"
3807ovn-nbctl show
3808echo "---------------------"
3809echo "---------SB dump-----"
3810ovn-sbctl list datapath_binding
3811echo "---------------------"
3812ovn-sbctl list logical_flow
3813echo "---------------------"
3814
3815echo "---------------------"
3816ovn-sbctl dump-flows
3817echo "---------------------"
3818
3819echo "------ hv1 dump ----------"
3820as hv1 ovs-ofctl dump-flows br-int
3821
3822# Send DHCPDISCOVER.
3823offer_ip=`ip_to_hex 10 0 0 4`
3824server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 3825expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 3826test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
3827
3828# NXT_RESUMEs should be 1.
3829OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3830
3831$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3832cat 1.expected | cut -c -48 > expout
3833AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3834# Skipping the IPv4 checksum.
3835cat 1.expected | cut -c 53- > expout
3836AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3837
3838# ovs-ofctl also resumes the packets and this causes other ports to receive
3839# the DHCP request packet. So reset the pcap files so that its easier to test.
3840reset_pcap_file hv1-vif1 hv1/vif1
3841reset_pcap_file hv1-vif2 hv1/vif2
3842rm -f 1.expected
3843rm -f 2.expected
3844
3845# Send DHCPREQUEST.
3846offer_ip=`ip_to_hex 10 0 0 6`
3847server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 3848expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 3849test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
3850
3851# NXT_RESUMEs should be 2.
3852OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3853
3854$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3855cat 2.expected | cut -c -48 > expout
3856AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3857# Skipping the IPv4 checksum.
3858cat 2.expected | cut -c 53- > expout
3859AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3860
3861reset_pcap_file hv1-vif1 hv1/vif1
3862reset_pcap_file hv1-vif2 hv1/vif2
3863rm -f 1.expected
3864rm -f 2.expected
3865
3866# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3867# but should be resumed without the reply.
3868# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3869# one from ovn-controller and the other from "ovs-ofctl resume."
3870offer_ip=0
213615b3 3871test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
281977f7
NS
3872
3873# NXT_RESUMEs should be 3.
3874OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3875
3876# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 3877OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
3878
3879reset_pcap_file hv1-vif1 hv1/vif1
3880reset_pcap_file hv1-vif2 hv1/vif2
3881rm -f 1.expected
3882rm -f 2.expected
3883
3884# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3885# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3886
213615b3 3887test_dhcp 3 f00000000003 01 0 4 0
281977f7
NS
3888
3889# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3890# this lport.
213615b3 3891test_dhcp 4 f00000000004 01 0 3 0
281977f7
NS
3892
3893# NXT_RESUMEs should be 3.
3894OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3895
49d7c759
BP
3896OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
3897OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 3898
213615b3
NS
3899# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
3900offer_ip=`ip_to_hex 10 0 0 6`
3901server_ip=`ip_to_hex 10 0 0 1`
3902expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3903src_ip=$offer_ip
3904dst_ip=$server_ip
3905test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
3906
3907# NXT_RESUMEs should be 4.
3908OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3909
3910$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3911cat 2.expected | cut -c -48 > expout
3912AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3913# Skipping the IPv4 checksum.
3914cat 2.expected | cut -c 53- > expout
3915AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3916
3917reset_pcap_file hv1-vif1 hv1/vif1
3918reset_pcap_file hv1-vif2 hv1/vif2
3919rm -f 1.expected
3920rm -f 2.expected
3921
3922# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
3923offer_ip=`ip_to_hex 10 0 0 6`
3924server_ip=`ip_to_hex 10 0 0 1`
3925expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3926src_ip=$offer_ip
3927dst_ip=`ip_to_hex 255 255 255 255`
3928test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
3929
3930# NXT_RESUMEs should be 5.
3931OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3932
3933$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3934cat 2.expected | cut -c -48 > expout
3935AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3936# Skipping the IPv4 checksum.
3937cat 2.expected | cut -c 53- > expout
3938AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3939
3940reset_pcap_file hv1-vif1 hv1/vif1
3941reset_pcap_file hv1-vif2 hv1/vif2
3942rm -f 1.expected
3943rm -f 2.expected
3944
3945# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
3946# The packet should not be received by ovn-controller.
3947src_ip=`ip_to_hex 10 0 0 6`
3948dst_ip=`ip_to_hex 10 0 0 4`
3949test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
3950
3951# NXT_RESUMEs should be 5.
3952OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3953
3954# vif1-tx.pcap should have received the DHCPv4 request packet
3955OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
3956
281977f7 3957as hv1
33ac3c83
NS
3958OVS_APP_EXIT_AND_WAIT([ovn-controller])
3959OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3960OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3961
3962as ovn-sb
3963OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3964
3965as ovn-nb
3966OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3967
3968as northd
3969OVS_APP_EXIT_AND_WAIT([ovn-northd])
3970
3971as main
3972OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3973OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3974
3975AT_CLEANUP
3976
40df4566 3977AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
3978AT_SKIP_IF([test $HAVE_PYTHON = no])
3979ovn_start
3980
3981ovn-nbctl ls-add ls1
3982ovn-nbctl lsp-add ls1 ls1-lp1 \
3983-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3984
3985ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3986
3987ovn-nbctl lsp-add ls1 ls1-lp2 \
3988-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3989
3990ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3991
40df4566
ZKL
3992ovn-nbctl lsp-add ls1 ls1-lp3 \
3993-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3994
3995ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3996
33ac3c83
NS
3997ovn-nbctl -- --id=@d1 create DHCP_Options cidr="ae70\:\:/64" \
3998options="\"server_id\"=\"00:00:00:10:00:01\"" \
3999-- add Logical_Switch_Port ls1-lp1 dhcpv6_options @d1 \
4000-- add Logical_Switch_Port ls1-lp2 dhcpv6_options @d1
4001
40df4566
ZKL
4002ovn-nbctl -- --id=@d2 create DHCP_Options cidr="ae70\:\:/64" \
4003options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"" \
4004-- add Logical_Switch_Port ls1-lp3 dhcpv6_options @d2
4005
33ac3c83
NS
4006ovn-nbctl ls-add ls2
4007ovn-nbctl lsp-add ls2 ls2-lp1 \
4008-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4009ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4010ovn-nbctl lsp-add ls2 ls2-lp2 \
4011-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4012ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4013
4014net_add n1
4015sim_add hv1
4016
4017as hv1
4018ovs-vsctl add-br br-phys
4019ovn_attach n1 br-phys 192.168.0.1
4020ovs-vsctl -- add-port br-int hv1-vif1 -- \
4021 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4022 options:tx_pcap=hv1/vif1-tx.pcap \
4023 options:rxq_pcap=hv1/vif1-rx.pcap \
4024 ofport-request=1
4025
4026ovs-vsctl -- add-port br-int hv1-vif2 -- \
4027 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4028 options:tx_pcap=hv1/vif2-tx.pcap \
4029 options:rxq_pcap=hv1/vif2-rx.pcap \
4030 ofport-request=2
4031
4032ovs-vsctl -- add-port br-int hv1-vif3 -- \
4033 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4034 options:tx_pcap=hv1/vif3-tx.pcap \
4035 options:rxq_pcap=hv1/vif3-rx.pcap \
4036 ofport-request=3
4037
4038ovs-vsctl -- add-port br-int hv1-vif4 -- \
4039 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4040 options:tx_pcap=hv1/vif4-tx.pcap \
4041 options:rxq_pcap=hv1/vif4-rx.pcap \
4042 ofport-request=4
4043
40df4566
ZKL
4044ovs-vsctl -- add-port br-int hv1-vif5 -- \
4045 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4046 options:tx_pcap=hv1/vif5-tx.pcap \
4047 options:rxq_pcap=hv1/vif5-rx.pcap \
4048 ofport-request=5
4049
33ac3c83
NS
4050ovn_populate_arp
4051
4052sleep 2
4053
4054trim_zeros() {
4055 sed 's/\(00\)\{1,\}$//'
4056}
4057
4058# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4059# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4060# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4061# packet should be received twice (one from ovn-controller and the other
4062# from the "ovs-ofctl monitor br-int resume"
4063test_dhcpv6() {
4064 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4065 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4066 # dst ip ff02::1:2
ab187e7e 4067 request=${request}ff020000000000000000000000010002
33ac3c83 4068 # udp header and dhcpv6 header
ab187e7e 4069 request=${request}02220223002affff${msg_code}010203
33ac3c83 4070 # Client identifier
ab187e7e 4071 request=${request}0001000a00030001${src_mac}
33ac3c83 4072 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 4073 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
4074 shift; shift; shift; shift; shift;
4075 if test $offer_ip != 0; then
4076 local server_mac=000000100001
4077 local server_lla=fe80000000000000020000fffe100001
4078 local reply_code=07
4079 if test $msg_code = 01; then
4080 reply_code=02
4081 fi
40df4566
ZKL
4082 local msg_len=54
4083 if test $offer_ip = 1; then
4084 msg_len=28
4085 fi
4086 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4087 # udp header and dhcpv6 header
ab187e7e 4088 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4089 # Client identifier
ab187e7e 4090 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4091 # IA-NA
40df4566 4092 if test $offer_ip != 1; then
ab187e7e 4093 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4094 fi
33ac3c83 4095 # Server identifier
ab187e7e 4096 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4097 echo $reply | trim_zeros >> $inport.expected
4098 else
4099 for outport; do
4100 echo $request | trim_zeros >> $outport.expected
4101 done
4102 fi
4103
4104 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4105}
4106
4107reset_pcap_file() {
4108 local iface=$1
4109 local pcap_file=$2
4110 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4111options:rxq_pcap=dummy-rx.pcap
4112 rm -f ${pcap_file}*.pcap
4113 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4114options:rxq_pcap=${pcap_file}-rx.pcap
4115}
4116
4117AT_CAPTURE_FILE([ofctl_monitor0.log])
4118as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4119--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4120
4121echo "---------NB dump-----"
4122ovn-nbctl show
4123echo "---------------------"
4124echo "---------SB dump-----"
4125ovn-sbctl list datapath_binding
4126echo "---------------------"
4127ovn-sbctl list logical_flow
4128echo "---------------------"
4129
4130echo "---------------------"
4131ovn-sbctl dump-flows
4132echo "---------------------"
4133
4134echo "------ hv1 dump ----------"
4135as hv1 ovs-ofctl dump-flows br-int
4136
4137src_mac=f00000000001
4138src_lla=fe80000000000000f20000fffe000001
4139offer_ip=ae700000000000000000000000000004
4140test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4141
4142# NXT_RESUMEs should be 1.
4143OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4144
4145$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4146# cat 1.expected | trim_zeros > expout
4147cat 1.expected | cut -c -120 > expout
4148AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4149# Skipping the UDP checksum
4150cat 1.expected | cut -c 125- > expout
4151AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4152
4153rm 1.expected
4154
4155# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4156# without any modifications and the packet should be received by ls1-lp1.
4157# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4158# resume and the other from ovs-ofctl monitor resume.
4159
4160reset_pcap_file hv1-vif1 hv1/vif1
4161reset_pcap_file hv1-vif2 hv1/vif2
4162
4163src_mac=f00000000002
4164src_lla=fe80000000000000f20000fffe000002
4165offer_ip=ae700000000000000000000000000005
4166# Set invalid msg_type
4167
4168test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4169
4170# NXT_RESUMEs should be 2.
4171OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4172
4173# vif2-tx.pcap should not have received the DHCPv6 reply packet
4174rm 2.packets
4175$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4176AT_CHECK([cat 2.packets], [0], [])
4177
4178# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4179$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4180cat 1.expected > expout
4181AT_CHECK([cat 1.packets], [0], [expout])
4182
4183# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4184# There should be no DHCPv6 reply from ovn-controller and the request packet
4185# should be received by ls2-lp2.
4186
4187src_mac=f00000000003
4188src_lla=fe80000000000000f20000fffe000003
4189test_dhcpv6 3 $src_mac $src_lla 01 0 4
4190
4191# NXT_RESUMEs should be 2 only.
4192OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4193
4194# vif3-tx.pcap should not have received the DHCPv6 reply packet
4195$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4196AT_CHECK([cat 3.packets], [0], [])
4197
4198# vif4-tx.pcap should have received the DHCPv6 request packet
4199$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4200cat 4.expected > expout
4201AT_CHECK([cat 4.packets], [0], [expout])
4202
40df4566
ZKL
4203# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4204# The DHCPv6 reply should doesn't contian offer_ip.
4205src_mac=f00000000022
4206src_lla=fe80000000000000f20000fffe000022
4207reset_pcap_file hv1-vif5 hv1/vif5
4208test_dhcpv6 5 $src_mac $src_lla 01 1 5
4209
4210# NXT_RESUMEs should be 3.
4211OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4212
4213$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4214# Skipping the UDP checksum
4215cat 5.expected | cut -c 1-120,125- > expout
4216AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4217
33ac3c83 4218as hv1
281977f7
NS
4219OVS_APP_EXIT_AND_WAIT([ovn-controller])
4220OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4221OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4222
4223as ovn-sb
4224OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4225
4226as ovn-nb
4227OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4228
4229as northd
4230OVS_APP_EXIT_AND_WAIT([ovn-northd])
4231
4232as main
4233OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4234OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4235
4236AT_CLEANUP
4237
c1645003 4238AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4239AT_SKIP_IF([test $HAVE_PYTHON = no])
4240ovn_start
4241
4242# Logical network:
4243# Two LRs - R1 and R2 that are connected to each other via LS "join"
4244# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4245# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4246# R2 is a gateway router.
4247
4248
4249
4250# Create two hypervisor and create OVS ports corresponding to logical ports.
4251net_add n1
4252
4253sim_add hv1
4254as hv1
4255ovs-vsctl add-br br-phys
4256ovn_attach n1 br-phys 192.168.0.1
4257ovs-vsctl -- add-port br-int hv1-vif1 -- \
4258 set interface hv1-vif1 external-ids:iface-id=foo1 \
4259 options:tx_pcap=hv1/vif1-tx.pcap \
4260 options:rxq_pcap=hv1/vif1-rx.pcap \
4261 ofport-request=1
4262
4263
4264sim_add hv2
4265as hv2
4266ovs-vsctl add-br br-phys
4267ovn_attach n1 br-phys 192.168.0.2
4268ovs-vsctl -- add-port br-int hv2-vif1 -- \
4269 set interface hv2-vif1 external-ids:iface-id=alice1 \
4270 options:tx_pcap=hv2/vif1-tx.pcap \
4271 options:rxq_pcap=hv2/vif1-rx.pcap \
4272 ofport-request=1
4273
4274# Pre-populate the hypervisors' ARP tables so that we don't lose any
4275# packets for ARP resolution (native tunneling doesn't queue packets
4276# for ARP resolution).
4277ovn_populate_arp
4278
4279ovn-nbctl create Logical_Router name=R1
4280ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4281
ea46a4e9
JP
4282ovn-nbctl ls-add foo
4283ovn-nbctl ls-add alice
4284ovn-nbctl ls-add join
c1645003
GS
4285
4286# Connect foo to R1
31114af7 4287ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4288ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4289 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4290
4291# Connect alice to R2
31114af7 4292ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4293ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4294 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4295
4296# Connect R1 to join
31114af7 4297ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4298ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4299 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4300
4301# Connect R2 to join
31114af7 4302ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4303ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4304 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4305
4306
4307#install static routes
4308ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4309ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4310R1 static_routes @lrt
4311
4312ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4313ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4314R2 static_routes @lrt
4315
4316# Create logical port foo1 in foo
31ed1192
JP
4317ovn-nbctl lsp-add foo foo1 \
4318-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4319
4320# Create logical port alice1 in alice
31ed1192
JP
4321ovn-nbctl lsp-add alice alice1 \
4322-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4323
4324
4325# Allow some time for ovn-northd and ovn-controller to catch up.
4326# XXX This should be more systematic.
4327sleep 2
4328
4329ip_to_hex() {
4330 printf "%02x%02x%02x%02x" "$@"
4331}
c1645003
GS
4332
4333# Send ip packets between foo1 and alice1
4334src_mac="f00000010203"
4335dst_mac="000001010203"
4336src_ip=`ip_to_hex 192 168 1 2`
4337dst_ip=`ip_to_hex 172 16 1 2`
4338packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4339
4340echo "---------NB dump-----"
4341ovn-nbctl show
4342echo "---------------------"
4343ovn-nbctl list logical_router
4344echo "---------------------"
4345ovn-nbctl list logical_router_port
4346echo "---------------------"
4347
4348echo "---------SB dump-----"
4349ovn-sbctl list datapath_binding
4350echo "---------------------"
4351ovn-sbctl list port_binding
4352echo "---------------------"
4353ovn-sbctl dump-flows
4354echo "---------------------"
4355ovn-sbctl list chassis
4356ovn-sbctl list encap
4357echo "---------------------"
4358
c1645003
GS
4359# Packet to Expect at alice1
4360src_mac="000002010203"
4361dst_mac="f00000010204"
4362src_ip=`ip_to_hex 192 168 1 2`
4363dst_ip=`ip_to_hex 172 16 1 2`
4364expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4365
4366
4367as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4368as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4369
ab39371d
RM
4370echo "------ hv1 dump after packet 1 ----------"
4371as hv1 ovs-ofctl show br-int
4372as hv1 ovs-ofctl dump-flows br-int
4373echo "------ hv2 dump after packet 1 ----------"
4374as hv2 ovs-ofctl show br-int
4375as hv2 ovs-ofctl dump-flows br-int
4376echo "----------------------------"
4377
49d7c759
BP
4378echo $expected > expected
4379OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4380
34114cf8
GS
4381# Delete the router and re-create it. Things should work as before.
4382ovn-nbctl lr-del R2
4383ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4384# Connect alice to R2
4385ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4386# Connect R2 to join
4387ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4388
4389ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4390ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4391R2 static_routes @lrt
4392
4393# Wait for ovn-controller to catch up.
4394sleep 1
4395
4396# Send the packet again.
4397as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4398
4399echo "------ hv1 dump after packet 2 ----------"
4400as hv1 ovs-ofctl show br-int
4401as hv1 ovs-ofctl dump-flows br-int
4402echo "------ hv2 dump after packet 2 ----------"
4403as hv2 ovs-ofctl show br-int
4404as hv2 ovs-ofctl dump-flows br-int
4405echo "----------------------------"
4406
49d7c759
BP
4407echo $expected >> expected
4408OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4409
7a8f15e0 4410OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4411
4412AT_CLEANUP
bb3c4568
FF
4413
4414AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4415AT_KEYWORDS([router-icmp-reply])
4416AT_SKIP_IF([test $HAVE_PYTHON = no])
4417ovn_start
4418
4419# Logical network:
4420# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4421# and has switch ls2 (172.16.1.0/24) connected to it.
4422
fa2a27b2 4423ovn-nbctl lr-add R1
bb3c4568 4424
ea46a4e9
JP
4425ovn-nbctl ls-add ls1
4426ovn-nbctl ls-add ls2
bb3c4568
FF
4427
4428# Connect ls1 to R1
31114af7 4429ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4430ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4431 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4432
4433# Connect ls2 to R1
31114af7 4434ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4435ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4436 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4437
4438# Create logical port ls1-lp1 in ls1
31ed1192
JP
4439ovn-nbctl lsp-add ls1 ls1-lp1 \
4440-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4441
4442# Create logical port ls2-lp1 in ls2
31ed1192
JP
4443ovn-nbctl lsp-add ls2 ls2-lp1 \
4444-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4445
4446# Create one hypervisor and create OVS ports corresponding to logical ports.
4447net_add n1
4448
4449sim_add hv1
4450as hv1
4451ovs-vsctl add-br br-phys
4452ovn_attach n1 br-phys 192.168.0.1
4453ovs-vsctl -- add-port br-int vif1 -- \
4454 set interface vif1 external-ids:iface-id=ls1-lp1 \
4455 options:tx_pcap=hv1/vif1-tx.pcap \
4456 options:rxq_pcap=hv1/vif1-rx.pcap \
4457 ofport-request=1
4458
4459ovs-vsctl -- add-port br-int vif2 -- \
4460 set interface vif2 external-ids:iface-id=ls2-lp1 \
4461 options:tx_pcap=hv1/vif2-tx.pcap \
4462 options:rxq_pcap=hv1/vif2-rx.pcap \
4463 ofport-request=1
4464
4465
4466# Allow some time for ovn-northd and ovn-controller to catch up.
4467# XXX This should be more systematic.
4468sleep 1
4469
4470
4471ip_to_hex() {
4472 printf "%02x%02x%02x%02x" "$@"
4473}
bb3c4568
FF
4474for i in 1 2; do
4475 : > vif$i.expected
4476done
4477# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4478#
4479# Causes a packet to be received on INPORT. The packet is an ICMPv4
4480# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4481# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4482# provided, then it should be the ip and icmp checksums of the packet
4483# responded; otherwise, no reply is expected.
4484# In the absence of an ip checksum calculation helpers, this relies
4485# on the caller to provide the checksums for the ip and icmp headers.
4486# XXX This should be more systematic.
4487#
4488# INPORT is an lport number, e.g. 11 for vif11.
4489# ETH_SRC and ETH_DST are each 12 hex digits.
4490# IPV4_SRC and IPV4_DST are each 8 hex digits.
4491# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4492# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4493test_ipv4_icmp_request() {
4494 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4495 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4496 shift; shift; shift; shift; shift; shift; shift
4497 shift; shift
4498
4499 # Use ttl to exercise section 4.2.2.9 of RFC1812
4500 local ip_ttl=01
4501 local icmp_id=5fbf
4502 local icmp_seq=0001
4503 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4504 local icmp_type_code_request=0800
4505 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4506 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4507
4508 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4509 if test X$exp_icmp_chksum != X; then
4510 # Expect to receive the reply, if any. In same port where packet was sent.
4511 # Note: src and dst fields are expected to be reversed.
4512 local icmp_type_code_response=0000
4513 local reply_icmp_ttl=fe
4514 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4515 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4516 echo $reply >> vif$inport.expected
4517 fi
4518}
4519
4520# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4521rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4522rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4523l1_ip=$(ip_to_hex 192 168 1 2)
4524l2_ip=$(ip_to_hex 172 16 1 2)
4525
4526# Ping router ip address that is on same subnet as the logical port
4527test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4528test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4529
4530# Ping router ip address that is on the other side of the logical ports
4531test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4532test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4533
4534echo "---------NB dump-----"
4535ovn-nbctl show
4536echo "---------------------"
4537ovn-nbctl list logical_router
4538echo "---------------------"
4539ovn-nbctl list logical_router_port
4540echo "---------------------"
4541
4542echo "---------SB dump-----"
4543ovn-sbctl list datapath_binding
4544echo "---------------------"
4545ovn-sbctl list logical_flow
4546echo "---------------------"
4547
4548echo "------ hv1 dump ----------"
4549as hv1 ovs-ofctl dump-flows br-int
4550
4551# Now check the packets actually received against the ones expected.
4552for inport in 1 2; do
49d7c759 4553 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4554done
4555
7a8f15e0 4556OVN_CLEANUP([hv1])
bb3c4568
FF
4557
4558AT_CLEANUP
94f79fcb
RB
4559
4560# 1 hypervisor, 1 port
4561# make sure that the port state is properly set to up and back down
4562# when created and deleted.
4563AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
4564ovn_start
4565
4566ovn-nbctl ls-add ls1
4567ovn-nbctl lsp-add ls1 lp1
4568ovn-nbctl lsp-set-addresses lp1 unknown
4569
4570net_add n1
4571sim_add hv1
4572as hv1 ovs-vsctl add-br br-phys
4573as hv1 ovn_attach n1 br-phys 192.168.0.1
4574
4575as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4576OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4577
4578as hv1 ovs-vsctl del-port br-int vif1
4579OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4580
7a8f15e0 4581OVN_CLEANUP([hv1])
94f79fcb 4582
94f79fcb 4583AT_CLEANUP
e75451fe 4584
ccc6e1db
FF
4585# 1 hypervisor, 1 port
4586# make sure that the OF rules created to support a datapath are added/cleared
4587# when logical switch is created and removed.
4588AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 4589AT_KEYWORDS([cleanup])
ccc6e1db
FF
4590ovn_start
4591
4592net_add n1
4593sim_add hv1
4594as hv1 ovs-vsctl add-br br-phys
4595as hv1 ovn_attach n1 br-phys 192.168.0.1
4596
4597# This shell function checks if OF rules in br-int have clauses
4598# related to OVN datapaths. The caller determines if it should find
4599# a match in the output, or not.
4600#
4601# EXPECT_DATAPATH param determines whether flows that refer to
4602# datapath to should be present or not. 0 means
4603# they should not be.
4604# STAGE_INFO param is a simple string to help identify the stage
4605# in the test when this function was invoked.
4606test_datapath_in_of_rules() {
4607 local expect_datapath=$1 stage_info=$2
4608 echo "------ ovn-nbctl show ${stage_info} ------"
4609 ovn-nbctl show
4610 echo "------ ovn-sbctl show ${stage_info} ------"
4611 ovn-sbctl show
4612 echo "------ OF rules ${stage_info} ------"
4613 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4614 # if there is a datapath mentioned in the output, check for the
4615 # magic keyword that represents one, based on the exit status of
4616 # a quiet grep
4617 if test $expect_datapath != 0; then
4618b102 4618 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 4619 else
4618b102 4620 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
4621 fi
4622}
4623
4624test_datapath_in_of_rules 0 "before ls+port create"
4625
4626ovn-nbctl ls-add ls1
4627ovn-nbctl lsp-add ls1 lp1
4628ovn-nbctl lsp-set-addresses lp1 unknown
4629
4630as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4631OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4632
4633test_datapath_in_of_rules 1 "after port is bound"
4634
4635as hv1 ovs-vsctl del-port br-int vif1
4636OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4637
4638ovn-nbctl lsp-set-addresses lp1
4639ovn-nbctl lsp-del lp1
4640ovn-nbctl ls-del ls1
4641
4642# wait for earlier changes to take effect
4643AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4644
4645# ensure OF rules are no longer present. There used to be a bug here.
4646test_datapath_in_of_rules 0 "after lport+ls removal"
4647
4648OVN_CLEANUP([hv1])
4649
4650AT_CLEANUP
4651
f8a8db39 4652AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
4653AT_SKIP_IF([test $HAVE_PYTHON = no])
4654ovn_start
4655
4656#TODO: since patch port for IPv6 logical router port is not ready not,
4657# so we are not going to test vifs on different lswitches cases. Try
4658# to update for that once relevant stuff implemented.
4659
4660# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4661# with. NS packet we test, from one VIF for another VIF, will be replied
4662# by local ovn-controller, but not by target VIF.
4663
4664# Create hypervisors and logical switch lsw0.
4665ovn-nbctl ls-add lsw0
4666net_add n1
4667sim_add hv1
4668as hv1
4669ovs-vsctl add-br br-phys
4670ovn_attach n1 br-phys 192.168.0.2
4671
4672# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4673ovs-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
4674ovn-nbctl lsp-add lsw0 lp1
4675ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4676ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4677
4678# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4679ovs-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
4680ovn-nbctl lsp-add lsw0 lp2
4681ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4682ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4683
4684# Add ACL rule for ICMPv6 on lsw0
4685ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4686ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4687ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4688
4689# Allow some time for ovn-northd and ovn-controller to catch up.
4690# XXX This should be more systematic.
4691sleep 1
4692
4693# Given the name of a logical port, prints the name of the hypervisor
4694# on which it is located.
4695vif_to_hv() {
4696 echo hv1${1%?}
4697}
e75451fe
ZKL
4698for i in 1 2; do
4699 : > $i.expected
4700done
4701
4702# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4703# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4704# vif2 will not receive NS packet, since ovn-controller will reply for it.
4705ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4706na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4707
4708as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 4709echo $na_packet >> 1.expected
e75451fe 4710
e75451fe
ZKL
4711echo "------ hv1 dump ------"
4712as hv1 ovs-vsctl show
4713as hv1 ovs-ofctl -O OpenFlow13 show br-int
4714as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4715
4716for i in 1 2; do
49d7c759 4717 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
4718done
4719
7a8f15e0 4720OVN_CLEANUP([hv1])
e75451fe
ZKL
4721
4722AT_CLEANUP
7417d147
RM
4723
4724AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
4725ovn_start
4726
4727net_add n1
4728
4729sim_add hv1
4730as hv1
4731ovs-vsctl add-br br-phys
4732ovn_attach n1 br-phys 192.168.0.1
4733
4734row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4735ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4736ovn-nbctl destroy Address_Set $row
4737
4738sleep 1
4739
4740# A bug previously existed in the address set support code
4741# that caused ovn-controller to crash after an address set
4742# was updated and then removed. This test case ensures
4743# that ovn-controller is at least still running after
4744# creating, updating, and deleting an address set.
4745AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4746
4747OVN_CLEANUP([hv1])
4748
4749AT_CLEANUP
8639f9be
ND
4750
4751AT_SETUP([ovn -- ipam])
8639f9be
ND
4752AT_SKIP_IF([test $HAVE_PYTHON = no])
4753ovn_start
4754
4755# Add a port to a switch that does not have a subnet set, then set the
4756# subnet which should result in an address being allocated for the port.
4757ovn-nbctl ls-add sw0
4758ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 4759ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
4760AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4761 ["0a:00:00:00:00:01 192.168.1.2"
4762])
4763
4764# Add 9 more ports to sw0, addresses should all be unique.
4765for n in `seq 1 9`; do
11547f85 4766 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4767done
4768AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4769 ["0a:00:00:00:00:02 192.168.1.3"
4770])
4771AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4772 ["0a:00:00:00:00:03 192.168.1.4"
4773])
4774AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4775 ["0a:00:00:00:00:04 192.168.1.5"
4776])
4777AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4778 ["0a:00:00:00:00:05 192.168.1.6"
4779])
4780AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4781 ["0a:00:00:00:00:06 192.168.1.7"
4782])
4783AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4784 ["0a:00:00:00:00:07 192.168.1.8"
4785])
4786AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4787 ["0a:00:00:00:00:08 192.168.1.9"
4788])
4789AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4790 ["0a:00:00:00:00:09 192.168.1.10"
4791])
4792AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4793 ["0a:00:00:00:00:0a 192.168.1.11"
4794])
4795
4796# Trying similar tests with a second switch. MAC addresses should be unique
4797# across both switches but IP's only need to be unique within the same switch.
4798ovn-nbctl ls-add sw1
4799ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 4800ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
4801AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4802 ["0a:00:00:00:00:0b 192.168.1.2"
4803])
4804
4805for n in `seq 11 19`; do
11547f85 4806 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4807done
4808AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4809 ["0a:00:00:00:00:0c 192.168.1.3"
4810])
4811AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4812 ["0a:00:00:00:00:0d 192.168.1.4"
4813])
4814AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4815 ["0a:00:00:00:00:0e 192.168.1.5"
4816])
4817AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4818 ["0a:00:00:00:00:0f 192.168.1.6"
4819])
4820AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4821 ["0a:00:00:00:00:10 192.168.1.7"
4822])
4823AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4824 ["0a:00:00:00:00:11 192.168.1.8"
4825])
4826AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4827 ["0a:00:00:00:00:12 192.168.1.9"
4828])
4829AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4830 ["0a:00:00:00:00:13 192.168.1.10"
4831])
4832AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4833 ["0a:00:00:00:00:14 192.168.1.11"
4834])
4835
4836# Change a port's address to test for multiple ip's for a single address entry
4837# and addresses set by the user.
4838ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
11547f85 4839ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
4840AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4841 ["0a:00:00:00:00:16 192.168.1.13"
4842])
4843
4844# Test for logical router port address management.
4845ovn-nbctl create Logical_Router name=R1
4846ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4847network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4848-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4849-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 4850ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
4851AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4852 ["0a:00:00:00:00:18 192.168.1.15"
4853])
4854
4855# Test for address reuse after logical port is deleted.
4856ovn-nbctl lsp-del p0
11547f85 4857ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
4858AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4859 ["0a:00:00:00:00:19 192.168.1.2"
4860])
4861
4862# Test for multiple addresses to one logical port.
4863ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4864"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 4865ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
4866AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4867 ["0a:00:00:00:00:1c 192.168.1.16"
4868])
4869
4870# Test for exhausting subnet address space.
4871ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 4872ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
4873AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4874 ["0a:00:00:00:00:1d 172.16.1.2"
4875])
4876
11547f85 4877ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 4878AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
7cc0741e 4879 ["0a:00:00:00:00:1e"
8639f9be
ND
4880])
4881
4882# Test that address management does not add duplicate MAC for lsp/lrp peers.
4883ovn-nbctl create Logical_Router name=R2
4884ovn-nbctl ls-add sw3
4885ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
7cc0741e 4886"0a:00:00:00:00:1f"
8639f9be
ND
4887ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4888network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4889-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4890-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 4891ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
4892AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4893 ["0a:00:00:00:00:20 192.168.1.17"
4894])
4895
6374d518
LR
4896# Test static MAC address with dynamically allocated IP
4897ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
4898"fe:dc:ba:98:76:54 dynamic"
4899AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4900 ["fe:dc:ba:98:76:54 192.168.1.18"
4901])
4902
6c4f7a8a
NS
4903# Update the static MAC address with dynamically allocated IP and check
4904# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
4905ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
4906ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
4907
4908AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4909 ["fe:dc:ba:98:76:55 192.168.1.18"
4910])
4911
4912ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
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 "fe:dc:ba:98:76:56 dynamic"
4918AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4919 ["fe:dc:ba:98:76:56 192.168.1.18"
4920])
4921
161ea2c8
NS
4922
4923# Test the exclude_ips from the IPAM list
4924ovn-nbctl --wait=sb set logical_switch sw0 \
4925other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
4926
4927ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
4928"dynamic"
4929# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
4930AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
4931 ["0a:00:00:00:00:21 192.168.1.20"
4932])
4933
4934ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
4935"dynamic"
4936# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
4937AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
4938 ["0a:00:00:00:00:22 192.168.1.22"
4939])
4940
4941ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
4942"dynamic"
4943# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
4944AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
4945 ["0a:00:00:00:00:23 192.168.1.51"
4946])
4947
4948# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
4949ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
4950ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
4951"dynamic"
4952AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
4953 ["0a:00:00:00:00:24 192.168.1.19"
4954])
4955
4956# Set invalid data in exclude_ips list. It should be ignored.
4957ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
4958ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
4959"dynamic"
4960# 192.168.1.21 should be assigned as that's the next free one.
4961AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
4962 ["0a:00:00:00:00:25 192.168.1.21"
4963])
4964
4965# Clear the dynamic addresses assignment request.
4966ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
4967AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
4968 [[[]]
4969])
4970
7cc0741e
NS
4971# Set IPv6 prefix
4972ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
4973ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
4974"dynamic"
4975
4976# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
4977# - aef0::800:ff:fe00:26 (EUI64)
4978AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
4979 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
4980])
4981
4982ovn-nbctl --wait=sb ls-add sw4
4983ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
4984ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
4985"dynamic"
4986
4987AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
4988 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
4989])
4990
4991ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
4992"f0:00:00:00:10:12 dynamic"
4993
4994AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
4995 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
4996])
4997
4998# Clear the other_config for sw4. No dynamic ip should be assigned.
4999ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5000ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5001"dynamic"
5002
5003AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5004 [[[]]
5005])
5006
5007# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5008ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5009-- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5010
5011# Now p40 should be assigned with dynamic addresses.
5012AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5013 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5014])
5015
5016ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5017"dynamic"
5018# p41 should not have IPv4 address (as the pool is exhausted).
5019AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5020 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5021])
5022
8639f9be
ND
5023as ovn-sb
5024OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5025
5026as ovn-nb
5027OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5028
5029as northd
5030OVS_APP_EXIT_AND_WAIT([ovn-northd])
5031
5032AT_CLEANUP
5033
5034AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5035AT_SKIP_IF([test $HAVE_PYTHON = no])
5036ovn_start
5037
5038ovn-nbctl lr-add R1
5039
5040# Test for a ping using dynamically allocated addresses.
5041ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5042ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5043
5044# Connect foo to R1
5045ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5046ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5047 options:router-port=foo \
5048 -- lsp-set-addresses rp-foo router
8639f9be
ND
5049
5050# Connect alice to R1
5051ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5052ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5053 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5054
5055# Create logical port foo1 in foo
fd3b31e9 5056ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5057-- lsp-set-addresses foo1 "dynamic"
8bc2c143 5058AT_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
5059
5060# Create logical port alice1 in alice
fd3b31e9 5061ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5062-- lsp-set-addresses alice1 "dynamic"
8bc2c143 5063AT_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
5064
5065# Create logical port foo2 in foo
fd3b31e9 5066ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5067-- lsp-set-addresses foo2 "dynamic"
8bc2c143 5068AT_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
5069
5070# Create a hypervisor and create OVS ports corresponding to logical ports.
5071net_add n1
5072
5073sim_add hv1
5074as hv1
5075ovs-vsctl add-br br-phys
5076ovn_attach n1 br-phys 192.168.0.1
5077ovs-vsctl -- add-port br-int hv1-vif1 -- \
5078 set interface hv1-vif1 external-ids:iface-id=foo1 \
5079 options:tx_pcap=hv1/vif1-tx.pcap \
5080 options:rxq_pcap=hv1/vif1-rx.pcap \
5081 ofport-request=1
5082
5083ovs-vsctl -- add-port br-int hv1-vif2 -- \
5084 set interface hv1-vif2 external-ids:iface-id=foo2 \
5085 options:tx_pcap=hv1/vif2-tx.pcap \
5086 options:rxq_pcap=hv1/vif2-rx.pcap \
5087 ofport-request=2
5088
5089ovs-vsctl -- add-port br-int hv1-vif3 -- \
5090 set interface hv1-vif3 external-ids:iface-id=alice1 \
5091 options:tx_pcap=hv1/vif3-tx.pcap \
5092 options:rxq_pcap=hv1/vif3-rx.pcap \
5093 ofport-request=3
5094
5095# Allow some time for ovn-northd and ovn-controller to catch up.
5096# XXX This should be more systematic.
5097sleep 1
5098
5099ip_to_hex() {
5100 printf "%02x%02x%02x%02x" "$@"
5101}
8639f9be
ND
5102
5103# Send ip packets between foo1 and foo2
5104src_mac="0a0000000001"
5105dst_mac="0a0000000003"
5106src_ip=`ip_to_hex 192 168 1 2`
5107dst_ip=`ip_to_hex 192 168 1 3`
5108packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5109as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5110
5111# Send ip packets between foo1 and alice1
5112src_mac="0a0000000001"
5113dst_mac="000000010203"
5114src_ip=`ip_to_hex 192 168 1 2`
5115dst_ip=`ip_to_hex 192 168 2 2`
5116packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5117as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5118
5119echo "---------NB dump-----"
5120ovn-nbctl show
5121echo "---------------------"
5122ovn-nbctl list logical_router
5123echo "---------------------"
5124ovn-nbctl list logical_router_port
5125echo "---------------------"
5126
5127echo "---------SB dump-----"
5128ovn-sbctl list datapath_binding
5129echo "---------------------"
5130ovn-sbctl list port_binding
5131echo "---------------------"
5132
5133echo "------ hv1 dump ----------"
5134as hv1 ovs-ofctl dump-flows br-int
5135
5136# Packet to Expect at foo2
5137src_mac="0a0000000001"
5138dst_mac="0a0000000003"
5139src_ip=`ip_to_hex 192 168 1 2`
5140dst_ip=`ip_to_hex 192 168 1 3`
5141expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5142
e4543cfe
DDP
5143$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5144echo $expected > expout
8639f9be
ND
5145AT_CHECK([cat received1.packets], [0], [expout])
5146
5147# Packet to Expect at alice1
5148src_mac="000000010204"
5149dst_mac="0a0000000002"
5150src_ip=`ip_to_hex 192 168 1 2`
5151dst_ip=`ip_to_hex 192 168 2 2`
5152expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5153
e4543cfe
DDP
5154$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5155echo $expected > expout
8639f9be
ND
5156AT_CHECK([cat received2.packets], [0], [expout])
5157
5158OVN_CLEANUP([hv1])
5159
5160AT_CLEANUP
f5792c3f
NS
5161
5162AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5163AT_KEYWORDS([vswitchd])
f5792c3f
NS
5164AT_SKIP_IF([test $HAVE_PYTHON = no])
5165ovn_start
5166
5167ovn-nbctl ls-add ls1
5168
5169ovn-nbctl lsp-add ls1 ls1-lp1 \
5170-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5171
5172ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5173
5174net_add n1
5175sim_add hv1
5176
5177as hv1
5178ovs-vsctl add-br br-phys
5179ovn_attach n1 br-phys 192.168.0.1
5180ovs-vsctl -- add-port br-int hv1-vif1 -- \
5181 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5182 options:tx_pcap=hv1/vif1-tx.pcap \
5183 options:rxq_pcap=hv1/vif1-rx.pcap \
5184 ofport-request=1
5185
5186ovn_populate_arp
5187sleep 2
5188
5189as hv1 ovs-vsctl show
5190
5191echo "---------------------"
5192ovn-sbctl dump-flows
5193echo "---------------------"
5194
5195echo "------ hv1 dump ----------"
5196as hv1 ovs-ofctl dump-flows br-int
5197total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5198
5199echo "Total flows before vswitchd restart = " $total_flows
5200
5201# Code taken from ovs-save utility
5202save_flows () {
5203 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5204 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5205 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5206 echo "EOF" >> restore_flows.sh
5207}
5208
5209restart_vswitchd () {
5210 restore_flows=$1
5211
5212 if test $restore_flows = true; then
5213 save_flows
5214 fi
5215
5216 as hv1
5217 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5218
5219 if test $restore_flows = true; then
5220 as hv1
5221 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5222 fi
5223
5224 as hv1
5225 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5226 ovs-ofctl dump-flows br-int
5227
5228 if test $restore_flows = true; then
5229 sh ./restore_flows.sh
5230 echo "Flows after restore"
5231 as hv1
5232 ovs-ofctl dump-flows br-int
5233 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5234 flow-restore-wait="true"
5235 fi
5236}
5237
5238# Save the flows, restart vswitchd and restore the flows
5239restart_vswitchd true
5240OVS_WAIT_UNTIL([
5241 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5242 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5243 test "${total_flows}" = "${total_flows_after_restart}"
5244])
5245
5246# Restart vswitchd without restoring
5247restart_vswitchd false
5248OVS_WAIT_UNTIL([
5249 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5250 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5251 test "${total_flows}" = "${total_flows_after_restart}"
5252])
5253
5254OVN_CLEANUP([hv1])
5255AT_CLEANUP
47021598
CSV
5256
5257AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5258AT_SKIP_IF([test $HAVE_PYTHON = no])
5259ovn_start
5260
5261# Topology: Two LSs - ls1 and ls2 are connected via router r0
5262
5263# Create logical switches
5264ovn-nbctl ls-add ls1
5265ovn-nbctl ls-add ls2
5266
5267# Create router
5268ovn-nbctl create Logical_Router name=lr0
5269
5270# Add router ls1p1 port to gateway router
5271ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5272ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5273 type=router options:router-port=lrp-ls1lp1 \
5274 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5275
5276# Add router ls2p2 port to gateway router
5277ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5278ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5279 type=router options:router-port=lrp-ls2lp1 \
5280 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5281
5282# Set default gateway (nexthop) to 192.168.1.254
5283ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5284
5285# Create logical port ls1lp2 in ls1
5286ovn-nbctl lsp-add ls1 ls1lp2 \
5287-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5288
5289# Create logical port ls2lp2 in ls2
5290ovn-nbctl lsp-add ls2 ls2lp2 \
5291-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5292
5293net_add n1
5294sim_add hv1
5295as hv1
5296ovs-vsctl add-br br-phys
5297ovn_attach n1 br-phys 192.168.0.1
5298ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5299 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5300 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5301 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5302 ofport-request=1
5303ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5304 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5305 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5306 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5307 ofport-request=2
5308
5309# Allow some time for ovn-northd and ovn-controller to catch up.
5310# XXX This should be more systematic.
5311sleep 1
5312
5313echo "---------NB dump-----"
5314ovn-nbctl show
5315echo "---------------------"
5316ovn-nbctl list logical_router
5317echo "---------------------"
5318ovn-nbctl list logical_router_port
5319echo "---------------------"
5320
5321echo "---------SB dump-----"
5322ovn-sbctl list datapath_binding
5323echo "---------------------"
5324ovn-sbctl list port_binding
5325echo "---------------------"
5326ovn-sbctl dump-flows
5327echo "---------------------"
5328ovn-sbctl list chassis
5329ovn-sbctl list encap
5330echo "---------------------"
5331
5332echo "------Flows dump-----"
5333as hv1
5334ovs-ofctl dump-flows
5335echo "---------------------"
5336
5337ip_to_hex() {
5338 printf "%02x%02x%02x%02x" "$@"
5339}
5340
5341src_mac="f00000000003"
5342dst_mac="f00000000001"
5343src_ip=`ip_to_hex 192 168 0 2`
5344dst_ip=`ip_to_hex 8 8 8 8`
5345packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5346
5347# Send IP packet destined to 8.8.8.8 from lsp1lp2
5348as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5349
5350trim_zeros() {
5351 sed 's/\(00\)\{1,\}$//'
5352}
5353
5354# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5355# not 8.8.8.8
5356
5357$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5358expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5359echo $expected > expout
5360AT_CHECK([cat packets], [0], [expout])
5361cat packets
5362
5363OVN_CLEANUP([hv1])
5364
5365AT_CLEANUP
8439c2eb
CSV
5366
5367AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5368AT_SKIP_IF([test $HAVE_PYTHON = no])
5369ovn_start
5370# Create logical switch
5371ovn-nbctl ls-add ls0
5372# Create gateway router
5373ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5374# Add router port to gateway router
5375ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5376ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5377 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
5378# Add nat-address option
5379ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5380
5381net_add n1
5382sim_add hv1
5383as hv1
5384ovs-vsctl \
5385 -- add-br br-phys \
5386 -- add-br br-eth0
5387
5388ovn_attach n1 br-phys 192.168.0.1
5389
5390AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5391AT_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])
5392
5393# Create a localnet port.
5394AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5395AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5396AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5397AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5398
5399
5400# Wait for packet to be received.
5401OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5402trim_zeros() {
5403 sed 's/\(00\)\{1,\}$//'
5404}
5405$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5406expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5407echo $expected > expout
5408AT_CHECK([sort packets], [0], [expout])
5409cat packets
5410
5411OVN_CLEANUP([hv1])
5412
5413AT_CLEANUP
6e31816f 5414
e914fb54
MS
5415AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5416AT_SKIP_IF([test $HAVE_PYTHON = no])
5417ovn_start
5418# Create logical switch
5419ovn-nbctl ls-add ls0
5420# Create gateway router
5421ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5422# Add router port to gateway router
5423ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5424ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5425 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
5426# Add nat-address option
5427ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5428# Add NAT rules
5429AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5430AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5431# Add load balancers
5432AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5433AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5434AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5435AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5436
5437net_add n1
5438sim_add hv1
5439as hv1
5440ovs-vsctl \
5441 -- add-br br-phys \
5442 -- add-br br-eth0
5443
5444ovn_attach n1 br-phys 192.168.0.1
5445
5446AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5447AT_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])
5448
5449# Create a localnet port.
5450AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5451AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5452AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5453AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5454
5455
5456# Wait for packet to be received.
5457OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5458trim_zeros() {
5459 sed 's/\(00\)\{1,\}$//'
5460}
5461$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5462expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5463echo $expected > expout
5464expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5465echo $expected >> expout
5466expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5467echo $expected >> expout
5468AT_CHECK([sort packets], [0], [expout])
5469cat packets
5470
5471OVN_CLEANUP([hv1])
5472
5473AT_CLEANUP
5474
6e31816f 5475AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
5476ovn_start
5477net_add n1
5478sim_add hv1
5479as hv1
5480ovs-vsctl -- add-br br-phys
5481ovn_attach n1 br-phys 192.168.0.1
5482# Create logical switch ls0
5483ovn-nbctl ls-add ls0
5484# Create ports lp0, lp1 in ls0
5485ovn-nbctl lsp-add ls0 lp0
5486ovn-nbctl lsp-add ls0 lp1
5487ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5488ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5489dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5490ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5491ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5492ovn-sbctl find MAC_Binding
093aa761 5493# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5494ovn-nbctl lsp-del lp0
5495ovn-sbctl find MAC_Binding
093aa761
BP
5496OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5497# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5498ovn-nbctl ls-del ls0
5499ovn-sbctl find MAC_Binding
093aa761 5500OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
5501
5502OVN_CLEANUP([hv1])
5503
5504AT_CLEANUP
926c34fd
RM
5505
5506AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
5507AT_SKIP_IF([test $HAVE_PYTHON = no])
5508ovn_start
5509
5510# Logical network:
5511# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5512# connected to a router R1.
5513# foo has foo1 to act as a client.
5514# bar has bar1, bar2, bar3 to act as servers.
5515
5516net_add n1
5517
5518sim_add hv1
5519as hv1
5520ovs-vsctl add-br br-phys
5521ovn_attach n1 br-phys 192.168.0.1
5522for i in foo1 bar1 bar2 bar3; do
5523 ovs-vsctl -- add-port br-int $i -- \
5524 set interface $i external-ids:iface-id=$i \
5525 options:tx_pcap=hv1/$i-tx.pcap \
5526 options:rxq_pcap=hv1/$i-rx.pcap
5527done
5528
5529ovn-nbctl create Logical_Router name=R1
5530ovn-nbctl ls-add foo
5531ovn-nbctl ls-add bar
5532
5533# Connect foo to R1
5534ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5535ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5536 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5537
5538# Connect bar to R1
5539ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5540ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5541 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5542
5543# Create logical port foo1 in foo
5544ovn-nbctl lsp-add foo foo1 \
5545-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5546
5547# Create logical port bar1, bar2 and bar3 in bar
5548for i in `seq 1 3`; do
5549 ip=`expr $i + 1`
5550 ovn-nbctl lsp-add bar bar$i \
5551 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5552done
5553
5554OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5555
5556OVN_CLEANUP([hv1])
5557
5558AT_CLEANUP
b511690b
GS
5559
5560AT_SETUP([ovn -- tag allocation])
b511690b
GS
5561ovn_start
5562
5563AT_CHECK([ovn-nbctl ls-add ls0])
5564AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5565AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5566AT_CHECK([ovn-nbctl ls-add ls1])
5567
5568dnl When a tag is provided, no allocation is done
5569AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5570AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5571])
5572dnl The same 'tag' gets created in southbound database.
5573AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5574logical_port="c0"], [0], [3
5575])
5576
5577dnl Allocate tags and see it getting created in both NB and SB
5578AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5579AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5580])
5581AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5582logical_port="c1"], [0], [1
5583])
5584
5585AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5586AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5587])
5588AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5589logical_port="c2"], [0], [2
5590])
5591AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5592AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5593])
5594AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5595logical_port="c3"], [0], [4
5596])
5597
5598dnl A different parent.
5599AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5600AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5601])
5602AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5603logical_port="c4"], [0], [1
5604])
5605
5606AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5607AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5608])
5609AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5610logical_port="c5"], [0], [2
5611])
5612
5613dnl Delete a logical port and create a new one.
5614AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5615AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5616AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5617])
5618AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5619logical_port="c6"], [0], [1
5620])
5621
5622dnl Restart northd to see that the same allocation remains.
5623as northd
5624OVS_APP_EXIT_AND_WAIT([ovn-northd])
5625start_daemon ovn-northd \
5626 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5627 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5628
5629dnl Create a switch to make sure that ovn-northd has run through the main loop.
5630AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5631AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5632])
5633AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5634])
5635AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5636])
5637AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5638])
5639AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5640])
5641AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5642])
5643
5644dnl Create a switch port with a tag that has already been allocated.
5645dnl It should go through fine with a duplicate tag.
5646AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5647AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5648])
5649AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5650logical_port="c7"], [0], [2
5651])
5652AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5653])
5654
5655AT_CHECK([ovn-nbctl ls-add ls2])
5656dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5657dnl gets copied to 'tag'
5658AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5659AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5660])
5661dnl The same 'tag' gets created in southbound database.
5662AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5663logical_port="local0"], [0], [25
5664])
5665dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5666AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5667AT_CHECK([ovn-nbctl lsp-get-tag local1])
5668dnl change the tag_request.
5669AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5670AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5671])
5672
5673AT_CLEANUP
57afd0c0
RR
5674
5675AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
5676ovn_start
5677ovn-nbctl ls-add lsw0
5678net_add n1
5679for i in 1 2; do
5680 sim_add hv$i
5681 as hv$i
5682 ovs-vsctl add-br br-phys
5683 ovn_attach n1 br-phys 192.168.0.$i
5684 ovs-vsctl add-br br-eth0
5685 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5686done
5687
5688# Create a localnet port.
5689AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5690AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5691AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5692AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5693
5694
5695# Create 3 vifs.
5696AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5697AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5698AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5699AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5700AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5701AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5702AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5703AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5704AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5705
5706# Bind the localvif1 to hv1.
5707as hv1
5708AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5709
5710# On hv1, check that there are no flows outputting bcast to tunnel
5711OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5712
1ea9b847 5713# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 5714as hv2
1ea9b847 5715OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
5716
5717# Now bind vif2 on hv2.
5718AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5719
5720# At this point, the broadcast flow on vif2 should be deleted.
5721# because, there is now a localnet vif bound (table=32 programming logic)
5722OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5723
5724# Verify that the local net patch port exists on hv2.
5725OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5726
5727# Now bind vif3 on hv2.
5728AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5729
5730# Verify that the local net patch port still exists on hv2
5731OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5732
5733# Delete localvif2
5734AT_CHECK([ovn-nbctl lsp-del localvif2])
5735
5736# Verify that the local net patch port still exists on hv2,
5737# because, localvif3 is still bound.
5738OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5739
57afd0c0 5740OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
5741
5742AT_CLEANUP
5743
d383eed5
JP
5744
5745AT_SETUP([ovn -- ACL logging])
5746AT_KEYWORDS([ovn])
5747ovn_start
5748
5749net_add n1
5750
5751sim_add hv
5752as hv
5753ovs-vsctl add-br br-phys
5754ovn_attach n1 br-phys 192.168.0.1
5755for i in lp1 lp2; do
5756 ovs-vsctl -- add-port br-int $i -- \
5757 set interface $i external-ids:iface-id=$i \
5758 options:tx_pcap=hv/$i-tx.pcap \
5759 options:rxq_pcap=hv/$i-rx.pcap
5760done
5761
5762lp1_mac="f0:00:00:00:00:01"
5763lp1_ip="192.168.1.2"
5764
5765lp2_mac="f0:00:00:00:00:02"
5766lp2_ip="192.168.1.3"
5767
5768ovn-nbctl ls-add lsw0
5769ovn-nbctl --wait=sb lsp-add lsw0 lp1
5770ovn-nbctl --wait=sb lsp-add lsw0 lp2
5771ovn-nbctl lsp-set-addresses lp1 $lp1_mac
5772ovn-nbctl lsp-set-addresses lp2 $lp2_mac
5773ovn-nbctl --wait=sb sync
5774
5775ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
5776ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
5777
5778ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
5779ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
5780
5781ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
5782ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
5783
5784ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
5785ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
5786
5787ovn-sbctl dump-flows
5788
5789
5790# Send packet that should be dropped without logging.
5791packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5792 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5793 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
5794as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5795
5796# Send packet that should be dropped with logging.
5797packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5798 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5799 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
5800as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5801
5802# Send packet that should be allowed without logging.
5803packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5804 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5805 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
5806as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5807
5808# Send packet that should be allowed with logging.
5809packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5810 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5811 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
5812as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5813
5814# Send packet that should allow related flows without logging.
5815packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5816 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5817 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
5818as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5819
5820# Send packet that should allow related flows with logging.
5821packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5822 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5823 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
5824as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5825
5826# Send packet that should allow related flows with logging.
5827packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5828 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5829 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
5830as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5831
5832# Send packet that should allow related flows with logging.
5833packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5834 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5835 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
5836as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5837
5838AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
5839name="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
5840name="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
5841name="<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
5842name="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
5843])
5844
5845OVN_CLEANUP([hv])
5846AT_CLEANUP
5847
5848
1a03fc7d
BS
5849AT_SETUP([ovn -- DSCP marking check])
5850AT_KEYWORDS([ovn])
5851ovn_start
5852
5853ovn-nbctl ls-add lsw0
5854ovn-nbctl --wait=sb lsp-add lsw0 lp1
5855ovn-nbctl --wait=sb lsp-add lsw0 lp2
5856ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5857ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5858ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5859ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5860ovn-nbctl --wait=sb sync
5861net_add n1
5862sim_add hv
5863as hv
5864ovs-vsctl add-br br-phys
5865ovn_attach n1 br-phys 192.168.0.1
5866ovs-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
5867ovs-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
5868
5869AT_CAPTURE_FILE([trace])
5870ovn_trace () {
5871 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5872}
5873
5874# Extracts nw_tos from the final flow from ofproto/trace output and prints
5875# it on stdout. Prints "none" if no nw_tos was included.
5876get_final_nw_tos() {
5877 if flow=$(grep '^Final flow:' stdout); then :; else
5878 # The output didn't have a final flow.
5879 return 99
5880 fi
5881
5882 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5883 case $tos in
5884 '') echo none ;;
5885 *) echo $tos ;;
5886 esac
5887}
5888
5889# check_tos TOS
5890#
5891# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
5892check_tos() {
5893 # First check with ovn-trace for logical flows.
5894 echo "checking for tos $1"
5895 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
5896 echo 'output("lp2");') > expout
5897 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])
5898
5899 # Then re-check with ofproto/trace for a physical packet.
5900 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])
5901 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
5902])
5903}
5904
5905# check at L2
5906AT_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");
5907])
5908AT_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])
5909AT_CHECK([get_final_nw_tos], [0], [none
5910])
5911
5912# check at L3 without dscp marking
5913check_tos 0
5914
5915# Mark DSCP with a valid value
5916qos_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)
5917check_tos 48
5918
5919# Update the DSCP marking
5920ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
5921check_tos 63
5922
5923ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
5924check_tos 63
5925
5926# Disable DSCP marking
5927ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
5928check_tos 0
5929
5930OVN_CLEANUP([hv])
57afd0c0 5931AT_CLEANUP
7fff4eb7
LR
5932
5933AT_SETUP([ovn -- read-only sb db:ptcp access])
5934AT_SKIP_IF([test $HAVE_PYTHON = no])
5935
5936: > .$1.db.~lock~
5937ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5938
5939# Add read-only remote to sb ovsdb-server
5940AT_CHECK(
5941 [ovsdb-tool transact ovn-sb.db \
5942 ['["OVN_Southbound",
5943 {"op": "insert",
5944 "table": "SB_Global",
5945 "row": {
5946 "connections": ["set", [["named-uuid", "xyz"]]]}},
5947 {"op": "insert",
5948 "table": "Connection",
5949 "uuid-name": "xyz",
5950 "row": {"target": "ptcp:0:127.0.0.1",
5951 "read_only": true}}]']], [0], [ignore], [ignore])
5952
5953start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
5954
5955PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5956
5957# read-only accesses should succeed
5958AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
5959AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
5960
5961# write access should fail
5962AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
5963[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
5964])
5965
5966OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5967AT_CLEANUP
5968
5969AT_SETUP([ovn -- read-only sb db:pssl access])
5970AT_SKIP_IF([test $HAVE_PYTHON = no])
5971AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5972PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5973AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5974\\]"])
5975
5976: > .$1.db.~lock~
5977ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5978
5979# Add read-only remote to sb ovsdb-server
5980AT_CHECK(
5981 [ovsdb-tool transact ovn-sb.db \
5982 ['["OVN_Southbound",
5983 {"op": "insert",
5984 "table": "SB_Global",
5985 "row": {
5986 "connections": ["set", [["named-uuid", "xyz"]]]}},
5987 {"op": "insert",
5988 "table": "Connection",
5989 "uuid-name": "xyz",
5990 "row": {"target": "pssl:0:127.0.0.1",
5991 "read_only": true}}]']], [0], [ignore], [ignore])
5992
5993start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
5994 --remote=db:OVN_Southbound,SB_Global,connections \
5995 --private-key="$PKIDIR/testpki-privkey2.pem" \
5996 --certificate="$PKIDIR/testpki-cert2.pem" \
5997 --ca-cert="$PKIDIR/testpki-cacert.pem" \
5998 ovn-sb.db
5999
6000PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6001
6002# read-only accesses should succeed
6003AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6004 --private-key=$PKIDIR/testpki-privkey.pem \
6005 --certificate=$PKIDIR/testpki-cert.pem \
6006 --ca-cert=$PKIDIR/testpki-cacert.pem \
6007 list SB_Global], [0], [stdout], [ignore])
6008AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6009 --private-key=$PKIDIR/testpki-privkey.pem \
6010 --certificate=$PKIDIR/testpki-cert.pem \
6011 --ca-cert=$PKIDIR/testpki-cacert.pem \
6012 list Connection], [0], [stdout], [ignore])
6013
6014# write access should fail
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 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6020[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6021])
6022
6023OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6024AT_CLEANUP
6025
821302cf
LR
6026AT_SETUP([ovn -- nb connection/ssl commands])
6027AT_SKIP_IF([test $HAVE_PYTHON = no])
6028AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6029PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6030AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6031\\]"])
6032
6033: > .$1.db.~lock~
6034ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6035
6036# Start nb db server using db connection/ssl entries (unpopulated initially)
6037start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6038 --remote=db:OVN_Northbound,NB_Global,connections \
6039 --private-key=db:OVN_Northbound,SSL,private_key \
6040 --certificate=db:OVN_Northbound,SSL,certificate \
6041 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6042 ovn-nb.db
6043
6044# Populate SSL configuration entries in nb db
6045AT_CHECK(
6046 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6047 $PKIDIR/testpki-cert.pem \
6048 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6049
6050# Populate a passive SSL connection in nb db
6051AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6052
6053PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6054
6055# Verify SSL connetivity to nb db server
6056AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6057 --private-key=$PKIDIR/testpki-privkey.pem \
6058 --certificate=$PKIDIR/testpki-cert.pem \
6059 --ca-cert=$PKIDIR/testpki-cacert.pem \
6060 list NB_Global],
6061 [0], [stdout], [ignore])
6062AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6063 --private-key=$PKIDIR/testpki-privkey.pem \
6064 --certificate=$PKIDIR/testpki-cert.pem \
6065 --ca-cert=$PKIDIR/testpki-cacert.pem \
6066 list Connection],
6067 [0], [stdout], [ignore])
6068AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6069 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6070 --certificate=$PKIDIR/testpki-cert.pem \
6071 --ca-cert=$PKIDIR/testpki-cacert.pem \
6072 get-connection],
6073 [0], [stdout], [ignore])
6074
6075OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6076AT_CLEANUP
6077
6078AT_SETUP([ovn -- sb connection/ssl commands])
6079AT_SKIP_IF([test $HAVE_PYTHON = no])
6080AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6081PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6082AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6083\\]"])
6084
6085: > .$1.db.~lock~
6086ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6087
6088# Start sb db server using db connection/ssl entries (unpopulated initially)
6089start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6090 --remote=db:OVN_Southbound,SB_Global,connections \
6091 --private-key=db:OVN_Southbound,SSL,private_key \
6092 --certificate=db:OVN_Southbound,SSL,certificate \
6093 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6094 ovn-sb.db
6095
6096# Populate SSL configuration entries in sb db
6097AT_CHECK(
6098 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6099 $PKIDIR/testpki-cert.pem \
6100 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6101
6102# Populate a passive SSL connection in sb db
6103AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6104
6105PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6106
6107# Verify SSL connetivity to sb db server
6108AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6109 --private-key=$PKIDIR/testpki-privkey.pem \
6110 --certificate=$PKIDIR/testpki-cert.pem \
6111 --ca-cert=$PKIDIR/testpki-cacert.pem \
6112 list SB_Global],
6113 [0], [stdout], [ignore])
6114AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6115 --private-key=$PKIDIR/testpki-privkey.pem \
6116 --certificate=$PKIDIR/testpki-cert.pem \
6117 --ca-cert=$PKIDIR/testpki-cacert.pem \
6118 list Connection],
6119 [0], [stdout], [ignore])
6120AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6121 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
6122 --certificate=$PKIDIR/testpki-cert.pem \
6123 --ca-cert=$PKIDIR/testpki-cacert.pem \
6124 get-connection],
6125 [0], [stdout], [ignore])
6126
6127OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6128AT_CLEANUP
6129
75fd74f8
GS
6130AT_SETUP([ovn -- nested containers])
6131ovn_start
6132
6133# Physical network:
6134# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6135
6136# Logical network:
6137# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6138# and "bar" (192.168.2.0/24). They are all connected to router R1.
6139
6140ovn-nbctl lr-add R1
6141ovn-nbctl ls-add mgmt
6142ovn-nbctl ls-add foo
6143ovn-nbctl ls-add bar
6144
6145# Connect mgmt to R1
6146ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6147ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6148 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6149
6150# Connect foo to R1
6151ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6152ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6153 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6154
6155# Connect bar to R1
6156ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6157ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6158 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6159
6160# "mgmt" has VM1 and VM2 connected
6161ovn-nbctl lsp-add mgmt vm1 \
6162-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6163
6164ovn-nbctl lsp-add mgmt vm2 \
6165-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6166
6167# "foo1" and "foo2" are containers belonging to switch "foo"
6168# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6169ovn-nbctl lsp-add foo foo1 vm1 1 \
6170-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6171
6172ovn-nbctl lsp-add foo foo2 vm2 2 \
6173-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6174
6175# "bar1" and "bar2" are containers belonging to switch "bar"
6176# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6177ovn-nbctl lsp-add bar bar1 vm1 2 \
6178-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6179
6180ovn-nbctl lsp-add bar bar2 vm2 1 \
6181-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6182
6183# bar3 is a standalone VM belonging to switch "bar"
6184ovn-nbctl lsp-add bar bar3 \
6185-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6186
6187# Create two hypervisor and create OVS ports corresponding to logical ports.
6188net_add n1
6189
6190sim_add hv1
6191as hv1
6192ovs-vsctl add-br br-phys
6193ovn_attach n1 br-phys 192.168.0.1
6194ovs-vsctl -- add-port br-int vm1 -- \
6195 set interface vm1 external-ids:iface-id=vm1 \
6196 options:tx_pcap=hv1/vm1-tx.pcap \
6197 options:rxq_pcap=hv1/vm1-rx.pcap \
6198 ofport-request=1
6199
6200ovs-vsctl -- add-port br-int bar3 -- \
6201 set interface bar3 external-ids:iface-id=bar3 \
6202 options:tx_pcap=hv1/bar3-tx.pcap \
6203 options:rxq_pcap=hv1/bar3-rx.pcap \
6204 ofport-request=2
6205
6206sim_add hv2
6207as hv2
6208ovs-vsctl add-br br-phys
6209ovn_attach n1 br-phys 192.168.0.2
6210ovs-vsctl -- add-port br-int vm2 -- \
6211 set interface vm2 external-ids:iface-id=vm2 \
6212 options:tx_pcap=hv2/vm2-tx.pcap \
6213 options:rxq_pcap=hv2/vm2-rx.pcap \
6214 ofport-request=1
6215
6216# Pre-populate the hypervisors' ARP tables so that we don't lose any
6217# packets for ARP resolution (native tunneling doesn't queue packets
6218# for ARP resolution).
6219ovn_populate_arp
6220
6221# Allow some time for ovn-northd and ovn-controller to catch up.
6222# XXX This should be more systematic.
6223sleep 1
6224
6225ip_to_hex() {
6226 printf "%02x%02x%02x%02x" "$@"
6227}
6228
6229# Send ip packets between foo1 and foo2 (same switch, different HVs and
6230# different VLAN tags).
6231src_mac="f00000010205"
6232dst_mac="f00000010206"
6233src_ip=`ip_to_hex 192 168 1 2`
6234dst_ip=`ip_to_hex 192 168 1 3`
6235packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6236as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6237
6238# expected packet at foo2
6239packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6240echo $packet > expected
6241OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6242
6243# Send ip packets between foo1 and bar2 (different switch, different HV)
6244src_mac="f00000010205"
6245dst_mac="000000010203"
6246src_ip=`ip_to_hex 192 168 1 2`
6247dst_ip=`ip_to_hex 192 168 2 3`
6248packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6249as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6250
6251# expected packet at bar2
6252src_mac="000000010204"
6253dst_mac="f00000010208"
6254packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6255echo $packet >> expected
6256OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6257
6258# Send ip packets between foo1 and bar1
6259# (different switch, loopback to same vm but different tag)
6260src_mac="f00000010205"
6261dst_mac="000000010203"
6262src_ip=`ip_to_hex 192 168 1 2`
6263dst_ip=`ip_to_hex 192 168 2 2`
6264packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6265as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6266
6267# expected packet at bar1
6268src_mac="000000010204"
6269dst_mac="f00000010207"
6270packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6271echo $packet > expected1
6272OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6273
6274# Send ip packets between bar1 and bar3
6275# (same switch. But one is container and another is a standalone VM)
6276src_mac="f00000010207"
6277dst_mac="f00000010209"
6278src_ip=`ip_to_hex 192 168 2 2`
6279dst_ip=`ip_to_hex 192 168 2 3`
6280packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6281as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6282
6283# expected packet at bar3
6284packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6285echo $packet > expected
6286OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6287
6288# Send ip packets between foo1 and vm1.
6289(different switch, container to the VM hosting it.)
6290src_mac="f00000010205"
6291dst_mac="000000010203"
6292src_ip=`ip_to_hex 192 168 1 2`
6293dst_ip=`ip_to_hex 172 16 1 2`
6294packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6295as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6296
6297# expected packet at vm1
6298src_mac="000000010202"
6299dst_mac="f00000010203"
6300packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6301echo $packet >> expected1
6302OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6303
6304# Send packets from vm1 to bar1.
6305(different switch, A hosting VM to a container inside it)
6306src_mac="f00000010203"
6307dst_mac="000000010202"
6308src_ip=`ip_to_hex 172 16 1 2`
6309dst_ip=`ip_to_hex 192 168 2 2`
6310packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6311as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6312
6313# expected packet at vm1
6314src_mac="000000010204"
6315dst_mac="f00000010207"
6316packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6317echo $packet >> expected1
6318OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6319
6320OVN_CLEANUP([hv1],[hv2])
6321
6322AT_CLEANUP
440a9f4b
GS
6323
6324AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6325AT_SKIP_IF([test $HAVE_PYTHON = no])
6326ovn_start
6327
6328# Logical network:
6329# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6330# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6331# (192.168.2.0/24) connected to it.
6332#
6333# R2 and R3 are gateway routers.
6334# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6335# connected to it. Note how both alice and bob have the same subnet behind it.
6336# We are trying to simulate external network via those 2 switches. In real
6337# world the switch ports of these switches will have addresses set as "unknown"
6338# to make them learning switches. Or those switches will be "localnet" ones.
6339
6340# Create three hypervisors and create OVS ports corresponding to logical ports.
6341net_add n1
6342
6343sim_add hv1
6344as hv1
6345ovs-vsctl add-br br-phys
6346ovn_attach n1 br-phys 192.168.0.1
6347ovs-vsctl -- add-port br-int hv1-vif1 -- \
6348 set interface hv1-vif1 external-ids:iface-id=foo1 \
6349 options:tx_pcap=hv1/vif1-tx.pcap \
6350 options:rxq_pcap=hv1/vif1-rx.pcap \
6351 ofport-request=1
6352
6353ovs-vsctl -- add-port br-int hv1-vif2 -- \
6354 set interface hv1-vif2 external-ids:iface-id=bar1 \
6355 options:tx_pcap=hv1/vif2-tx.pcap \
6356 options:rxq_pcap=hv1/vif2-rx.pcap \
6357 ofport-request=2
6358
6359sim_add hv2
6360as hv2
6361ovs-vsctl add-br br-phys
6362ovn_attach n1 br-phys 192.168.0.2
6363ovs-vsctl -- add-port br-int hv2-vif1 -- \
6364 set interface hv2-vif1 external-ids:iface-id=alice1 \
6365 options:tx_pcap=hv2/vif1-tx.pcap \
6366 options:rxq_pcap=hv2/vif1-rx.pcap \
6367 ofport-request=1
6368
6369sim_add hv3
6370as hv3
6371ovs-vsctl add-br br-phys
6372ovn_attach n1 br-phys 192.168.0.3
6373ovs-vsctl -- add-port br-int hv3-vif1 -- \
6374 set interface hv3-vif1 external-ids:iface-id=bob1 \
6375 options:tx_pcap=hv3/vif1-tx.pcap \
6376 options:rxq_pcap=hv3/vif1-rx.pcap \
6377 ofport-request=1
6378
6379
6380ovn-nbctl create Logical_Router name=R1
6381ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6382ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6383
6384ovn-nbctl ls-add foo
6385ovn-nbctl ls-add bar
6386ovn-nbctl ls-add alice
6387ovn-nbctl ls-add bob
6388ovn-nbctl ls-add join
6389
6390# Connect foo to R1
6391ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6392ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6393 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6394
6395# Connect bar to R1
6396ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6397ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6398 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6399
6400# Connect alice to R2
6401ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6402ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6403 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6404
6405# Connect bob to R3
6406ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6407ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6408 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6409
6410# Connect R1 to join
6411ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6412ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6413 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6414
6415# Connect R2 to join
6416ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6417ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6418 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6419
6420# Connect R3 to join
6421ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6422ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6423 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6424
6425# Install static routes with source ip address as the policy for routing.
6426# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6427ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6428ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6429
6430# Install static routes with destination ip address as the policy for routing.
6431ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6432
6433ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6434
6435# Create logical port foo1 in foo
6436ovn-nbctl lsp-add foo foo1 \
6437-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6438
6439# Create logical port bar1 in bar
6440ovn-nbctl lsp-add bar bar1 \
6441-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6442
6443# Create logical port alice1 in alice
6444ovn-nbctl lsp-add alice alice1 \
6445-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6446
6447# Create logical port bob1 in bob
6448ovn-nbctl lsp-add bob bob1 \
6449-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6450
6451# Pre-populate the hypervisors' ARP tables so that we don't lose any
6452# packets for ARP resolution (native tunneling doesn't queue packets
6453# for ARP resolution).
6454ovn_populate_arp
6455
6456# Allow some time for ovn-northd and ovn-controller to catch up.
6457# XXX This should be more systematic.
6458sleep 1
6459
6460ip_to_hex() {
6461 printf "%02x%02x%02x%02x" "$@"
6462}
6463trim_zeros() {
6464 sed 's/\(00\)\{1,\}$//'
6465}
6466
6467# Send ip packets between foo1 and bar1
6468# (East-west traffic should flow normally)
6469src_mac="f00000010203"
6470dst_mac="000001010203"
6471src_ip=`ip_to_hex 192 168 1 2`
6472dst_ip=`ip_to_hex 192 168 2 2`
6473packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6474as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6475
6476# Send ip packets between foo1 and alice1
6477src_mac="f00000010203"
6478dst_mac="000001010203"
6479src_ip=`ip_to_hex 192 168 1 2`
6480dst_ip=`ip_to_hex 172 16 1 3`
6481packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6482as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 6483as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
6484
6485# Send ip packets between bar1 and bob1
6486src_mac="f00000010204"
6487dst_mac="000001010204"
6488src_ip=`ip_to_hex 192 168 2 2`
6489dst_ip=`ip_to_hex 172 16 1 4`
6490packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6491as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6492#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6493
6494# Packet to expect at bar1
6495src_mac="000001010204"
6496dst_mac="f00000010204"
6497src_ip=`ip_to_hex 192 168 1 2`
6498dst_ip=`ip_to_hex 192 168 2 2`
6499expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6500echo $expected > expected
6501OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6502
6503# Packet to Expect at alice1
6504src_mac="000002010203"
6505dst_mac="f00000010205"
6506src_ip=`ip_to_hex 192 168 1 2`
6507dst_ip=`ip_to_hex 172 16 1 3`
6508expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6509echo $expected > expected
6510OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6511
6512# Packet to Expect at bob1
6513src_mac="000003010203"
6514dst_mac="f00000010206"
6515src_ip=`ip_to_hex 192 168 2 2`
6516dst_ip=`ip_to_hex 172 16 1 4`
6517expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6518echo $expected > expected
6519OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6520
6521for sim in hv1 hv2 hv3; do
6522 as $sim
6523 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6524 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6525 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6526done
6527
6528as ovn-sb
6529OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6530
6531as ovn-nb
6532OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6533
6534as northd
6535OVS_APP_EXIT_AND_WAIT([ovn-northd])
6536
6537as main
6538OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6539OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6540
6541AT_CLEANUP
41a15b71 6542
302eda27
NS
6543AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6544AT_SKIP_IF([test $HAVE_PYTHON = no])
6545ovn_start
6546
6547ovn-nbctl ls-add ls1
6548
6549ovn-nbctl lsp-add ls1 ls1-lp1 \
6550-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6551
6552ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6553
6554ovn-nbctl lsp-add ls1 ls1-lp2 \
6555-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6556
6557ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6558
6559DNS1=`ovn-nbctl create DNS records={}`
6560DNS2=`ovn-nbctl create DNS records={}`
6561
6562ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6563ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6564ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6565
6566ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6567
6568net_add n1
6569sim_add hv1
6570
6571as hv1
6572ovs-vsctl add-br br-phys
6573ovn_attach n1 br-phys 192.168.0.1
6574ovs-vsctl -- add-port br-int hv1-vif1 -- \
6575 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6576 options:tx_pcap=hv1/vif1-tx.pcap \
6577 options:rxq_pcap=hv1/vif1-rx.pcap \
6578 ofport-request=1
6579
6580ovs-vsctl -- add-port br-int hv1-vif2 -- \
6581 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6582 options:tx_pcap=hv1/vif2-tx.pcap \
6583 options:rxq_pcap=hv1/vif2-rx.pcap \
6584 ofport-request=2
6585
6586ovn_populate_arp
6587sleep 2
6588as hv1 ovs-vsctl show
6589
6590echo "*************************"
6591ovn-sbctl list DNS
6592echo "*************************"
6593
6594ip_to_hex() {
6595 printf "%02x%02x%02x%02x" "$@"
6596}
6597
6598reset_pcap_file() {
6599 local iface=$1
6600 local pcap_file=$2
6601 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6602options:rxq_pcap=dummy-rx.pcap
6603 rm -f ${pcap_file}*.pcap
6604 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6605options:rxq_pcap=${pcap_file}-rx.pcap
6606}
6607
6608# set_dns_params host_name
6609# Sets the dns_req_data and dns_resp_data
6610set_dns_params() {
6611 local hname=$1
6612 local ttl=00000e10
6613 an_count=0001
6614 type=0001
6615 case $hname in
6616 vm1)
6617 # vm1.ovn.org
6618 query_name=03766d31036f766e036f726700
6619 # IPv4 address - 10.0.0.4
6620 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6621 ;;
6622 vm2)
6623 # vm2.ovn.org
6624 query_name=03766d32036f766e036f726700
6625 # IPv4 address - 10.0.0.6
6626 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6627 # IPv4 address - 20.0.0.4
6628 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6629 an_count=0002
6630 ;;
6631 vm3)
6632 # vm3.ovn.org
6633 query_name=03766d33036f766e036f726700
6634 # IPv4 address - 40.0.0.4
6635 expected_dns_answer=${query_name}00010001${ttl}000428000004
6636 ;;
6637 vm1_ipv6_only)
6638 # vm1.ovn.org
6639 query_name=03766d31036f766e036f726700
6640 # IPv6 address - aef0::4
6641 type=001c
6642 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6643 ;;
6644 vm1_ipv4_v6)
6645 # vm1.ovn.org
6646 query_name=03766d31036f766e036f726700
6647 type=00ff
6648 an_count=0002
6649 # IPv4 address - 10.0.0.4
6650 # IPv6 address - aef0::4
6651 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6652 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
6653 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
6654 ;;
6655 vm1_invalid_type)
6656 # vm1.ovn.org
6657 query_name=03766d31036f766e036f726700
6658 # IPv6 address - aef0::4
6659 type=0002
6660 ;;
6661 vm1_incomplete)
6662 # set type to none
6663 type=''
6664 esac
6665 # TTL - 3600
6666 local dns_req_header=010201200001000000000000
6667 local dns_resp_header=010281200001${an_count}00000000
6668 dns_req_data=${dns_req_header}${query_name}${type}0001
6669 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
6670}
6671
6672# This shell function sends a DNS request packet
6673# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
6674test_dns() {
6675 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6676 local dns_query_data=$7
6677 shift; shift; shift; shift; shift; shift; shift;
6678 # Packet size => IPv4 header (20) + UDP header (8) +
6679 # DNS data (header + query)
6680 ip_len=`expr 28 + ${#dns_query_data} / 2`
6681 udp_len=`expr $ip_len - 20`
6682 ip_len=$(printf "%x" $ip_len)
6683 udp_len=$(printf "%x" $udp_len)
6684 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
6685 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
6686 # dns data
6687 request=${request}${dns_query_data}
6688
6689 if test $dns_reply != 0; then
6690 local dns_reply=$1
6691 ip_len=`expr 28 + ${#dns_reply} / 2`
6692 udp_len=`expr $ip_len - 20`
6693 ip_len=$(printf "%x" $ip_len)
6694 udp_len=$(printf "%x" $udp_len)
6695 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
6696 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
6697 echo $reply >> $inport.expected
6698 else
6699 for outport; do
6700 echo $request >> $outport.expected
6701 done
6702 fi
6703 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6704}
6705
6706AT_CAPTURE_FILE([ofctl_monitor0.log])
6707as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
6708--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
6709
6710set_dns_params vm2
6711src_ip=`ip_to_hex 10 0 0 4`
6712dst_ip=`ip_to_hex 10 0 0 1`
6713dns_reply=1
6714test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6715
6716# NXT_RESUMEs should be 1.
6717OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6718
6719$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6720cat 1.expected | cut -c -48 > expout
6721AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6722# Skipping the IPv4 checksum.
6723cat 1.expected | cut -c 53- > expout
6724AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6725
6726reset_pcap_file hv1-vif1 hv1/vif1
6727reset_pcap_file hv1-vif2 hv1/vif2
6728rm -f 1.expected
6729rm -f 2.expected
6730
6731set_dns_params vm1
6732src_ip=`ip_to_hex 10 0 0 6`
6733dst_ip=`ip_to_hex 10 0 0 1`
6734dns_reply=1
6735test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6736
6737# NXT_RESUMEs should be 2.
6738OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6739
6740$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6741cat 2.expected | cut -c -48 > expout
6742AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6743# Skipping the IPv4 checksum.
6744cat 2.expected | cut -c 53- > expout
6745AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6746
6747reset_pcap_file hv1-vif1 hv1/vif1
6748reset_pcap_file hv1-vif2 hv1/vif2
6749rm -f 1.expected
6750rm -f 2.expected
6751
6752# Clear the query name options for ls1-lp2
6753ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
6754
6755set_dns_params vm2
6756src_ip=`ip_to_hex 10 0 0 4`
6757dst_ip=`ip_to_hex 10 0 0 1`
6758dns_reply=0
6759test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
6760
6761# NXT_RESUMEs should be 3.
6762OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6763
6764$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6765AT_CHECK([cat 1.packets], [0], [])
6766
6767reset_pcap_file hv1-vif1 hv1/vif1
6768reset_pcap_file hv1-vif2 hv1/vif2
6769rm -f 1.expected
6770rm -f 2.expected
6771
6772# Clear the query name for ls1-lp1
6773# Since ls1 has no query names configued,
6774# ovn-northd should not add the DNS flows.
6775ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
6776
6777set_dns_params vm1
6778src_ip=`ip_to_hex 10 0 0 6`
6779dst_ip=`ip_to_hex 10 0 0 1`
6780dns_reply=0
6781test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6782
6783# NXT_RESUMEs should be 3 only.
6784OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6785
6786$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6787AT_CHECK([cat 2.packets], [0], [])
6788
6789reset_pcap_file hv1-vif1 hv1/vif1
6790reset_pcap_file hv1-vif2 hv1/vif2
6791rm -f 1.expected
6792rm -f 2.expected
6793
6794# Test IPv6 (AAAA records) using IPv4 packet.
6795# Add back the DNS options for ls1-lp1.
6796ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6797
6798set_dns_params vm1_ipv6_only
6799src_ip=`ip_to_hex 10 0 0 6`
6800dst_ip=`ip_to_hex 10 0 0 1`
6801dns_reply=1
6802test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6803
6804# NXT_RESUMEs should be 4.
6805OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6806
6807$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6808cat 2.expected | cut -c -48 > expout
6809AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6810# Skipping the IPv4 checksum.
6811cat 2.expected | cut -c 53- > expout
6812AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6813
6814reset_pcap_file hv1-vif1 hv1/vif1
6815reset_pcap_file hv1-vif2 hv1/vif2
6816rm -f 1.expected
6817rm -f 2.expected
6818
6819# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
6820set_dns_params vm1_ipv4_v6
6821src_ip=`ip_to_hex 10 0 0 6`
6822dst_ip=`ip_to_hex 10 0 0 1`
6823dns_reply=1
6824test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6825
6826# NXT_RESUMEs should be 5.
6827OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6828
6829$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6830cat 2.expected | cut -c -48 > expout
6831AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6832# Skipping the IPv4 checksum.
6833cat 2.expected | cut -c 53- > expout
6834AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6835
6836reset_pcap_file hv1-vif1 hv1/vif1
6837reset_pcap_file hv1-vif2 hv1/vif2
6838rm -f 1.expected
6839rm -f 2.expected
6840
6841# Invalid type.
6842set_dns_params vm1_invalid_type
6843src_ip=`ip_to_hex 10 0 0 6`
6844dst_ip=`ip_to_hex 10 0 0 1`
6845dns_reply=0
6846test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6847
6848# NXT_RESUMEs should be 6.
6849OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6850
6851$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6852AT_CHECK([cat 2.packets], [0], [])
6853
6854reset_pcap_file hv1-vif1 hv1/vif1
6855reset_pcap_file hv1-vif2 hv1/vif2
6856rm -f 1.expected
6857rm -f 2.expected
6858
6859# Incomplete DNS packet.
6860set_dns_params vm1_incomplete
6861src_ip=`ip_to_hex 10 0 0 6`
6862dst_ip=`ip_to_hex 10 0 0 1`
6863dns_reply=0
6864test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6865
6866# NXT_RESUMEs should be 7.
6867OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6868
6869$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6870AT_CHECK([cat 2.packets], [0], [])
6871
6872reset_pcap_file hv1-vif1 hv1/vif1
6873reset_pcap_file hv1-vif2 hv1/vif2
6874rm -f 1.expected
6875rm -f 2.expected
6876
6877# Add one more DNS record to the ls1.
6878ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
6879
6880set_dns_params vm3
6881src_ip=`ip_to_hex 10 0 0 4`
6882dst_ip=`ip_to_hex 10 0 0 1`
6883dns_reply=1
6884test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6885
6886# NXT_RESUMEs should be 8.
6887OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6888
6889$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6890cat 1.expected | cut -c -48 > expout
6891AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6892# Skipping the IPv4 checksum.
6893cat 1.expected | cut -c 53- > expout
6894AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6895
6896reset_pcap_file hv1-vif1 hv1/vif1
6897reset_pcap_file hv1-vif2 hv1/vif2
6898rm -f 1.expected
6899rm -f 2.expected
6900
6901as hv1
6902 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6903OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6904OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6905
6906as ovn-sb
6907OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6908
6909as ovn-nb
6910OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6911
6912as northd
6913OVS_APP_EXIT_AND_WAIT([ovn-northd])
6914
6915as main
6916OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6917OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6918AT_CLEANUP
6919
1da17a0b 6920AT_SETUP([ovn -- packet test with HA distributed router gateway port])
6921AT_SKIP_IF([test $HAVE_PYTHON = no])
6922ovn_start
6923
6924net_add n1
6925
6926sim_add hv1
6927as hv1
6928ovs-vsctl add-br br-phys
6929ovn_attach n1 br-phys 192.168.0.1
6930ovs-vsctl -- add-port br-int hv1-vif1 -- \
6931 set interface hv1-vif1 external-ids:iface-id=foo1 \
6932 options:tx_pcap=hv1/vif1-tx.pcap \
6933 options:rxq_pcap=hv1/vif1-rx.pcap \
6934 ofport-request=1
6935
6936sim_add gw1
6937as gw1
6938ovs-vsctl add-br br-phys
6939ovn_attach n1 br-phys 192.168.0.2
6940
6941sim_add gw2
6942as gw2
6943ovs-vsctl add-br br-phys
6944ovn_attach n1 br-phys 192.168.0.4
6945
6946sim_add ext1
6947as ext1
6948ovs-vsctl add-br br-phys
6949ovn_attach n1 br-phys 192.168.0.3
6950ovs-vsctl -- add-port br-int ext1-vif1 -- \
6951 set interface ext1-vif1 external-ids:iface-id=outside1 \
6952 options:tx_pcap=ext1/vif1-tx.pcap \
6953 options:rxq_pcap=ext1/vif1-rx.pcap \
6954 ofport-request=1
6955
6956# Pre-populate the hypervisors' ARP tables so that we don't lose any
6957# packets for ARP resolution (native tunneling doesn't queue packets
6958# for ARP resolution).
6959ovn_populate_arp
6960
6961ovn-nbctl create Logical_Router name=R1
6962
6963ovn-nbctl ls-add foo
6964ovn-nbctl ls-add alice
6965ovn-nbctl ls-add outside
6966
6967# Connect foo to R1
6968ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6969ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6970 type=router options:router-port=foo \
6971 -- lsp-set-addresses rp-foo router
6972
6973# Connect alice to R1 as distributed router gateway port on gw1
6974ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
6975
6976ovn-nbctl \
6977 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
6978 chassis_name=gw1 \
6979 priority=20 -- \
6980 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
6981 chassis_name=gw2 \
6982 priority=10 -- \
6983 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
6984
6985ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6986 type=router options:router-port=alice \
6987 -- lsp-set-addresses rp-alice router
6988
6989# Create logical port foo1 in foo
6990ovn-nbctl lsp-add foo foo1 \
6991-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6992
6993# Create logical port outside1 in outside
6994ovn-nbctl lsp-add outside outside1 \
6995-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
6996
6997# Create localnet port in alice
6998ovn-nbctl lsp-add alice ln-alice
6999ovn-nbctl lsp-set-addresses ln-alice unknown
7000ovn-nbctl lsp-set-type ln-alice localnet
7001ovn-nbctl lsp-set-options ln-alice network_name=phys
7002
7003# Create localnet port in outside
7004ovn-nbctl lsp-add outside ln-outside
7005ovn-nbctl lsp-set-addresses ln-outside unknown
7006ovn-nbctl lsp-set-type ln-outside localnet
7007ovn-nbctl lsp-set-options ln-outside network_name=phys
7008
7009# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7010# mapping to the external network, is the one generating packets
7011as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7012as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7013as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7014
7015AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7016
7017# Allow some time for ovn-northd and ovn-controller to catch up.
7018# XXX This should be more systematic.
7019sleep 2
7020
7021ip_to_hex() {
7022 printf "%02x%02x%02x%02x" "$@"
7023}
7024
7025reset_pcap_file() {
7026 local iface=$1
7027 local pcap_file=$2
7028 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7029options:rxq_pcap=dummy-rx.pcap
7030 rm -f ${pcap_file}*.pcap
7031 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7032options:rxq_pcap=${pcap_file}-rx.pcap
7033}
7034
7035test_ip_packet()
7036{
7037 local active_gw=$1
7038 local backup_gw=$2
7039
7040 # Send ip packet between foo1 and outside1
7041 src_mac="f00000010203" # foo1 mac
7042 dst_mac="000001010203" # rp-foo mac (internal router leg)
7043 src_ip=`ip_to_hex 192 168 1 2`
7044 dst_ip=`ip_to_hex 172 16 1 3`
7045 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7046
7047 # ARP request packet to expect at outside1
7048 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7049
7050 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7051
7052 # Send ARP reply from outside1 back to the router
7053 # XXX: note, we could avoid this if we plug this port into a netns
7054 # and setup the IP address into the port, so the kernel would simply reply
7055 src_mac="000002010203"
7056 reply_mac="f00000010204"
7057 dst_ip=`ip_to_hex 172 16 1 3`
7058 src_ip=`ip_to_hex 172 16 1 1`
7059 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7060
7061 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7062
7063 # Packet to Expect at ext1 chassis, outside1 port
7064 src_mac="000002010203"
7065 dst_mac="f00000010204"
7066 src_ip=`ip_to_hex 192 168 1 2`
7067 dst_ip=`ip_to_hex 172 16 1 3`
7068 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7069 echo $expected > ext1-vif1.expected
7070
7071 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7072 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7073 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7074
7075 # Resend packet from foo1 to outside1
7076 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7077
7078 sleep 1
7079
7080 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7081 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7082 AT_CHECK([grep $expected packets | sort], [0], [expout])
7083 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7084 AT_CHECK([grep $expected packets | sort], [0], [])
7085}
7086
7087test_ip_packet gw1 gw2
7088
8e1d9349 7089ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 7090 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7091 chassis_name=gw1 \
7092 priority=10 -- \
7093 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7094 chassis_name=gw2 \
7095 priority=20 -- \
7096 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7097
7098test_ip_packet gw2 gw1
7099
7100OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7101AT_CLEANUP
7102
41a15b71
MS
7103AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7104AT_SKIP_IF([test $HAVE_PYTHON = no])
7105ovn_start
7106
7107# Logical network:
7108# One LR R1 that has switches foo (192.168.1.0/24) and
7109# alice (172.16.1.0/24) connected to it. The logical port
7110# between R1 and alice has a "redirect-chassis" specified,
7111# i.e. it is the distributed router gateway port.
7112# Switch alice also has a localnet port defined.
7113# An additional switch outside has a localnet port and the
7114# same subnet as alice (172.16.1.0/24).
7115
7116# Physical network:
7117# Three hypervisors hv[123].
7118# hv1 hosts vif foo1.
7119# hv2 is the "redirect-chassis" that hosts the distributed
7120# router gateway port.
7121# hv3 hosts vif outside1.
7122# In order to show that connectivity works only through hv2,
7123# an initial round of tests is run without any bridge-mapping
7124# defined for the localnet on hv2. These tests are expected
7125# to fail.
7126# Subsequent tests are run after defining the bridge-mapping
7127# for the localnet on hv2. These tests are expected to succeed.
7128
7129# Create three hypervisors and create OVS ports corresponding
7130to logical ports.
7131net_add n1
7132
7133sim_add hv1
7134as hv1
7135ovs-vsctl add-br br-phys
7136ovn_attach n1 br-phys 192.168.0.1
7137ovs-vsctl -- add-port br-int hv1-vif1 -- \
7138 set interface hv1-vif1 external-ids:iface-id=foo1 \
7139 options:tx_pcap=hv1/vif1-tx.pcap \
7140 options:rxq_pcap=hv1/vif1-rx.pcap \
7141 ofport-request=1
7142
7143sim_add hv2
7144as hv2
7145ovs-vsctl add-br br-phys
7146ovn_attach n1 br-phys 192.168.0.2
7147
7148sim_add hv3
7149as hv3
7150ovs-vsctl add-br br-phys
7151ovn_attach n1 br-phys 192.168.0.3
7152ovs-vsctl -- add-port br-int hv3-vif1 -- \
7153 set interface hv3-vif1 external-ids:iface-id=outside1 \
7154 options:tx_pcap=hv3/vif1-tx.pcap \
7155 options:rxq_pcap=hv3/vif1-rx.pcap \
7156 ofport-request=1
7157
7158# Pre-populate the hypervisors' ARP tables so that we don't lose any
7159# packets for ARP resolution (native tunneling doesn't queue packets
7160# for ARP resolution).
7161ovn_populate_arp
7162
7163ovn-nbctl create Logical_Router name=R1
7164
7165ovn-nbctl ls-add foo
7166ovn-nbctl ls-add alice
7167ovn-nbctl ls-add outside
7168
7169# Connect foo to R1
7170ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7171ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7172 type=router options:router-port=foo \
7173 -- lsp-set-addresses rp-foo router
7174
7175# Connect alice to R1 as distributed router gateway port on hv2
7176ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7177 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7178ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7179 type=router options:router-port=alice \
7180 -- lsp-set-addresses rp-alice router
7181
7182# Create logical port foo1 in foo
7183ovn-nbctl lsp-add foo foo1 \
7184-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7185
7186# Create logical port outside1 in outside
7187ovn-nbctl lsp-add outside outside1 \
7188-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7189
7190# Create localnet port in alice
7191ovn-nbctl lsp-add alice ln-alice
7192ovn-nbctl lsp-set-addresses ln-alice unknown
7193ovn-nbctl lsp-set-type ln-alice localnet
7194ovn-nbctl lsp-set-options ln-alice network_name=phys
7195
7196# Create localnet port in outside
7197ovn-nbctl lsp-add outside ln-outside
7198ovn-nbctl lsp-set-addresses ln-outside unknown
7199ovn-nbctl lsp-set-type ln-outside localnet
7200ovn-nbctl lsp-set-options ln-outside network_name=phys
7201
7202# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7203as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7204as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7205
7206
7207# Allow some time for ovn-northd and ovn-controller to catch up.
7208# XXX This should be more systematic.
7209sleep 2
7210
7211echo "---------NB dump-----"
7212ovn-nbctl show
7213echo "---------------------"
7214ovn-nbctl list logical_router
7215echo "---------------------"
7216ovn-nbctl list logical_router_port
7217echo "---------------------"
7218
7219echo "---------SB dump-----"
7220ovn-sbctl list datapath_binding
7221echo "---------------------"
7222ovn-sbctl list port_binding
7223echo "---------------------"
7224ovn-sbctl dump-flows
7225echo "---------------------"
7226ovn-sbctl list chassis
7227ovn-sbctl list encap
1da17a0b 7228echo "------ Gateway_Chassis dump (SBDB) -------"
7229ovn-sbctl list Gateway_Chassis
7230echo "------ Port_Binding chassisredirect -------"
7231ovn-sbctl find Port_Binding type=chassisredirect
7232echo "-------------------------------------------"
41a15b71
MS
7233
7234echo "------ hv1 dump ----------"
7235as hv1 ovs-ofctl show br-int
7236as hv1 ovs-ofctl dump-flows br-int
7237echo "------ hv2 dump ----------"
7238as hv2 ovs-ofctl show br-int
7239as hv2 ovs-ofctl dump-flows br-int
7240echo "------ hv3 dump ----------"
7241as hv3 ovs-ofctl show br-int
7242as hv3 ovs-ofctl dump-flows br-int
7243echo "--------------------------"
7244
1da17a0b 7245
41a15b71
MS
7246# Check that redirect mapping is programmed only on hv2
7247AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7248])
7249AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7250])
7251# Check that hv1 sends chassisredirect port traffic to hv2
7252AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7253])
7254AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7255])
7256# Check that arp reply on distributed gateway port is only programmed on hv2
7257AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7258])
7259AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7260])
7261
7262
7263ip_to_hex() {
7264 printf "%02x%02x%02x%02x" "$@"
7265}
7266
7267
7268: > hv2-vif1.expected
7269: > hv3-vif1.expected
7270
7271# test_arp INPORT SHA SPA TPA [REPLY_HA]
7272#
7273# Causes a packet to be received on INPORT. The packet is an ARP
7274# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7275# it should be the hardware address of the target to expect to receive in an
7276# ARP reply; otherwise no reply is expected.
7277#
7278# INPORT is an logical switch port number, e.g. 11 for vif11.
7279# SHA and REPLY_HA are each 12 hex digits.
7280# SPA and TPA are each 8 hex digits.
7281test_arp() {
7282 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7283 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7284 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7285
7286 if test X$reply_ha != X; then
7287 # Expect to receive the reply, if any.
7288 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7289 echo $reply >> hv${hv}-vif$inport.expected
7290 fi
7291}
7292
7293rtr_ip=$(ip_to_hex 172 16 1 1)
7294foo_ip=$(ip_to_hex 192 168 1 2)
7295outside_ip=$(ip_to_hex 172 16 1 3)
7296
7297echo $rtr_ip
7298echo $foo_ip
7299echo $outside_ip
7300
7301# ARP for router IP address from outside1, no response expected
7302test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7303
7304# Now check the packets actually received against the ones expected.
7305OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7306
7307# Send ip packet between foo1 and outside1
7308src_mac="f00000010203"
7309dst_mac="000001010203"
7310src_ip=`ip_to_hex 192 168 1 2`
7311dst_ip=`ip_to_hex 172 16 1 3`
7312packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7313
7314# Now check the packets actually received against the ones expected.
7315OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7316
7317# Now add bridge-mappings on hv2, which should make everything work
7318as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7319
7320# Allow some time for ovn-northd and ovn-controller to catch up.
7321# XXX This should be more systematic.
7322sleep 2
7323
7324# ARP for router IP address from outside1
7325test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7326
7327# Now check the packets actually received against the ones expected.
7328OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7329
7330# Send ip packet between foo1 and outside1
7331src_mac="f00000010203"
7332dst_mac="000001010203"
7333src_ip=`ip_to_hex 192 168 1 2`
7334dst_ip=`ip_to_hex 172 16 1 3`
7335packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7336
7337# ARP request packet to expect at outside1
7338src_mac="000002010203"
7339src_ip=`ip_to_hex 172 16 1 1`
7340arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7341
7342as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7343
7344echo $arp_request >> hv3-vif1.expected
7345OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7346
7347# Send ARP reply from outside1 back to the router
7348reply_mac="f00000010204"
7349arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7350
7351as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7352
7353# Allow some time for ovn-northd and ovn-controller to catch up.
7354# XXX This should be more systematic.
7355sleep 1
7356
7357# Packet to Expect at outside1
7358src_mac="000002010203"
7359dst_mac="f00000010204"
7360src_ip=`ip_to_hex 192 168 1 2`
7361dst_ip=`ip_to_hex 172 16 1 3`
7362expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7363
7364# Resend packet from foo1 to outside1
7365as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7366
7367echo "------ hv1 dump ----------"
7368as hv1 ovs-ofctl show br-int
7369as hv1 ovs-ofctl dump-flows br-int
7370echo "------ hv2 dump ----------"
7371as hv2 ovs-ofctl show br-int
7372as hv2 ovs-ofctl dump-flows br-int
7373echo "------ hv3 dump ----------"
7374as hv3 ovs-ofctl show br-int
7375as hv3 ovs-ofctl dump-flows br-int
7376echo "----------------------------"
7377
7378echo $expected >> hv3-vif1.expected
7379OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7380
7381#Check ovn-trace over "chassisredirect" port
7382AT_CAPTURE_FILE([trace])
7383ovn_trace () {
7384 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7385}
7386
7387echo 'ip.ttl--;' > expout
7388echo 'eth.src = 00:00:02:01:02:03;' >> expout
7389echo 'eth.dst = f0:00:00:01:02:04;' >> expout
7390echo 'output("ln-alice");' >> expout
7391AT_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])
7392
7393# Create logical port alice1 in alice on hv1
7394as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7395 set interface hv1-vif2 external-ids:iface-id=alice1 \
7396 options:tx_pcap=hv1/vif2-tx.pcap \
7397 options:rxq_pcap=hv1/vif2-rx.pcap \
7398 ofport-request=1
7399
7400ovn-nbctl lsp-add alice alice1 \
7401-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
7402
7403# Create logical port foo2 in foo on hv2
7404as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7405 set interface hv2-vif1 external-ids:iface-id=foo2 \
7406 options:tx_pcap=hv2/vif1-tx.pcap \
7407 options:rxq_pcap=hv2/vif1-rx.pcap \
7408 ofport-request=1
7409
7410ovn-nbctl lsp-add foo foo2 \
7411-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7412
7413# Allow some time for ovn-northd and ovn-controller to catch up.
7414# XXX This should be more systematic.
7415sleep 1
7416
7417: > hv1-vif2.expected
7418
7419# Send ip packet between alice1 and foo2
7420src_mac="f00000010205"
7421dst_mac="000002010203"
7422src_ip=`ip_to_hex 172 16 1 4`
7423dst_ip=`ip_to_hex 192 168 1 3`
7424packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7425
7426as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7427
7428# Packet to Expect at foo2
7429src_mac="000001010203"
7430dst_mac="f00000010206"
7431src_ip=`ip_to_hex 172 16 1 4`
7432dst_ip=`ip_to_hex 192 168 1 3`
7433expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7434
7435echo $expected >> hv2-vif1.expected
f5f64552 7436OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 7437
415ed5d7 7438AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc --lines], [0], [1
7439])
7440
8e1d9349 7441ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 7442
7443AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc --lines], [0], [0
7444])
7445
41a15b71
MS
7446OVN_CLEANUP([hv1],[hv2],[hv3])
7447
7448AT_CLEANUP
26b9e08d
MS
7449
7450AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7451AT_SKIP_IF([test $HAVE_PYTHON = no])
7452ovn_start
7453# Create logical switches
7454ovn-nbctl ls-add ls0
7455ovn-nbctl ls-add ls1
7456# Create distributed router
7457ovn-nbctl create Logical_Router name=lr0
7458# Add distributed gateway port to distributed router
7459ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
7460 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
7461ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
7462 type=router options:router-port=lrp0 addresses="router"
7463# Add router port to ls1
7464ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
7465ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
7466 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
7467# Add logical ports for NAT rules
7468ovn-nbctl lsp-add ls1 foo1 \
7469-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
7470ovn-nbctl lsp-add ls1 foo2 \
7471-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
7472# Add nat-addresses option
7473ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7474# Add NAT rules
7475AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
7476AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
7477AT_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 7478AT_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
7479
7480net_add n1
7481sim_add hv1
7482as hv1
7483ovs-vsctl add-br br-phys
7484ovn_attach n1 br-phys 192.168.0.1
7485
7486AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7487AT_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])
7488
7489sim_add hv2
7490as hv2
7491ovs-vsctl add-br br-phys
7492ovn_attach n1 br-phys 192.168.0.2
7493# Initially test with no bridge-mapping on hv2, expect to receive no packets
7494
f40c5588
MS
7495sim_add hv3
7496as hv3
7497ovs-vsctl add-br br-phys
7498ovn_attach n1 br-phys 192.168.0.3
7499# Initially test with no bridge-mapping on hv3
7500
26b9e08d
MS
7501# Create a localnet port.
7502AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
7503AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7504AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7505AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7506
7507# Allow some time for ovn-northd and ovn-controller to catch up.
7508# XXX This should be more systematic.
7509sleep 2
7510
7511# Expect no packets when hv2 bridge-mapping is not present
7512: > packets
7513OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
7514
7515# Add bridge-mapping on hv2
f40c5588 7516AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
7517
7518# Wait for packets to be received.
7519OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
7520trim_zeros() {
7521 sed 's/\(00\)\{1,\}$//'
7522}
7523$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7524expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
7525echo $expected > expout
7526expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
7527echo $expected >> expout
7528AT_CHECK([sort packets], [0], [expout])
f40c5588 7529sort packets | cat
26b9e08d 7530
f40c5588
MS
7531# Temporarily remove nat-addresses option to avoid race conditions
7532# due to GARP backoff
7533ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
7534
7535reset_pcap_file() {
7536 local iface=$1
7537 local pcap_file=$2
7538 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7539options:rxq_pcap=dummy-rx.pcap
7540 rm -f ${pcap_file}*.pcap
7541 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7542options:rxq_pcap=${pcap_file}-rx.pcap
7543}
7544
7545as hv1 reset_pcap_file snoopvif hv1/snoopvif
7546
7547# Add OVS ports for foo1 and foo2 on hv3
7548ovs-vsctl -- add-port br-int hv3-vif1 -- \
7549 set interface hv3-vif1 external-ids:iface-id=foo1 \
7550 ofport-request=1
7551ovs-vsctl -- add-port br-int hv3-vif2 -- \
7552 set interface hv3-vif2 external-ids:iface-id=foo2 \
7553 ofport-request=2
7554
7555# Add bridge-mapping on hv3
7556AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7557
7558# Re-add nat-addresses option
7559ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7560
7561# Wait for packets to be received.
7562OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
7563trim_zeros() {
7564 sed 's/\(00\)\{1,\}$//'
7565}
7566
7567$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7568expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
7569echo $expected >> expout
7570expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
7571echo $expected >> expout
7572AT_CHECK([sort packets], [0], [expout])
7573sort packets | cat
7574
7575OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
7576
7577AT_CLEANUP
6b785fd8
GS
7578
7579AT_SETUP([ovn -- /32 router IP address])
7580AT_SKIP_IF([test $HAVE_PYTHON = no])
7581ovn_start
7582
7583# Logical network:
7584# 2 LS 'foo' and 'alice' connected via router R1.
7585# R1 connects to 'alice' with a /32 IP address. We use static routes and
7586# nexthop to push traffic to a logical port in switch 'alice'
7587
7588ovn-nbctl lr-add R1
7589
7590ovn-nbctl ls-add foo
7591ovn-nbctl ls-add alice
7592
7593# Connect foo to R1
7594ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
7595ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7596 options:router-port=foo addresses=\"00:00:00:01:02:03\"
7597
7598# Connect alice to R1.
7599ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
7600ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7601 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
7602
7603# Create logical port foo1 in foo
7604ovn-nbctl lsp-add foo foo1 \
7605-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7606
7607# Create logical port alice1 in alice
7608ovn-nbctl lsp-add alice alice1 \
7609-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
7610
7611#install default route in R1 to use alice1's IP address as nexthop
7612ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
7613
7614# Create two hypervisor and create OVS ports corresponding to logical ports.
7615net_add n1
7616
7617sim_add hv1
7618as hv1
7619ovs-vsctl add-br br-phys
7620ovn_attach n1 br-phys 192.168.0.1
7621ovs-vsctl -- add-port br-int hv1-vif1 -- \
7622 set interface hv1-vif1 external-ids:iface-id=foo1 \
7623 options:tx_pcap=hv1/vif1-tx.pcap \
7624 options:rxq_pcap=hv1/vif1-rx.pcap \
7625 ofport-request=1
7626
7627sim_add hv2
7628as hv2
7629ovs-vsctl add-br br-phys
7630ovn_attach n1 br-phys 192.168.0.2
7631ovs-vsctl -- add-port br-int hv2-vif1 -- \
7632 set interface hv2-vif1 external-ids:iface-id=alice1 \
7633 options:tx_pcap=hv2/vif1-tx.pcap \
7634 options:rxq_pcap=hv2/vif1-rx.pcap \
7635 ofport-request=1
7636
7637
7638# Pre-populate the hypervisors' ARP tables so that we don't lose any
7639# packets for ARP resolution (native tunneling doesn't queue packets
7640# for ARP resolution).
7641ovn_populate_arp
7642
7643# Allow some time for ovn-northd and ovn-controller to catch up.
7644# XXX This should be more systematic.
7645sleep 1
7646
7647ip_to_hex() {
7648 printf "%02x%02x%02x%02x" "$@"
7649}
7650
7651# Send ip packets between foo1 and alice1
7652src_mac="f00000010203"
7653dst_mac="000000010203"
7654src_ip=`ip_to_hex 192 168 1 2`
7655dst_ip=`ip_to_hex 10 0 0 2`
7656packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7657
7658# Send the first packet to trigger a ARP response and population of
7659# mac_bindings table.
7660as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7661OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
7662
7663# Send the second packet to reach the destination.
7664as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7665
7666# Packet to Expect at 'alice1'
7667src_mac="000000010204"
7668dst_mac="f00000010204"
7669src_ip=`ip_to_hex 192 168 1 2`
7670dst_ip=`ip_to_hex 10 0 0 2`
7671echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
7672
7673OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7674
7675OVN_CLEANUP([hv1],[hv2])
7676
7677AT_CLEANUP
2a38ef45
DA
7678
7679AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
7680AT_SKIP_IF([test $HAVE_PYTHON = no])
7681ovn_start
7682
7683ovn-nbctl ls-add ls1
7684
7685# Add localport to the switch
7686ovn-nbctl lsp-add ls1 lp01
7687ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
7688ovn-nbctl lsp-set-type lp01 localport
7689
7690net_add n1
7691
7692for i in 1 2; do
7693 sim_add hv$i
7694 as hv$i
7695 ovs-vsctl add-br br-phys
7696 ovn_attach n1 br-phys 192.168.0.$i
7697 ovs-vsctl add-port br-int vif01 -- \
7698 set Interface vif01 external-ids:iface-id=lp01 \
7699 options:tx_pcap=hv${i}/vif01-tx.pcap \
7700 options:rxq_pcap=hv${i}/vif01-rx.pcap \
7701 ofport-request=${i}0
7702
7703 ovs-vsctl add-port br-int vif${i}1 -- \
7704 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
7705 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
7706 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
7707 ofport-request=${i}1
7708
7709 ovn-nbctl lsp-add ls1 lp${i}1
7710 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
7711 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
7712
7713 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
7714done
7715
7716ovn-nbctl --wait=sb sync
7717ovn-sbctl dump-flows
7718
7719ovn_populate_arp
7720
7721# Given the name of a logical port, prints the name of the hypervisor
7722# on which it is located.
7723vif_to_hv() {
7724 echo hv${1%?}
7725}
7726#
7727# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
7728#
7729# This shell function causes a packet to be received on INPORT. The packet's
7730# content has Ethernet destination DST and source SRC (each exactly 12 hex
7731# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
7732# logical switch port numbers, e.g. 11 for vif11.
7733#
7734# EOUT is the end-to-end output port, that is, where the packet will end up
7735# after possibly bouncing through one or more localnet ports. LOUT is the
7736# logical output port, which might be a localnet port, as seen by ovn-trace
7737# (which doesn't know what localnet ports are connected to and therefore can't
7738# figure out the end-to-end answer).
7739#
7740# DEFHV is the default hypervisor from where the packet is going to be sent
7741# if the source port is a localport.
7742for i in 1 2; do
7743 for j in 0 1; do
7744 : > $i$j.expected
7745 done
7746done
7747test_packet() {
7748 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
7749 echo "$@"
7750
7751 # First try tracing the packet.
7752 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
7753 if test $lout != drop; then
7754 echo "output(\"$lout\");"
7755 fi > expout
7756 AT_CAPTURE_FILE([trace])
7757 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
7758
7759 # Then actually send a packet, for an end-to-end test.
7760 local packet=$(echo $dst$src | sed 's/://g')${eth}
7761 hv=`vif_to_hv $inport`
7762 # If hypervisor 0 (localport) use the defhv parameter
da88b550 7763 if test $hv = hv0; then
2a38ef45
DA
7764 hv=$defhv
7765 fi
7766 vif=vif$inport
7767 as $hv ovs-appctl netdev-dummy/receive $vif $packet
7768 if test $eout != drop; then
7769 echo $packet >> ${eout#lp}.expected
7770 fi
7771}
7772
7773
7774# lp11 and lp21 are on different hypervisors
7775test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
7776test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
7777
7778# Both VIFs should be able to reach the localport on their own HV
7779test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
7780test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
7781
7782# Packet sent from localport on same hv should reach the vif
7783test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
7784test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
7785
7786# Packet sent from localport on different hv should be dropped
7787test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
7788test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
7789
7790# Now check the packets actually received against the ones expected.
7791for i in 1 2; do
7792 for j in 0 1; do
7793 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
7794 done
7795done
7796
7797OVN_CLEANUP([hv1],[hv2])
7798
7799AT_CLEANUP
1da17a0b 7800
7801AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
7802AT_SKIP_IF([test $HAVE_PYTHON = no])
7803ovn_start
7804
7805net_add n1
7806
7807# create gateways with external network connectivity
7808
7809for i in 1 2; do
7810 sim_add gw$i
7811 as gw$i
7812 ovs-vsctl add-br br-phys
7813 ovn_attach n1 br-phys 192.168.0.$i
7814 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7815done
7816
7817ovn-nbctl ls-add inside
7818ovn-nbctl ls-add outside
7819
7820# create hypervisors with a vif port each to an internal network
7821
7822for i in 1 2; do
7823 sim_add hv$i
7824 as hv$i
7825 ovs-vsctl add-br br-phys
7826 ovn_attach n1 br-phys 192.168.0.1$i
7827 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
7828 set interface hv$i-vif1 external-ids:iface-id=inside$i \
7829 options:tx_pcap=hv$i/vif1-tx.pcap \
7830 options:rxq_pcap=hv$i/vif1-rx.pcap \
7831 ofport-request=1
7832
7833 ovn-nbctl lsp-add inside inside$i \
7834 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
7835
7836done
7837
7838ovn_populate_arp
7839
7840ovn-nbctl create Logical_Router name=R1
7841
7842# Connect inside to R1
7843ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
7844ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
7845 type=router options:router-port=inside \
7846 -- lsp-set-addresses rp-inside router
7847
7848# Connect outside to R1 as distributed router gateway port on gw1+gw2
7849ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
7850
7851ovn-nbctl --id=@gc0 create Gateway_Chassis \
7852 name=outside_gw1 chassis_name=gw1 priority=20 -- \
7853 --id=@gc1 create Gateway_Chassis \
7854 name=outside_gw2 chassis_name=gw2 priority=10 -- \
7855 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
7856
7857ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
7858 type=router options:router-port=outside \
7859 -- lsp-set-addresses rp-outside router
7860
7861# Create localnet port in outside
7862ovn-nbctl lsp-add outside ln-outside
7863ovn-nbctl lsp-set-addresses ln-outside unknown
7864ovn-nbctl lsp-set-type ln-outside localnet
7865ovn-nbctl lsp-set-options ln-outside network_name=phys
7866
7867# Allow some time for ovn-northd and ovn-controller to catch up.
7868# XXX This should be more systematic.
8e1d9349 7869ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 7870
7871echo "---------NB dump-----"
7872ovn-nbctl show
7873echo "---------------------"
7874ovn-nbctl list logical_router
7875echo "---------------------"
7876ovn-nbctl list logical_router_port
7877echo "---------------------"
7878
7879echo "---------SB dump-----"
7880ovn-sbctl list datapath_binding
7881echo "---------------------"
7882ovn-sbctl list port_binding
7883echo "---------------------"
7884ovn-sbctl dump-flows
7885echo "---------------------"
7886ovn-sbctl list chassis
7887ovn-sbctl list encap
7888echo "---------------------"
7889echo "------ Gateway_Chassis dump (SBDB) -------"
7890ovn-sbctl list Gateway_Chassis
7891echo "------ Port_Binding chassisredirect -------"
7892ovn-sbctl find Port_Binding type=chassisredirect
7893echo "-------------------------------------------"
7894
3475695e
VA
7895for chassis in gw1 gw2 hv1 hv2; do
7896 as $chassis
7897 echo "------ $chassis dump ----------"
7898 ovs-ofctl show br-int
7899 ovs-ofctl dump-flows br-int
3475695e
VA
7900 echo "--------------------------"
7901done
508b7f96 7902function bfd_dump() {
7903 for chassis in gw1 gw2 hv1 hv2; do
7904 as $chassis
7905 echo "------ $chassis dump (BFD)----"
7906 echo "BFD (from $chassis):"
7907 # dump BFD config and status to the other chassis
7908 for chassis2 in gw1 gw2 hv1 hv2; do
7909 if [[ "$chassis" != "$chassis2" ]]; then
7910 echo " -> $chassis2:"
7911 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
7912 fi
7913 done
7914 echo "--------------------------"
7915 done
7916}
7917
7918bfd_dump
1da17a0b 7919
7920hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
7921hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
7922hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
7923hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
7924
7925echo $hv1_gw1_ofport
7926echo $hv1_gw2_ofport
7927echo $hv2_gw1_ofport
7928echo $hv2_gw2_ofport
7929
7930echo "--- hv1 ---"
7931as hv1 ovs-ofctl dump-flows br-int table=32
7932
7933echo "--- hv2 ---"
7934as hv2 ovs-ofctl dump-flows br-int table=32
7935
508b7f96 7936gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
7937gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
7938
1da17a0b 7939AT_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
7940])
7941
7942AT_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
7943])
7944
508b7f96 7945sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
7946
7947# make sure that flows for handling the outside router port reside on gw1
7948AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
7949]])
7950AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
7951]])
7952
7953# make sure ARP responder flows for outside router port reside on gw1 too
7954AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
7955]])
7956AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
7957]])
7958
7959
7960
7961# check that the chassis redirect port has been claimed by the gw1 chassis
7962AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
7963 [0],[[1
7964]])
7965
7966
7967# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 7968
7969ovn-nbctl --id=@gc0 create Gateway_Chassis \
7970 name=outside_gw1 chassis_name=gw1 priority=10 -- \
7971 --id=@gc1 create Gateway_Chassis \
7972 name=outside_gw2 chassis_name=gw2 priority=20 -- \
7973 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
7974
508b7f96 7975
1da17a0b 7976# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 7977ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 7978
508b7f96 7979# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 7980AT_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
7981])
7982
7983AT_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
7984])
7985
508b7f96 7986# check that the chassis redirect port has been reclaimed by the gw2 chassis
7987AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
7988 [0],[[1
7989]])
1da17a0b 7990
3475695e
VA
7991# check BFD enablement on tunnel ports from gw1 #########
7992as gw1
7993for chassis in gw2 hv1 hv2; do
7994 echo "checking gw1 -> $chassis"
7995 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
7996 [[enable=true
7997]])
7998done
7999
8000
8001# check BFD enablement on tunnel ports from gw2 ##########
8002as gw2
8003for chassis in gw1 hv1 hv2; do
8004 echo "checking gw2 -> $chassis"
8005 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8006 [[enable=true
8007]])
8008done
8009
8010# check BFD enablement on tunnel ports from hv1 ###########
8011as hv1
8012for chassis in gw1 gw2; do
8013 echo "checking hv1 -> $chassis"
8014 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8015 [[enable=true
8016]])
8017done
8018# make sure BFD is not enabled to hv2, we don't need it
8019AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8020 [[enable=false
8021]])
8022
8023
8024# check BFD enablement on tunnel ports from hv2 ##########
8025as hv2
8026for chassis in gw1 gw2; do
8027 echo "checking hv2 -> $chassis"
8028 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8029 [[enable=true
8030]])
8031done
8032# make sure BFD is not enabled to hv1, we don't need it
8033AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8034 [[enable=false
8035]])
8036
508b7f96 8037sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8038
8039# make sure that flows for handling the outside router port reside on gw2 now
8040AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8041]])
8042AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8043]])
8044
8045# disconnect GW2 from the network, GW1 should take over
8046as gw2
8047port=${sandbox}_br-phys
8048as main ovs-vsctl del-port n1 $port
8049sleep 4
8050
8051bfd_dump
8052
8053# make sure that flows for handling the outside router port reside on gw2 now
8054AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8055]])
8056AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8057]])
8058
8059# check that the chassis redirect port has been reclaimed by the gw1 chassis
8060AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8061 [0],[[1
8062]])
8063
1da17a0b 8064OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8065
8066AT_CLEANUP
acfc41ff
VAK
8067
8068AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8069AT_SKIP_IF([test $HAVE_PYTHON = no])
8070ovn_start
8071ovn-nbctl ls-add ls0
8072ovn-nbctl ls-add ls1
8073ovn-nbctl create Logical_Router name=lr0
8074ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8075
8076ovn-nbctl --id=@gc0 create Gateway_Chassis \
8077 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8078 --id=@gc1 create Gateway_Chassis \
8079 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8080 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8081
8082ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8083 type=router options:router-port=lrp0 addresses="router"
8084ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8085ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8086 type=router options:router-port=lrp1 addresses="router"
8087
8088# Add NAT rules
8089AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8090
8091net_add n1
8092sim_add hv1
8093as hv1
8094ovs-vsctl add-br br-phys
8095ovn_attach n1 br-phys 192.168.0.1
8096AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8097AT_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])
8098
8099sim_add hv2
8100as hv2
8101ovs-vsctl add-br br-phys
8102ovn_attach n1 br-phys 192.168.0.2
8103AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8104
8105sim_add hv3
8106as hv3
8107ovs-vsctl add-br br-phys
8108ovn_attach n1 br-phys 192.168.0.3
8109AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8110
8111# Create a localnet port.
8112AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8113AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8114AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8115AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8116
8117# wait for earlier changes to take effect
8118AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8119
8120reset_pcap_file() {
8121 local iface=$1
8122 local pcap_file=$2
8123 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8124options:rxq_pcap=dummy-rx.pcap
8125 rm -f ${pcap_file}*.pcap
8126 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8127options:rxq_pcap=${pcap_file}-rx.pcap
8128}
8129
8130as hv1 reset_pcap_file snoopvif hv1/snoopvif
8131as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8132as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8133# add nat-addresses option
8134ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8135
8136# Wait for packets to be received through hv2.
8137OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8138trim_zeros() {
8139 sed 's/\(00\)\{1,\}$//'
8140}
8141
2db7bb2c 8142only_broadcast_from_lrp1() {
8143 grep "fffffffffffff00000000001"
8144}
8145
acfc41ff 8146garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 8147echo $garp > expout
8148
8149$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
8150echo "packets on hv1-snoopvif:"
8151cat hv1_snoop_tx
8152AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 8153$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
8154echo "packets on hv2 br-phys tx"
8155cat hv2_br_phys_tx
8156AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 8157$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
8158echo "packets on hv3 br-phys tx"
8159cat hv3_br_phys_tx
8160AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8161
8162
8163# at this point, we invert the priority of the gw chassis between hv2 and hv3
8164
8165ovn-nbctl --wait=hv \
8166 --id=@gc0 create Gateway_Chassis \
8167 name=outside_gw1 chassis_name=hv2 priority=1 -- \
8168 --id=@gc1 create Gateway_Chassis \
8169 name=outside_gw2 chassis_name=hv3 priority=10 -- \
8170 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8171
8172
8173as hv1 reset_pcap_file snoopvif hv1/snoopvif
8174as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8175as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8176
8177# Wait for packets to be received.
8178OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8179trim_zeros() {
8180 sed 's/\(00\)\{1,\}$//'
8181}
8182
2db7bb2c 8183$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 8184AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 8185$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 8186AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 8187$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
8188AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8189OVN_CLEANUP([hv1],[hv2],[hv3])
8190
8191AT_CLEANUP
79371ff5 8192
8193AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8194AT_SKIP_IF([test $HAVE_PYTHON = no])
8195ovn_start
8196
8197net_add n1
8198
8199# create two gateways with external network connectivity
8200for i in 1 2; do
8201 sim_add gw$i
8202 as gw$i
8203 ovs-vsctl add-br br-phys
8204 ovn_attach n1 br-phys 192.168.0.$i
8205 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8206done
8207
8208ovn-nbctl ls-add inside
8209ovn-nbctl ls-add outside
8210
8211# create one hypervisors with a vif port the internal network
8212sim_add hv1
8213as hv1
8214ovs-vsctl add-br br-phys
8215ovn_attach n1 br-phys 192.168.0.11
8216ovs-vsctl -- add-port br-int hv1-vif1 -- \
8217 set interface hv1-vif1 external-ids:iface-id=inside1 \
8218 options:tx_pcap=hv1/vif1-tx.pcap \
8219 options:rxq_pcap=hv1/vif1-rx.pcap \
8220 ofport-request=1
8221
8222ovn-nbctl lsp-add inside inside1 \
8223 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
8224
8225
8226ovn_populate_arp
8227
8228ovn-nbctl create Logical_Router name=R1
8229
8230# Connect inside to R1
8231ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8232ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8233 type=router options:router-port=inside \
8234 -- lsp-set-addresses rp-inside router
8235
8236# Connect outside to R1 as distributed router gateway port on gw1+gw2
8237ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8238
8239ovn-nbctl --id=@gc0 create Gateway_Chassis \
8240 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8241 --id=@gc1 create Gateway_Chassis \
8242 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8243 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8244
8245ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8246 type=router options:router-port=outside \
8247 -- lsp-set-addresses rp-outside router
8248
8249# Create localnet port in outside
8250ovn-nbctl lsp-add outside ln-outside
8251ovn-nbctl lsp-set-addresses ln-outside unknown
8252ovn-nbctl lsp-set-type ln-outside localnet
8253ovn-nbctl lsp-set-options ln-outside network_name=phys
8254
8255# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 8256ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 8257
8258# currently when ovn-controller is restarted, the old entry is deleted
8259# and a new one is created, which leaves the Gateway_Chassis with
8260# an empty chassis for a while. NOTE: restarting ovn-controller in tests
8261# doesn't have the same effect because "name" is conserved, and the
8262# Chassis entry is not replaced.
8263
325b2b1a 8264truncate -s 0 gw1/ovn-controller.log
8265
79371ff5 8266gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8267ovn-sbctl destroy Chassis $gw2_chassis
8268
8269# Ensure ovn-controller has processed latest sbdb update
8270# ovn-nbctl --wait=hv sync
8271
8272AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
8273
8274OVN_CLEANUP([gw1],[gw2],[hv1])
8275
8276AT_CLEANUP