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