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