]> git.proxmox.com Git - mirror_ovs.git/blame - tests/ovn.at
ovn-test: Add 'expr-to-packets' command.
[mirror_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
9d4aecca
BP
456AT_SETUP([ovn -- 4-term numeric expression normalization])
457AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
8c3caa2c 458 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
459])
460AT_CLEANUP
461
9d4aecca
BP
462AT_SETUP([ovn -- 4-term string expression normalization])
463AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
464 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
465])
466AT_CLEANUP
467
468AT_SETUP([ovn -- 4-term mixed expression normalization])
469AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
8c3caa2c 470 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
9d4aecca
BP
471])
472AT_CLEANUP
473
474AT_SETUP([ovn -- 5-term numeric expression normalization])
475AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
8c3caa2c 476 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
9d4aecca
BP
477])
478AT_CLEANUP
479
480AT_SETUP([ovn -- 5-term string expression normalization])
481AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
482 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
483])
484AT_CLEANUP
485
486AT_SETUP([ovn -- 5-term mixed expression normalization])
487AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
8c3caa2c 488 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
489])
490AT_CLEANUP
491
492AT_SETUP([ovn -- 4-term numeric expressions to flows])
8c3caa2c 493AT_KEYWORDS([expression])
9d4aecca 494AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
8c3caa2c 495 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
9d4aecca
BP
496])
497AT_CLEANUP
498
499AT_SETUP([ovn -- 4-term string expressions to flows])
8c3caa2c 500AT_KEYWORDS([expression])
9d4aecca
BP
501AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
502 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
503])
504AT_CLEANUP
505
506AT_SETUP([ovn -- 4-term mixed expressions to flows])
8c3caa2c 507AT_KEYWORDS([expression])
9d4aecca 508AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
8c3caa2c 509 [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
510])
511AT_CLEANUP
512
513AT_SETUP([ovn -- 3-term numeric expressions to flows])
8c3caa2c 514AT_KEYWORDS([expression])
9d4aecca 515AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
8c3caa2c 516 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
517])
518AT_CLEANUP
f386a8a7
BP
519
520AT_SETUP([ovn -- converting expressions to flows -- string fields])
8c3caa2c 521AT_KEYWORDS([expression])
f386a8a7
BP
522expr_to_flow () {
523 echo "$1" | ovstest test-ovn expr-to-flows | sort
524}
cc5e28d8 525AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 526])
cc5e28d8 527AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
528])
529AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
530])
531AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
532ip,reg14=0x5
533ipv6,reg14=0x5
f386a8a7
BP
534])
535AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
536ip,reg14=0x6
537ipv6,reg14=0x6
f386a8a7
BP
538])
539AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
540])
541AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
542[reg14=0x5
543reg14=0x6
544reg14=0xfffe
f386a8a7
BP
545])
546AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
547ip,reg14=0x5
548ip,reg14=0x6
549ipv6,reg14=0x5
550ipv6,reg14=0x6
f386a8a7 551])
9d4aecca
BP
552AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
553(no flows)
554])
f386a8a7 555AT_CLEANUP
3b7cb7e1 556
2c5cbb15 557AT_SETUP([ovn -- converting expressions to flows -- address sets])
8c3caa2c 558AT_KEYWORDS([expression])
2c5cbb15
RB
559expr_to_flow () {
560 echo "$1" | ovstest test-ovn expr-to-flows | sort
561}
562AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
563ip,nw_src=10.0.0.1
564ip,nw_src=10.0.0.2
565ip,nw_src=10.0.0.3
566])
567AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
568ip,nw_src=10.0.0.1
569ip,nw_src=10.0.0.2
570ip,nw_src=10.0.0.3
571])
572AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
573ip,nw_src=1.2.3.4
574ip,nw_src=10.0.0.1
575ip,nw_src=10.0.0.2
576ip,nw_src=10.0.0.3
577])
578AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
579ip,nw_src=1.2.0.0/20
580ip,nw_src=10.0.0.1
581ip,nw_src=10.0.0.2
582ip,nw_src=10.0.0.3
583ip,nw_src=5.5.5.0/24
584])
585AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
586ipv6,ipv6_src=::1
587ipv6,ipv6_src=::2
588ipv6,ipv6_src=::3
589])
590AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
591ipv6,ipv6_src=::1
592ipv6,ipv6_src=::2
593ipv6,ipv6_src=::3
594ipv6,ipv6_src=::4
595])
596AT_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
597dl_src=00:00:00:00:00:01
598dl_src=00:00:00:00:00:02
599dl_src=00:00:00:00:00:03
600])
601AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
602dl_src=00:00:00:00:00:01
603dl_src=00:00:00:00:00:02
604dl_src=00:00:00:00:00:03
605])
ea382567
RB
606AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
607dl_src=00:00:00:00:00:01
608dl_src=00:00:00:00:00:02
609dl_src=00:00:00:00:00:03
610dl_src=ba:be:be:ef:de:ad
611])
2c5cbb15
RB
612AT_CLEANUP
613
3b7cb7e1 614AT_SETUP([ovn -- action parsing])
d5a76da4
BP
615dnl Unindented text is input (a set of OVN logical actions).
616dnl Indented text is expected output.
617AT_DATA([test-cases.txt],
618[[# drop
619drop;
620 encodes as drop
621drop; next;
622 Syntax error at `next' expecting end of input.
623next; drop;
624 Syntax error at `drop' expecting action.
5f822129
BP
625
626# output
d5a76da4
BP
627output;
628 encodes as resubmit(,64)
5f822129
BP
629
630# next
d5a76da4
BP
631next;
632 formats as next(11);
633 encodes as resubmit(,27)
634next(11);
635 encodes as resubmit(,27)
636next(0);
637 encodes as resubmit(,16)
638next(15);
639 encodes as resubmit(,31)
640
641next();
642 Syntax error at `)' expecting small integer.
643next(10;
644 Syntax error at `;' expecting `)'.
645next(16);
646 "next" argument must be in range 0 to 15.
5f822129
BP
647
648# Loading a constant value.
d5a76da4
BP
649tcp.dst=80;
650 formats as tcp.dst = 80;
651 encodes as set_field:80->tcp_dst
652 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
653eth.dst[40] = 1;
654 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
655vlan.pcp = 2;
656 encodes as set_field:0x4000/0xe000->vlan_tci
657 has prereqs vlan.tci[12]
658vlan.tci[13..15] = 2;
659 encodes as set_field:0x4000/0xe000->vlan_tci
660inport = "";
661 encodes as set_field:0->reg14
662ip.ttl=4;
663 formats as ip.ttl = 4;
664 encodes as set_field:4->nw_ttl
665 has prereqs eth.type == 0x800 || eth.type == 0x86dd
666outport="eth0"; next; outport="LOCAL"; next;
667 formats as outport = "eth0"; next(11); outport = "LOCAL"; next(11);
668 encodes as set_field:0x5->reg15,resubmit(,27),set_field:0xfffe->reg15,resubmit(,27)
669
670inport[1] = 1;
671 Cannot select subfield of string field inport.
672ip.proto[1] = 1;
673 Cannot select subfield of nominal field ip.proto.
674eth.dst[40] == 1;
675 Syntax error at `==' expecting `=' or `<->'.
676ip = 1;
677 Predicate symbol ip used where lvalue required.
678ip.proto = 6;
679 Field ip.proto is not modifiable.
680inport = {"a", "b"};
681 Syntax error at `{' expecting constant.
682inport = {};
683 Syntax error at `{' expecting constant.
684bad_prereq = 123;
685 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
686self_recurse = 123;
687 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'.
688vlan.present = 0;
689 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
690
691# Moving one field into another.
d5a76da4
BP
692reg0=reg1;
693 formats as reg0 = reg1;
694 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
695vlan.pcp = reg0[0..2];
696 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
697 has prereqs vlan.tci[12]
698reg0[10] = vlan.pcp[1];
699 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
700 has prereqs vlan.tci[12]
701outport = inport;
702 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
703
704reg0[0] = vlan.present;
705 Predicate symbol vlan.present used where lvalue required.
706reg0 = reg1[0..10];
707 Can't assign 11-bit value to 32-bit destination.
708inport = reg0;
709 Can't assign integer field (reg0) to string field (inport).
710inport = big_string;
711 String fields inport and big_string are incompatible for assignment.
712ip.proto = reg0[0..7];
713 Field ip.proto is not modifiable.
5f822129
BP
714
715# Exchanging fields.
d5a76da4
BP
716reg0 <-> reg1;
717 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]
718vlan.pcp <-> reg0[0..2];
719 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]
720 has prereqs vlan.tci[12]
721reg0[10] <-> vlan.pcp[1];
722 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
723 has prereqs vlan.tci[12]
724outport <-> inport;
725 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
726
727reg0[0] <-> vlan.present;
728 Predicate symbol vlan.present used where lvalue required.
729reg0 <-> reg1[0..10];
730 Can't exchange 32-bit field with 11-bit field.
731inport <-> reg0;
732 Can't exchange string field (inport) with integer field (reg0).
733inport <-> big_string;
734 String fields inport and big_string are incompatible for exchange.
735ip.proto <-> reg0[0..7];
736 Field ip.proto is not modifiable.
737reg0[0..7] <-> ip.proto;
738 Field ip.proto is not modifiable.
5f822129
BP
739
740# TTL decrement.
d5a76da4
BP
741ip.ttl--;
742 encodes as dec_ttl
743 has prereqs ip
744ip.ttl
745 Syntax error at end of input expecting `--'.
5f822129 746
467085fd 747# load balancing.
d5a76da4
BP
748ct_lb;
749 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
750 has prereqs ip
751ct_lb();
752 formats as ct_lb;
753 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
754 has prereqs ip
755ct_lb(192.168.1.2:80, 192.168.1.3:80);
756 encodes as group:1
757 has prereqs ip
758ct_lb(192.168.1.2, 192.168.1.3, );
759 formats as ct_lb(192.168.1.2, 192.168.1.3);
760 encodes as group:2
761 has prereqs ip
762
763ct_lb(192.168.1.2:);
764 Syntax error at `)' expecting port number.
765ct_lb(192.168.1.2:123456);
766 Syntax error at `123456' expecting port number.
767ct_lb(foo);
768 Syntax error at `foo' expecting IPv4 address.
769
770# ct_next
771ct_next;
772 encodes as ct(table=27,zone=NXM_NX_REG13[0..15])
773 has prereqs ip
774
775# ct_commit
776ct_commit;
777 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
778 has prereqs ip
779ct_commit();
780 formats as ct_commit;
781 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
782 has prereqs ip
783ct_commit(ct_mark=1);
784 formats as ct_commit(ct_mark=0x1);
785 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
786 has prereqs ip
787ct_commit(ct_mark=1/1);
788 formats as ct_commit(ct_mark=0x1/0x1);
789 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
790 has prereqs ip
791ct_commit(ct_label=1);
792 formats as ct_commit(ct_label=0x1);
793 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
794 has prereqs ip
795ct_commit(ct_label=1/1);
796 formats as ct_commit(ct_label=0x1/0x1);
797 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
798 has prereqs ip
799ct_commit(ct_mark=1, ct_label=2);
800 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
801 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
802 has prereqs ip
803
804ct_commit(ct_label=0x01020304050607080910111213141516);
805 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
806 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
807 has prereqs ip
808ct_commit(ct_label=0x181716151413121110090807060504030201);
809 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
810 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
811 has prereqs ip
812ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
813 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
814 has prereqs ip
815ct_commit(ct_label=18446744073709551615);
816 formats as ct_commit(ct_label=0xffffffffffffffff);
817 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
818 has prereqs ip
819ct_commit(ct_label=18446744073709551616);
820 Decimal constants must be less than 2**64.
821
822# ct_dnat
823ct_dnat;
824 encodes as ct(table=27,zone=NXM_NX_REG11[0..15],nat)
825 has prereqs ip
826ct_dnat(192.168.1.2);
827 encodes as ct(commit,table=27,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
828 has prereqs ip
829
830ct_dnat(192.168.1.2, 192.168.1.3);
831 Syntax error at `,' expecting `)'.
832ct_dnat(foo);
833 Syntax error at `foo' expecting IPv4 address.
834ct_dnat(foo, bar);
835 Syntax error at `foo' expecting IPv4 address.
836ct_dnat();
837 Syntax error at `)' expecting IPv4 address.
838
839# ct_snat
840ct_snat;
841 encodes as ct(zone=NXM_NX_REG12[0..15],nat)
842 has prereqs ip
843ct_snat(192.168.1.2);
844 encodes as ct(commit,table=27,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
845 has prereqs ip
846
847ct_snat(192.168.1.2, 192.168.1.3);
848 Syntax error at `,' expecting `)'.
849ct_snat(foo);
850 Syntax error at `foo' expecting IPv4 address.
851ct_snat(foo, bar);
852 Syntax error at `foo' expecting IPv4 address.
853ct_snat();
854 Syntax error at `)' expecting IPv4 address.
de297547 855
6335d074 856# arp
d5a76da4
BP
857arp { eth.dst = ff:ff:ff:ff:ff:ff; output; };
858 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)
859 has prereqs ip4
6335d074 860
0bac7164 861# get_arp
d5a76da4
BP
862get_arp(outport, ip4.dst);
863 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[]
864 has prereqs eth.type == 0x800
865get_arp(inport, reg0);
866 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[]
867
868get_arp;
869 Syntax error at `;' expecting `('.
870get_arp();
871 Syntax error at `)' expecting field name.
872get_arp(inport);
873 Syntax error at `)' expecting `,'.
874get_arp(inport ip4.dst);
875 Syntax error at `ip4.dst' expecting `,'.
876get_arp(inport, ip4.dst;
877 Syntax error at `;' expecting `)'.
878get_arp(inport, eth.dst);
879 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
880get_arp(inport, outport);
881 Cannot use string field outport where numeric field is required.
882get_arp(reg0, ip4.dst);
883 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
884
885# put_arp
d5a76da4
BP
886put_arp(inport, arp.spa, arp.sha);
887 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[]
888 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 889
42814145 890# put_dhcp_opts
d5a76da4
BP
891reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
892 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)
893reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
894 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");
895 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)
896reg0[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);
897 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);
898 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)
899
900reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
901 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
902reg1[0] = put_dhcp_opts();
903 put_dhcp_opts requires offerip to be specified.
904reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
905 Syntax error at `x' expecting DHCPv4 option name.
906reg1[0] = put_dhcp_opts(router = 10.0.0.1);
907 put_dhcp_opts requires offerip to be specified.
908reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
909 Syntax error at `"hi"'.
910reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
911 Syntax error at `xyzzy' expecting DHCPv4 option name.
912reg1[0] = put_dhcp_opts(offerip="xyzzy");
913 DHCPv4 option offerip requires numeric value.
914reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
915 DHCPv4 option domain requires string value.
42814145 916
f8a8db39 917# nd_na
d5a76da4
BP
918nd_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; };
919 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
920 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)
921 has prereqs nd_ns
e75451fe 922
c34a87b6 923# get_nd
d5a76da4
BP
924get_nd(outport, ip6.dst);
925 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[]
926 has prereqs eth.type == 0x86dd
927get_nd(inport, xxreg0);
928 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[]
929get_nd;
930 Syntax error at `;' expecting `('.
931get_nd();
932 Syntax error at `)' expecting field name.
933get_nd(inport);
934 Syntax error at `)' expecting `,'.
935get_nd(inport ip6.dst);
936 Syntax error at `ip6.dst' expecting `,'.
937get_nd(inport, ip6.dst;
938 Syntax error at `;' expecting `)'.
939get_nd(inport, eth.dst);
940 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
941get_nd(inport, outport);
942 Cannot use string field outport where numeric field is required.
943get_nd(xxreg0, ip6.dst);
944 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
945
946# put_nd
d5a76da4
BP
947put_nd(inport, nd.target, nd.sll);
948 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[]
949 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 950
01cfdb2f 951# put_dhcpv6_opts
d5a76da4 952reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
a55dacac 953 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
954reg1[0] = put_dhcpv6_opts();
955 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
956reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
957 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
a55dacac 958 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
959reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
960 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
a55dacac 961 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 962reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
a55dacac 963 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
964reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
965 Syntax error at `x' expecting DHCPv6 option name.
966reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
967 Syntax error at `"hi"'.
968reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
969 Syntax error at `xyzzy' expecting DHCPv6 option name.
970reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
971 DHCPv6 option ia_addr requires numeric value.
972reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
973 DHCPv6 option domain_search requires string value.
01cfdb2f 974
a6095f81
BS
975# set_queue
976set_queue(0);
977 encodes as set_queue:0
978set_queue(61440);
979 encodes as set_queue:61440
980set_queue(65535);
981 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
982
5f822129 983# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
984ip4.src = ip6.src[0..31];
985 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
986 has prereqs eth.type == 0x800 && eth.type == 0x86dd
987ip4.src <-> ip6.src[0..31];
988 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[]
989 has prereqs eth.type == 0x800 && eth.type == 0x86dd
990
991# Miscellaneous negative tests.
992;
993 Syntax error at `;'.
994xyzzy;
995 Syntax error at `xyzzy' expecting action.
996next; 123;
997 Syntax error at `123'.
998next; xyzzy;
999 Syntax error at `xyzzy' expecting action.
1000next
9aef3c1b 1001 Syntax error at end of input expecting `;'.
3b7cb7e1 1002]])
d5a76da4
BP
1003sed '/^[[ ]]/d' test-cases.txt > input.txt
1004cp test-cases.txt expout
3b7cb7e1
BP
1005AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1006AT_CLEANUP
f295c17b
BP
1007
1008AT_BANNER([OVN end-to-end tests])
1009
9975d7be
BP
1010# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1011AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1012AT_KEYWORDS([ovnarp])
f295c17b
BP
1013AT_SKIP_IF([test $HAVE_PYTHON = no])
1014ovn_start
1015
1016# Create hypervisors hv[123].
9975d7be 1017# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1018# Add all of the vifs to a single logical switch lsw0.
1019# Turn on port security on all the vifs except vif[123]1.
1020# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1021# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1022ovn-nbctl ls-add lsw0
f295c17b
BP
1023net_add n1
1024for i in 1 2 3; do
1025 sim_add hv$i
1026 as hv$i
1027 ovs-vsctl add-br br-phys
1028 ovn_attach n1 br-phys 192.168.0.$i
1029
1030 for j in 1 2 3; do
1031 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 1032 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1033 if test $j = 1; then
31ed1192 1034 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1035 else
7dc88496
NS
1036 if test $j = 3; then
1037 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1038 else
1039 ip_addrs="192.168.0.$i$j"
1040 fi
31ed1192
JP
1041 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1042 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1043 fi
1044 done
1045done
1046ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1047ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1048ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1049ovn-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\"
1050ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b
BP
1051
1052# Pre-populate the hypervisors' ARP tables so that we don't lose any
1053# packets for ARP resolution (native tunneling doesn't queue packets
1054# for ARP resolution).
1055ovn_populate_arp
1056
1057# Allow some time for ovn-northd and ovn-controller to catch up.
1058# XXX This should be more systematic.
1059sleep 1
611099dc 1060
fc6f9978
HZ
1061# Make sure there is no attempt to adding duplicated flows by ovn-controller
1062AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1063AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1064AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1065
57d143eb
HZ
1066# Given the name of a logical port, prints the name of the hypervisor
1067# on which it is located.
1068vif_to_hv() {
1069 echo hv${1%?}
1070}
1071
f295c17b
BP
1072# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1073#
1074# This shell function causes a packet to be received on INPORT. The packet's
1075# content has Ethernet destination DST and source SRC (each exactly 12 hex
1076# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1077# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1078# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1079for i in 1 2 3; do
1080 for j in 1 2 3; do
1081 : > $i$j.expected
1082 done
1083done
1084test_packet() {
1085 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1086 hv=`vif_to_hv $inport`
f295c17b
BP
1087 vif=vif$inport
1088 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1089 for outport; do
e4543cfe 1090 echo $packet >> $outport.expected
f295c17b
BP
1091 done
1092}
1093
57d143eb
HZ
1094# test_arp INPORT SHA SPA TPA [REPLY_HA]
1095#
1096# Causes a packet to be received on INPORT. The packet is an ARP
1097# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1098# it should be the hardware address of the target to expect to receive in an
1099# ARP reply; otherwise no reply is expected.
1100#
31ed1192 1101# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1102# SHA and REPLY_HA are each 12 hex digits.
1103# SPA and TPA are each 8 hex digits.
1104test_arp() {
1105 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1106 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1107 hv=`vif_to_hv $inport`
1108 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1109
92f9822b 1110 if test X$reply_ha = X; then
57d143eb
HZ
1111 # Expect to receive the broadcast ARP on the other logical switch ports
1112 # if no reply is expected.
1113 local i j
1114 for i in 1 2 3; do
1115 for j in 1 2 3; do
1116 if test $i$j != $inport; then
1117 echo $request >> $i$j.expected
1118 fi
1119 done
1120 done
1121 else
1122 # Expect to receive the reply, if any.
1123 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1124 echo $reply >> $inport.expected
1125 fi
1126}
1127
1128ip_to_hex() {
1129 printf "%02x%02x%02x%02x" "$@"
1130}
1131
f295c17b
BP
1132# Send packets between all pairs of source and destination ports:
1133#
31ed1192
JP
1134# 1. Unicast packets are delivered to exactly one logical switch port
1135# (except that packets destined to their input ports are dropped).
f295c17b 1136#
31ed1192
JP
1137# 2. Broadcast and multicast are delivered to all logical switch ports
1138# except the input port.
f295c17b 1139#
ea46a4e9 1140# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1141# MAC address.
1142#
ea46a4e9 1143# 4. The switch drops all packets with a VLAN tag.
f295c17b 1144#
ea46a4e9 1145# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1146# affects behavior when port security is turned off, since otherwise port
1147# security would drop the packet anyway.)
1148#
ea46a4e9 1149# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1150# switch ports with "unknown" among their MAC addresses (and port
1151# security disabled).
f295c17b 1152#
ea46a4e9 1153# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1154#
ea46a4e9 1155# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1156#
9fcb6a18
BP
1157# 9. OVN generates responses to ARP requests for known IPs, except for
1158# requests from a port for the port's own IP.
57d143eb
HZ
1159#
1160# 10. No response to ARP requests for unknown IPs.
4acd1e87 1161
f295c17b
BP
1162for is in 1 2 3; do
1163 for js in 1 2 3; do
1164 s=$is$js
1165 bcast=
4d5c43d5
JP
1166 unknown=
1167 bacl2=
1168 bacl3=
f295c17b
BP
1169 for id in 1 2 3; do
1170 for jd in 1 2 3; do
1171 d=$id$jd
1172
1173 if test $d != $s; then unicast=$d; else unicast=; fi
1174 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1175
1176 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1177 impersonate=$d
1178 else
1179 impersonate=
1180 fi
f295c17b
BP
1181 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1182
4d5c43d5
JP
1183 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1184 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1185 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1186 # Source of 11, 21, or 31 and dest of 33 should be dropped
1187 # due to the 4th ACL that uses address_set(set1).
1188 acl4=
1189 else
1190 acl4=$d
1191 fi
f295c17b
BP
1192 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1193 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1194 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1195 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
f295c17b
BP
1196
1197 test_packet $s f000000000$d f00000000055 810000091234 #4
1198 test_packet $s f000000000$d 0100000000$s $s$d #5
1199
4d5c43d5
JP
1200 if test $d != $s && test $jd = 1; then
1201 unknown="$unknown $d"
1202 fi
f295c17b
BP
1203 bcast="$bcast $unicast"
1204 bacl2="$bacl2 $acl2"
1205 bacl3="$bacl3 $acl3"
57d143eb
HZ
1206
1207 sip=`ip_to_hex 192 168 0 $i$j`
1208 tip=`ip_to_hex 192 168 0 $id$jd`
1209 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1210 if test $d != $s; then
1211 reply_ha=f000000000$d
1212 else
1213 reply_ha=
1214 fi
1215 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1216 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1217
1218 if test $jd = 3; then
31ed1192 1219 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1220 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1221 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1222 fi
f295c17b
BP
1223 done
1224 done
1225
4d5c43d5 1226 # Broadcast and multicast.
f295c17b
BP
1227 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1228 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1229 if test $js = 1; then
f295c17b
BP
1230 bcast_impersonate=$bcast
1231 else
4d5c43d5
JP
1232 bcast_impersonate=
1233 fi
f295c17b
BP
1234 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1235
1236 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1237
1238 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1239 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1240 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1241 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1242 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1243 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1244 done
1245done
1246
7dc88496
NS
1247# set address for lp13 with invalid characters.
1248# lp13 should be configured with only 192.168.0.13.
31ed1192 1249ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1250
1251# Allow some time for ovn-northd and ovn-controller to catch up.
1252# XXX This should be more systematic.
1253sleep 1
1254
7dc88496
NS
1255sip=`ip_to_hex 192 168 0 11`
1256tip=`ip_to_hex 192 168 0 13`
1257test_arp 11 f00000000011 $sip $tip f00000000013
1258
1259tip=`ip_to_hex 192 169 0 13`
1260#arp request for 192.169.0.13 should be flooded
1261test_arp 11 f00000000011 $sip $tip
1262
91125642 1263# dump information and flows with counters
bb0c41d3
RM
1264ovn-sbctl dump-flows -- list multicast_group
1265
1266echo "------ hv1 dump ------"
1267as hv1 ovs-vsctl show
1268as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1269
1270echo "------ hv2 dump ------"
1271as hv2 ovs-vsctl show
1272as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1273
1274echo "------ hv3 dump ------"
1275as hv3 ovs-vsctl show
1276as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1277
f295c17b
BP
1278# Now check the packets actually received against the ones expected.
1279for i in 1 2 3; do
1280 for j in 1 2 3; do
49d7c759 1281 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1282 done
1283done
fcde56f5 1284
7a8f15e0 1285OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1286
f295c17b 1287AT_CLEANUP
eb6b08eb 1288
4acd1e87
BP
1289AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1290AT_SKIP_IF([test $HAVE_PYTHON = no])
1291ovn_start
1292
1293# Create a logical switch and some logical ports.
1294# Turn on port security on all lports except ls1.
1295# Make ls1 a destination for unknown MACs.
1296# Add some ACLs for Ethertypes 1234, 1235, 1236.
1297ovn-nbctl ls-add lsw0
1298ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1299for i in 1 2 3; do
1300 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1301done
1302ovn-nbctl --wait=sb sync
1303for i in 1 2 3; do
4acd1e87
BP
1304 ovn-sbctl lsp-bind lp$i hv0
1305 if test $i = 1; then
abb37b6b 1306 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1307 else
abb37b6b
FF
1308 if test $i = 3; then
1309 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1310 else
1311 ip_addrs="192.168.0.$i"
1312 fi
1313 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1314 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
4acd1e87
BP
1315 fi
1316done
1317ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1318ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1319ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1320ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1321ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1322
1323ovn-nbctl --wait=sb sync
1324on_exit 'kill `cat ovn-trace.pid`'
1325ovn-trace --detach --pidfile --no-chdir
1326
1327# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1328#
1329# This shell function causes a packet to be received on INPORT. The packet's
1330# content has Ethernet destination DST and source SRC (each exactly 12 hex
1331# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1332# more) list the VIFs on which the packet should be received. INPORT and the
1333# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1334test_packet() {
1335 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1336 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1337 while :; do
abb37b6b
FF
1338 case $1 in # (
1339 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1340 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1341 *) break ;;
1342 esac
4acd1e87
BP
1343 done
1344 for outport; do
abb37b6b 1345 echo "output(\"lp$outport\");"
4acd1e87
BP
1346 done > expout
1347
1348 AT_CAPTURE_FILE([trace])
1349 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1350}
1351
1352# test_arp INPORT SHA SPA TPA [REPLY_HA]
1353#
1354# Causes a packet to be received on INPORT. The packet is an ARP
1355# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1356# it should be the hardware address of the target to expect to receive in an
1357# ARP reply; otherwise no reply is expected.
1358#
1359# INPORT is an logical switch port number, e.g. 11 for vif11.
1360# SHA and REPLY_HA are each 12 hex digits.
1361# SPA and TPA are each 8 hex digits.
1362test_arp() {
1363 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1364
1365 local request="inport == \"lp$inport\"
1366 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1367 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1368 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1369
1370 if test -z "$reply_ha"; then
1371 reply=
abb37b6b
FF
1372 local i
1373 for i in 1 2 3; do
1374 if test $i != $inport; then
1375 reply="${reply}output(\"lp$i\");
4acd1e87 1376"
abb37b6b
FF
1377 fi
1378 done
4acd1e87
BP
1379 else
1380 reply="\
1381eth.dst = $sha;
1382eth.src = $reply_ha;
1383arp.op = 2;
1384arp.tha = $sha;
1385arp.sha = $reply_ha;
1386arp.tpa = $spa;
1387arp.spa = $tpa;
1388output(\"lp$inport\");
1389"
1390 fi
1391
1392 AT_CAPTURE_FILE([trace])
1393 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1394}
1395
1396# Send packets between all pairs of source and destination ports:
1397#
1398# 1. Unicast packets are delivered to exactly one logical switch port
1399# (except that packets destined to their input ports are dropped).
1400#
1401# 2. Broadcast and multicast are delivered to all logical switch ports
1402# except the input port.
1403#
1404# 3. When port security is turned on, the switch drops packets from the wrong
1405# MAC address.
1406#
1407# 4. The switch drops all packets with a VLAN tag.
1408#
1409# 5. The switch drops all packets with a multicast source address. (This only
1410# affects behavior when port security is turned off, since otherwise port
1411# security would drop the packet anyway.)
1412#
1413# 6. The switch delivers packets with an unknown destination to logical
1414# switch ports with "unknown" among their MAC addresses (and port
1415# security disabled).
1416#
1417# 7. The switch drops unicast packets that violate an ACL.
1418#
1419# 8. The switch drops multicast and broadcast packets that violate an ACL.
1420#
9fcb6a18
BP
1421# 9. OVN generates responses to ARP requests for known IPs, except for
1422# requests from a port for the port's own IP.
4acd1e87
BP
1423#
1424# 10. No response to ARP requests for unknown IPs.
1425
1426for s in 1 2 3; do
1427 bcast=
1428 unknown=
1429 bacl2=
1430 bacl3=
1431 for d in 1 2 3; do
abb37b6b
FF
1432 echo
1433 echo "lp$s -> lp$d"
1434 if test $d != $s; then unicast=$d; else unicast=; fi
1435 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1436
1437 if test $d != $s && test $s = 1; then
1438 impersonate=$d
1439 else
1440 impersonate=
1441 fi
1442 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1443
1444 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1445 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1446 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1447 # Source of 1 or 2 and dest of 3 should be dropped
1448 # due to the 4th ACL that uses address_set(set1).
1449 acl4=
1450 else
1451 acl4=$d
1452 fi
1453
1454 #7, acl1 to acl4:
1455 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1456 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1457 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1458 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1459
1460 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1461 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1462
1463 if test $d != $s && test $d = 1; then
1464 unknown="$unknown $d"
1465 fi
1466 bcast="$bcast $unicast"
1467 bacl2="$bacl2 $acl2"
1468 bacl3="$bacl3 $acl3"
1469
1470 sip=192.168.0.$s
1471 tip=192.168.0.$d
1472 tip_unknown=11.11.11.11
9fcb6a18
BP
1473 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1474 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1475 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1476
1477 if test $d = 3; then
1478 # lp3 has an additional ip 192.169.0.[123]3.
1479 tip=192.169.0.$d
9fcb6a18 1480 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1481 fi
4acd1e87
BP
1482 done
1483
1484 # Broadcast and multicast.
1485 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1486 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1487 if test $s = 1; then
abb37b6b 1488 bcast_impersonate=$bcast
4acd1e87 1489 else
abb37b6b 1490 bcast_impersonate=
4acd1e87
BP
1491 fi
1492 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1493
1494 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1495
1496 #8, acl1 to acl3:
1497 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1498 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1499 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1500
1501 #8, acl1 to acl3:
1502 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1503 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1504 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1505done
1506
1507AT_CLEANUP
1508
7277bc83
RB
1509# 2 hypervisors, 4 logical ports per HV
1510# 2 locally attached networks (one flat, one vlan tagged over same device)
1511# 2 ports per HV on each network
e90aeb57 1512AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1513AT_SKIP_IF([test $HAVE_PYTHON = no])
1514ovn_start
1515
ea46a4e9
JP
1516# In this test cases we create 3 switches, all connected to same
1517# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1518# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1519# of VIF port name indicates the hypervisor it is bound to, e.g.
1520# lp23 means VIF 3 on hv2.
1521#
ea46a4e9 1522# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1523# - ls1:
1524# - untagged
ea46a4e9 1525# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1526#
1527# - ls2:
1528# - tagged with VLAN 101
ea46a4e9 1529# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1530# - ls3:
1531# - untagged
ea46a4e9 1532# - ports: lp15, lp25
0ee7f7f1 1533#
ea46a4e9 1534# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1535# physical network.
1536
1537for i in 1 2 3; do
ea46a4e9
JP
1538 ls_name=ls$i
1539 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1540 ln_port_name=ln$i
1541 if test $i -eq 2; then
ea46a4e9 1542 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1543 else
ea46a4e9 1544 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1545 fi
31ed1192
JP
1546 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1547 ovn-nbctl lsp-set-type $ln_port_name localnet
1548 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1549done
d79fc5f4 1550
69b72264
BP
1551# lsp_to_ls LSP
1552#
1553# Prints the name of the logical switch that contains LSP.
1554lsp_to_ls () {
1555 case $1 in dnl (
1556 lp?[[12]]) echo ls1 ;; dnl (
1557 lp?[[34]]) echo ls2 ;; dnl (
1558 lp?5) echo ls3 ;; dnl (
1559 *) AT_FAIL_IF([:]) ;;
1560 esac
1561}
1562
d79fc5f4
RB
1563net_add n1
1564for i in 1 2; do
1565 sim_add hv$i
1566 as hv$i
1567 ovs-vsctl add-br br-phys
1568 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1569 ovn_attach n1 br-phys 192.168.0.$i
1570
0ee7f7f1 1571 for j in 1 2 3 4 5; do
d79fc5f4
RB
1572 ovs-vsctl add-port br-int vif$i$j -- \
1573 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1574 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1575 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1576 ofport-request=$i$j
1577
31ed1192 1578 lsp_name=lp$i$j
69b72264 1579 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 1580
ea46a4e9 1581 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1582 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1583 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1584
31ed1192 1585 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1586 done
1587done
69b72264
BP
1588ovn-nbctl --wait=sb sync
1589ovn-sbctl dump-flows
d79fc5f4
RB
1590
1591ovn_populate_arp
1592
1593# XXX This is now the 3rd copy of these functions in this file ...
1594
1595# Given the name of a logical port, prints the name of the hypervisor
1596# on which it is located.
1597vif_to_hv() {
1598 echo hv${1%?}
1599}
1600#
69b72264 1601# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
1602#
1603# This shell function causes a packet to be received on INPORT. The packet's
1604# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
1605# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1606# logical switch port numbers, e.g. 11 for vif11.
1607#
1608# EOUT is the end-to-end output port, that is, where the packet will end up
1609# after possibly bouncing through one or more localnet ports. LOUT is the
1610# logical output port, which might be a localnet port, as seen by ovn-trace
1611# (which doesn't know what localnet ports are connected to and therefore can't
1612# figure out the end-to-end answer).
d79fc5f4 1613for i in 1 2; do
0ee7f7f1 1614 for j in 1 2 3 4 5; do
d79fc5f4
RB
1615 : > $i$j.expected
1616 done
1617done
1618test_packet() {
69b72264
BP
1619 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1620 echo "$@"
1621
1622 # First try tracing the packet.
1623 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1624 if test $lout != drop; then
1625 echo "output(\"$lout\");"
1626 fi > expout
1627 AT_CAPTURE_FILE([trace])
1628 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1629
1630 # Then actually send a packet, for an end-to-end test.
1631 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
1632 hv=`vif_to_hv $inport`
1633 vif=vif$inport
1634 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
1635 if test $eout != drop; then
1636 echo $packet >> ${eout#lp}.expected
1637 fi
d79fc5f4
RB
1638}
1639
7277bc83
RB
1640# lp11 and lp21 are on the same network (phys, untagged)
1641# and on different hypervisors
69b72264
BP
1642test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1643test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 1644
7277bc83
RB
1645# lp11 and lp12 are on the same network (phys, untagged)
1646# and on the same hypervisor
69b72264
BP
1647test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1648test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
1649
1650# lp13 and lp23 are on the same network (phys, VLAN 101)
1651# and on different hypervisors
69b72264
BP
1652test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1653test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
1654
1655# lp13 and lp14 are on the same network (phys, VLAN 101)
1656# and on the same hypervisor
69b72264
BP
1657test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1658test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 1659
0ee7f7f1 1660# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 1661# same hypervisor, and on different switches
69b72264
BP
1662test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1663test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
1664
1665# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 1666# different hypervisors, and on different switches
69b72264
BP
1667test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1668test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 1669
d79fc5f4 1670# Ports that should not be able to communicate
69b72264
BP
1671test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1672test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1673test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1674test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1675test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1676test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1677test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1678test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 1679
d79fc5f4
RB
1680# Dump a bunch of info helpful for debugging if there's a failure.
1681
1682echo "------ OVN dump ------"
1683ovn-nbctl show
1684ovn-sbctl show
1685
1686echo "------ hv1 dump ------"
1687as hv1 ovs-vsctl show
1688as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1689
1690echo "------ hv2 dump ------"
1691as hv2 ovs-vsctl show
1692as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1693
1694# Now check the packets actually received against the ones expected.
1695for i in 1 2; do
0ee7f7f1 1696 for j in 1 2 3 4 5; do
49d7c759 1697 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
1698 done
1699done
1700
7a8f15e0 1701OVN_CLEANUP([hv1],[hv2])
d9c8c57c 1702
d79fc5f4
RB
1703AT_CLEANUP
1704
91125642
FF
1705AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1706AT_KEYWORDS([vtep])
eb6b08eb
JP
1707AT_SKIP_IF([test $HAVE_PYTHON = no])
1708ovn_start
1709
1710# Configure the Northbound database
ea46a4e9 1711ovn-nbctl ls-add lsw0
eb6b08eb 1712
31ed1192
JP
1713ovn-nbctl lsp-add lsw0 lp1
1714ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 1715
31ed1192
JP
1716ovn-nbctl lsp-add lsw0 lp2
1717ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 1718
31ed1192
JP
1719ovn-nbctl lsp-add lsw0 lp-vtep
1720ovn-nbctl lsp-set-type lp-vtep vtep
1721ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1722ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 1723
77adbb62
DB
1724# lpr, lr and lrp1 are used for the ARP request handling test only.
1725ovn-nbctl lsp-add lsw0 lpr
1726ovn-nbctl lr-add lr
1727ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1728ovn-nbctl set Logical_Switch_Port lpr type=router \
1729 options:router-port=lrp1 \
1730 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1731
1732
eb6b08eb
JP
1733net_add n1 # Network to connect hv1, hv2, and vtep
1734net_add n2 # Network to connect vtep and hv3
1735
1736# Create hypervisor hv1 connected to n1
1737sim_add hv1
1738as hv1
1739ovs-vsctl add-br br-phys
1740ovn_attach n1 br-phys 192.168.0.1
1741ovs-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
1742
1743# Create hypervisor hv2 connected to n1
1744sim_add hv2
1745as hv2
1746ovs-vsctl add-br br-phys
1747ovn_attach n1 br-phys 192.168.0.2
1748ovs-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
1749
1750
1751# Start the vtep emulator with a leg in both networks
1752sim_add vtep
1753as vtep
1754
1755ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1756ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1757
1758ovs-vsctl add-br br-phys
1759net_attach n1 br-phys
1760
1761mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1762arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1763ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1764ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1765
1766ovs-vsctl add-br br-vtep
1767net_attach n2 br-vtep
1768
1769vtep-ctl add-ps br-vtep
1770vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1771vtep-ctl add-ls lsw0
1772
1773start_daemon ovs-vtep br-vtep
1774start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1775
8cdc4312 1776OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 1777
475f0a2c
DB
1778OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1779 grep -- source`"])
1780# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
1781sleep 1
1782
1783# Add hv3 on the other side of the vtep
1784sim_add hv3
1785as hv3
1786ovs-vsctl add-br br-phys
1787net_attach n2 br-phys
1788
1789ovs-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
1790
1791# Pre-populate the hypervisors' ARP tables so that we don't lose any
1792# packets for ARP resolution (native tunneling doesn't queue packets
1793# for ARP resolution).
1794ovn_populate_arp
1795
1796# Allow some time for ovn-northd and ovn-controller to catch up.
1797# XXX This should be more systematic.
1798sleep 1
6977df72 1799
eb6b08eb
JP
1800# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1801#
1802# This shell function causes a packet to be received on INPORT. The packet's
1803# content has Ethernet destination DST and source SRC (each exactly 12 hex
1804# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1805# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1806# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
1807for i in 1 2 3; do
1808 : > $i.expected
1809done
1810test_packet() {
1811 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1812 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1813 hv=hv$inport
1814 vif=vif$inport
1815 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1816 for outport; do
e4543cfe 1817 echo $packet >> $outport.expected
eb6b08eb
JP
1818 done
1819}
1820
1821# Send packets between all pairs of source and destination ports:
1822#
31ed1192
JP
1823# 1. Unicast packets are delivered to exactly one logical switch port
1824# (except that packets destined to their input ports are dropped).
eb6b08eb 1825#
31ed1192
JP
1826# 2. Broadcast and multicast are delivered to all logical switch ports
1827# except the input port.
eb6b08eb 1828#
ea46a4e9 1829# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1830# switch ports with "unknown" among their MAC addresses (and port
1831# security disabled).
eb6b08eb
JP
1832for s in 1 2 3; do
1833 bcast=
1834 unknown=
1835 for d in 1 2 3; do
1836 if test $d != $s; then unicast=$d; else unicast=; fi
1837 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1838
1839 # The vtep (vif3) is the only one configured for "unknown"
1840 if test $d != $s && test $d = 3; then
1841 unknown="$unknown $d"
1842 fi
1843 bcast="$bcast $unicast"
1844 done
1845
1846 # Broadcast and multicast.
46ed1382
DB
1847 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1848 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
1849
1850 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1851done
1852
77adbb62
DB
1853# ARP request should not be responded to by logical switch router
1854# type arp responder on HV1 and HV2 and should reach directly to
1855# vif1 and vif2
1856ip_to_hex() {
1857 printf "%02x%02x%02x%02x" "$@"
1858}
1859sha=f00000000003
1860spa=`ip_to_hex 192 168 1 2`
1861tpa=`ip_to_hex 192 168 1 1`
1862request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1863as hv3 ovs-appctl netdev-dummy/receive vif3 $request
1864echo $request >> 1.expected
1865echo $request >> 2.expected
1866
bb0c41d3
RM
1867# dump information with counters
1868echo "------ OVN dump ------"
1869ovn-nbctl show
1870ovn-sbctl show
1871
77adbb62
DB
1872echo "---------SB dump-----"
1873ovn-sbctl list datapath_binding
1874echo "---------------------"
1875ovn-sbctl list port_binding
1876echo "---------------------"
1877ovn-sbctl dump-flows
1878
bb0c41d3
RM
1879echo "------ hv1 dump ------"
1880as hv1 ovs-vsctl show
6195e2e7 1881as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
1882as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1883
1884echo "------ hv2 dump ------"
1885as hv2 ovs-vsctl show
6195e2e7 1886as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
1887as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1888
1889echo "------ hv3 dump ------"
1890as hv3 ovs-vsctl show
6754e92d
FF
1891# note: hv3 has no logical port bind, thus it should not have br-int
1892AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
1893[ovs-ofctl: br-int is not a bridge or a socket
1894])
bb0c41d3 1895
eb6b08eb
JP
1896# Now check the packets actually received against the ones expected.
1897for i in 1 2 3; do
49d7c759 1898 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 1899done
fcde56f5
LR
1900
1901# Gracefully terminate daemons
7a8f15e0
LR
1902OVN_CLEANUP([hv1],[hv2],[vtep])
1903OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 1904
eb6b08eb 1905AT_CLEANUP
9975d7be 1906
184bc3ca
RB
1907# Similar test to "hardware GW"
1908AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
1909AT_SKIP_IF([test $HAVE_PYTHON = no])
1910ovn_start
1911
1912# Configure the Northbound database
1913ovn-nbctl ls-add lsw0
1914
1915ovn-nbctl lsp-add lsw0 lp1
1916ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1917
1918ovn-nbctl lsp-add lsw0 lp2
1919ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1920
1921ovn-nbctl lsp-add lsw0 lp-gw
1922ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 1923ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
1924ovn-nbctl lsp-set-addresses lp-gw unknown
1925
1926net_add n1 # Network to connect hv1, hv2, and gw
1927net_add n2 # Network to connect gw and hv3
1928
1929# Create hypervisor hv1 connected to n1
1930sim_add hv1
1931as hv1
1932ovs-vsctl add-br br-phys
1933ovn_attach n1 br-phys 192.168.0.1
1934ovs-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
1935
1936# Create hypervisor hv2 connected to n1
1937sim_add hv2
1938as hv2
1939ovs-vsctl add-br br-phys
1940ovn_attach n1 br-phys 192.168.0.2
1941ovs-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
1942
1943# Create hypervisor hv_gw connected to n1 and n2
1944# connect br-phys bridge to n1; connect hv-gw bridge to n2
1945sim_add hv_gw
1946as hv_gw
1947ovs-vsctl add-br br-phys
1948ovn_attach n1 br-phys 192.168.0.3
1949ovs-vsctl add-br br-phys2
1950net_attach n2 br-phys2
1951ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
1952
184bc3ca
RB
1953# Add hv3 on the other side of the GW
1954sim_add hv3
1955as hv3
1956ovs-vsctl add-br br-phys
1957net_attach n2 br-phys
1958ovs-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
1959
1960
1961# Pre-populate the hypervisors' ARP tables so that we don't lose any
1962# packets for ARP resolution (native tunneling doesn't queue packets
1963# for ARP resolution).
1964ovn_populate_arp
1965
1966# Allow some time for ovn-northd and ovn-controller to catch up.
1967# XXX This should be more systematic.
1968sleep 1
1969
1970# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1971#
1972# This shell function causes a packet to be received on INPORT. The packet's
1973# content has Ethernet destination DST and source SRC (each exactly 12 hex
1974# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1975# more) list the VIFs on which the packet should be received. INPORT and the
1976# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
1977for i in 1 2 3; do
1978 : > $i.expected
1979done
1980test_packet() {
1981 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1982 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1983 hv=hv$inport
1984 vif=vif$inport
1985 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1986 for outport; do
e4543cfe 1987 echo $packet >> $outport.expected
184bc3ca
RB
1988 done
1989}
1990
1991# Send packets between all pairs of source and destination ports:
1992#
1993# 1. Unicast packets are delivered to exactly one lport (except that packets
1994# destined to their input ports are dropped).
1995#
1996# 2. Broadcast and multicast are delivered to all lports except the input port.
1997#
1998# 3. The lswitch delivers packets with an unknown destination to lports with
1999# "unknown" among their MAC addresses (and port security disabled).
2000for s in 1 2 3 ; do
2001 bcast=
2002 unknown=
2003 for d in 1 2 3 ; do
2004 if test $d != $s; then unicast=$d; else unicast=; fi
2005 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2006
2007 # The vtep (vif3) is the only one configured for "unknown"
2008 if test $d != $s && test $d = 3; then
2009 unknown="$unknown $d"
2010 fi
2011 bcast="$bcast $unicast"
2012 done
2013
2014 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2015 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2016 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2017done
2018
184bc3ca
RB
2019echo "------ ovn-nbctl show ------"
2020ovn-nbctl show
2021echo "------ ovn-sbctl show ------"
2022ovn-sbctl show
2023
2024echo "------ hv1 ------"
2025as hv1 ovs-vsctl show
2026echo "------ hv1 br-int ------"
2027as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2028echo "------ hv1 br-phys ------"
2029as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2030
2031echo "------ hv2 ------"
2032as hv2 ovs-vsctl show
2033echo "------ hv2 br-int ------"
2034as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2035echo "------ hv2 br-phys ------"
2036as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2037
2038echo "------ hv_gw ------"
2039as hv_gw ovs-vsctl show
2040echo "------ hv_gw br-phys ------"
2041as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2042echo "------ hv_gw br-phys2 ------"
2043as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2044
2045echo "------ hv3 ------"
2046as hv3 ovs-vsctl show
2047echo "------ hv3 br-phys ------"
2048as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2049
2050# Now check the packets actually received against the ones expected.
2051for i in 1 2 3; do
49d7c759 2052 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2053done
2054AT_CLEANUP
2055
9975d7be
BP
2056# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2057AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2058AT_SKIP_IF([test $HAVE_PYTHON = no])
2059ovn_start
2060
2061# Logical network:
2062#
2063# Three logical switches ls1, ls2, ls3.
86e98048
BP
2064# One logical router lr0 connected to ls[123],
2065# with nine subnets, three per logical switch:
2066#
2067# lrp11 on ls1 for subnet 192.168.11.0/24
2068# lrp12 on ls1 for subnet 192.168.12.0/24
2069# lrp13 on ls1 for subnet 192.168.13.0/24
2070# ...
2071# lrp33 on ls3 for subnet 192.168.33.0/24
2072#
2073# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2074# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2075for i in 1 2 3; do
ea46a4e9 2076 ovn-nbctl ls-add ls$i
9975d7be 2077 for j in 1 2 3; do
86e98048 2078 for k in 1 2 3; do
31ed1192
JP
2079 # Add "unknown" to MAC addresses for lp?11, so packets for
2080 # MAC-IP bindings discovered via ARP later have somewhere to go.
2081 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2082
2083 ovn-nbctl \
2084 -- lsp-add ls$i lp$i$j$k \
2085 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2086 192.168.$i$j.$k" $unknown
86e98048
BP
2087 done
2088 done
2089done
2090
fa2a27b2 2091ovn-nbctl lr-add lr0
86e98048
BP
2092for i in 1 2 3; do
2093 for j in 1 2 3; do
bf44c2cd 2094 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2095 ovn-nbctl \
31ed1192 2096 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2097 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2098 options:router-port=lrp$i$j \
86e98048 2099 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2100 done
2101done
2102
80f408f4 2103ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2104 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2105
9975d7be
BP
2106# Physical network:
2107#
2108# Three hypervisors hv[123].
86e98048
BP
2109# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2110# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2111# lp?3[123] all on hv3.
2112
9975d7be
BP
2113
2114# Given the name of a logical port, prints the name of the hypervisor
2115# on which it is located.
2116vif_to_hv() {
2117 case $1 in dnl (
86e98048
BP
2118 ?11) echo 1 ;; dnl (
2119 ?12 | ?21 | ?22) echo 2 ;; dnl (
2120 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2121 esac
2122}
2123
86e98048
BP
2124# Given the name of a logical port, prints the name of its logical router
2125# port, e.g. "vif_to_lrp 123" yields 12.
2126vif_to_lrp() {
2127 echo ${1%?}
2128}
2129
2130# Given the name of a logical port, prints the name of its logical
2131# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2132vif_to_ls() {
86e98048 2133 echo ${1%??}
e3393e3f
BP
2134}
2135
9975d7be
BP
2136net_add n1
2137for i in 1 2 3; do
2138 sim_add hv$i
2139 as hv$i
2140 ovs-vsctl add-br br-phys
2141 ovn_attach n1 br-phys 192.168.0.$i
2142done
2143for i in 1 2 3; do
2144 for j in 1 2 3; do
86e98048 2145 for k in 1 2 3; do
269ecccc
JP
2146 hv=`vif_to_hv $i$j$k`
2147 as hv$hv ovs-vsctl \
2148 -- add-port br-int vif$i$j$k \
2149 -- set Interface vif$i$j$k \
2150 external-ids:iface-id=lp$i$j$k \
2151 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2152 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2153 ofport-request=$i$j$k
86e98048 2154 done
9975d7be
BP
2155 done
2156done
2157
2158# Pre-populate the hypervisors' ARP tables so that we don't lose any
2159# packets for ARP resolution (native tunneling doesn't queue packets
2160# for ARP resolution).
2161ovn_populate_arp
2162
2163# Allow some time for ovn-northd and ovn-controller to catch up.
2164# XXX This should be more systematic.
2165sleep 1
2166
e3393e3f 2167# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2168#
2169# This shell function causes a packet to be received on INPORT. The packet's
2170# content has Ethernet destination DST and source SRC (each exactly 12 hex
2171# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2172# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2173# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2174for i in 1 2 3; do
2175 for j in 1 2 3; do
86e98048
BP
2176 for k in 1 2 3; do
2177 : > $i$j$k.expected
269ecccc 2178 done
9975d7be
BP
2179 done
2180done
e3393e3f 2181test_ip() {
9975d7be
BP
2182 # This packet has bad checksums but logical L3 routing doesn't check.
2183 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2184 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2185 shift; shift; shift; shift; shift
2186 hv=hv`vif_to_hv $inport`
2187 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2188 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2189 in_ls=`vif_to_ls $inport`
2190 in_lrp=`vif_to_lrp $inport`
9975d7be 2191 for outport; do
269ecccc 2192 out_ls=`vif_to_ls $outport`
86e98048 2193 if test $in_ls = $out_ls; then
9975d7be
BP
2194 # Ports on the same logical switch receive exactly the same packet.
2195 echo $packet
2196 else
2197 # Routing decrements TTL and updates source and dest MAC
2198 # (and checksum).
269ecccc 2199 out_lrp=`vif_to_lrp $outport`
86e98048 2200 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2201 fi >> $outport.expected
9975d7be
BP
2202 done
2203}
2204
e3393e3f 2205as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2206as hv1 ovn-sbctl list port_binding
2207as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2208as hv1 ovn-sbctl dump-flows
2209as hv1 ovs-ofctl dump-flows br-int
2210
e3393e3f 2211# Send IP packets between all pairs of source and destination ports:
9975d7be 2212#
31ed1192
JP
2213# 1. Unicast IP packets are delivered to exactly one logical switch port
2214# (except that packets destined to their input ports are dropped).
9975d7be 2215#
31ed1192
JP
2216# 2. Broadcast IP packets are delivered to all logical switch ports
2217# except the input port.
86e98048
BP
2218ip_to_hex() {
2219 printf "%02x%02x%02x%02x" "$@"
2220}
9975d7be 2221for is in 1 2 3; do
269ecccc
JP
2222 for js in 1 2 3; do
2223 for ks in 1 2 3; do
2224 bcast=
2225 s=$is$js$ks
2226 smac=f00000000$s
2227 sip=`ip_to_hex 192 168 $is$js $ks`
2228 for id in 1 2 3; do
2229 for jd in 1 2 3; do
2230 for kd in 1 2 3; do
2231 d=$id$jd$kd
2232 dip=`ip_to_hex 192 168 $id$jd $kd`
2233 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2234 if test $d != $s; then unicast=$d; else unicast=; fi
2235
2236 test_ip $s $smac $dmac $sip $dip $unicast #1
2237
2238 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2239 done
2240 done
9975d7be 2241 done
269ecccc
JP
2242 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2243 done
2244 done
e3393e3f
BP
2245done
2246
0bac7164
BP
2247# 3. Send an IP packet from every logical port to every other subnet,
2248# to an IP address that does not have a static IP-MAC binding.
2249# This should generate a broadcast ARP request for the destination
2250# IP address in the destination subnet.
2251for is in 1 2 3; do
269ecccc
JP
2252 for js in 1 2 3; do
2253 for ks in 1 2 3; do
2254 s=$is$js$ks
2255 smac=f00000000$s
2256 sip=`ip_to_hex 192 168 $is$js $ks`
2257 for id in 1 2 3; do
2258 for jd in 1 2 3; do
2259 if test $is$js = $id$jd; then
2260 continue
2261 fi
2262
2263 # Send the packet.
2264 dmac=00000000ff$is$js
2265 # Calculate a 4th octet for the destination that is
2266 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2267 # that have static MAC bindings, and fits in the range
2268 # 0-255.
2269 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2270 dip=`ip_to_hex 192 168 $id$jd $o4`
2271 test_ip $s $smac $dmac $sip $dip
2272
2273 # Every LP on the destination subnet's lswitch should
2274 # receive the ARP request.
2275 lrmac=00000000ff$id$jd
2276 lrip=`ip_to_hex 192 168 $id$jd 254`
2277 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2278 for jd2 in 1 2 3; do
2279 for kd in 1 2 3; do
e4543cfe 2280 echo $arp >> $id$jd2$kd.expected
0bac7164 2281 done
269ecccc 2282 done
0bac7164 2283 done
269ecccc 2284 done
0bac7164 2285 done
269ecccc 2286 done
0bac7164
BP
2287done
2288
e3393e3f
BP
2289# test_arp INPORT SHA SPA TPA [REPLY_HA]
2290#
2291# Causes a packet to be received on INPORT. The packet is an ARP
2292# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2293# it should be the hardware address of the target to expect to receive in an
2294# ARP reply; otherwise no reply is expected.
2295#
31ed1192 2296# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2297# SHA and REPLY_HA are each 12 hex digits.
2298# SPA and TPA are each 8 hex digits.
2299test_arp() {
2300 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2301 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2302 hv=hv`vif_to_hv $inport`
2303 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2304 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2305
57d143eb 2306 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2307 # IP address is not configured to the switch patch port.
e3393e3f 2308 local i=`vif_to_ls $inport`
86e98048 2309 local j k
e3393e3f 2310 for j in 1 2 3; do
86e98048 2311 for k in 1 2 3; do
ea46a4e9 2312 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2313 # so no ARP flooding expected for it.
2314 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2315 echo $request >> $i$j$k.expected
2316 fi
2317 done
e3393e3f
BP
2318 done
2319
2320 # Expect to receive the reply, if any.
2321 if test X$reply_ha != X; then
86e98048
BP
2322 lrp=`vif_to_lrp $inport`
2323 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2324 echo $reply >> $inport.expected
2325 fi
2326}
2327
2328# Test router replies to ARP requests from all source ports:
2329#
0bac7164 2330# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2331#
0bac7164 2332# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2333# in its subnet.
2334#
0bac7164 2335# 6. Router replies to query for its MAC address from another subnet.
e3393e3f 2336#
0bac7164 2337# 7. No reply to query for IP address other than router IP.
e3393e3f 2338for i in 1 2 3; do
269ecccc
JP
2339 for j in 1 2 3; do
2340 for k in 1 2 3; do
2341 smac=f00000000$i$j$k # Source MAC
2342 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2343 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2344 rmac=00000000ff$i$j # Router MAC
2345 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2346 test_arp $i$j$k $smac $sip $rip $rmac #4
2347 test_arp $i$j$k $smac $otherip $rip $rmac #5
2348 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2349 test_arp $i$j$k $smac $sip $otherip #7
0bac7164 2350 done
269ecccc 2351 done
0bac7164
BP
2352done
2353
2354# Allow some time for packet forwarding.
2355# XXX This can be improved.
2356sleep 1
2357
2358# 8. Generate an ARP reply for each of the IP addresses ARPed for
2359# earlier as #3.
2360#
2361# Here, the $s is the VIF that originated the ARP request and $d is
2362# the VIF that sends the ARP reply, which is somewhat backward but
2363# it means that $s and $d are the same as #3.
2364: > mac_bindings.expected
2365for is in 1 2 3; do
269ecccc
JP
2366 for js in 1 2 3; do
2367 for ks in 1 2 3; do
2368 s=$is$js$ks
2369 for id in 1 2 3; do
2370 for jd in 1 2 3; do
2371 if test $is$js = $id$jd; then
2372 continue
2373 fi
2374
2375 kd=1
2376 d=$id$jd$kd
2377
2378 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2379 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2380 host_mac=8000000000$o4
2381
2382 lrmac=00000000ff$id$jd
2383 lrip=`ip_to_hex 192 168 $id$jd 254`
2384
2385 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2386
2387 echo
2388 echo
2389 echo
2390 hv=hv`vif_to_hv $d`
2391 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2392 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2393 #as $hv ovs-ofctl dump-flows br-int table=19
2394
2395 host_ip_pretty=192.168.$id$jd.$o4
2396 host_mac_pretty=80:00:00:00:00:$o4
2397 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2398 done
269ecccc 2399 done
9975d7be 2400 done
269ecccc 2401 done
9975d7be 2402done
0bac7164 2403
9975d7be
BP
2404# Allow some time for packet forwarding.
2405# XXX This can be improved.
2406sleep 1
2407
0bac7164
BP
2408# 9. Send an IP packet from every logical port to every other subnet. These
2409# are the same packets already sent as #3, but now the destinations' IP-MAC
2410# bindings have been discovered via ARP, so instead of provoking an ARP
2411# request, these packets now get routed to their destinations (which don't
2412# have static MAC bindings, so they go to the port we've designated as
2413# accepting "unknown" MACs.)
2414for is in 1 2 3; do
269ecccc
JP
2415 for js in 1 2 3; do
2416 for ks in 1 2 3; do
2417 s=$is$js$ks
2418 smac=f00000000$s
2419 sip=`ip_to_hex 192 168 $is$js $ks`
2420 for id in 1 2 3; do
2421 for jd in 1 2 3; do
2422 if test $is$js = $id$jd; then
2423 continue
2424 fi
2425
2426 # Send the packet.
2427 dmac=00000000ff$is$js
2428 # Calculate a 4th octet for the destination that is
2429 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2430 # that have static MAC bindings, and fits in the range
2431 # 0-255.
2432 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2433 dip=`ip_to_hex 192 168 $id$jd $o4`
2434 test_ip $s $smac $dmac $sip $dip
2435
2436 # Expect the packet egress.
2437 host_mac=8000000000$o4
2438 outport=${id}11
2439 out_lrp=$id$jd
e4543cfe 2440 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2441 done
269ecccc 2442 done
0bac7164 2443 done
269ecccc 2444 done
0bac7164
BP
2445done
2446
0bac7164
BP
2447ovn-sbctl -f csv -d bare --no-heading \
2448 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2449
9975d7be
BP
2450# Now check the packets actually received against the ones expected.
2451for i in 1 2 3; do
2452 for j in 1 2 3; do
86e98048 2453 for k in 1 2 3; do
abb37b6b
FF
2454 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2455 [$i$j$k.expected])
86e98048 2456 done
9975d7be
BP
2457 done
2458done
fcde56f5 2459
0bac7164
BP
2460# Check the MAC bindings against those expected.
2461AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2462])
2463
fcde56f5 2464# Gracefully terminate daemons
7a8f15e0 2465OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2466
9975d7be 2467AT_CLEANUP
685f4dfe
NS
2468
2469# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2470AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
2471AT_SKIP_IF([test $HAVE_PYTHON = no])
2472ovn_start
2473
2474# Create hypervisors hv[123].
2475# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2476# Add all of the vifs to a single logical switch lsw0.
2477# Turn off port security on vifs vif[123]1
2478# Turn on l2 port security on vifs vif[123]2
2479# Turn of l2 and l3 port security on vifs vif[123]3
2480# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 2481ovn-nbctl ls-add lsw0
685f4dfe
NS
2482net_add n1
2483for i in 1 2 3; do
2484 sim_add hv$i
2485 as hv$i
2486 ovs-vsctl add-br br-phys
2487 ovn_attach n1 br-phys 192.168.0.$i
2488
2489 for j in 1 2 3; do
2490 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 2491 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 2492 if test $j = 1; then
31ed1192 2493 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 2494 elif test $j = 2; then
31ed1192
JP
2495 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2496 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
2497 else
2498 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
2499 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2500 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
2501 fi
2502 done
2503done
2504
685f4dfe
NS
2505# Pre-populate the hypervisors' ARP tables so that we don't lose any
2506# packets for ARP resolution (native tunneling doesn't queue packets
2507# for ARP resolution).
2508ovn_populate_arp
2509
2510# Allow some time for ovn-northd and ovn-controller to catch up.
2511# XXX This should be more systematic.
2512sleep 1
685f4dfe
NS
2513
2514# Given the name of a logical port, prints the name of the hypervisor
2515# on which it is located.
2516vif_to_hv() {
2517 echo hv${1%?}
2518}
2519
685f4dfe
NS
2520for i in 1 2 3; do
2521 for j in 1 2 3; do
2522 : > $i$j.expected
2523 done
2524done
2525
2526# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2527#
2528# This shell function causes an ip packet to be received on INPORT.
2529# The packet's content has Ethernet destination DST and source SRC
2530# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2531# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2532# be received. INPORT and the OUTPORTs are specified as logical switch
2533# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2534test_ip() {
2535 # This packet has bad checksums but logical L3 routing doesn't check.
2536 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 2537 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
2538 shift; shift; shift; shift; shift
2539 hv=`vif_to_hv $inport`
2540 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2541 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2542 for outport; do
e4543cfe 2543 echo $packet >> $outport.expected
685f4dfe
NS
2544 done
2545}
2546
2547# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2548#
2549# Causes a packet to be received on INPORT. The packet is an ARP
2550# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2551# it should be the hardware address of the target to expect to receive in an
2552# ARP reply; otherwise no reply is expected.
2553#
31ed1192 2554# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2555# SHA and REPLY_HA are each 12 hex digits.
2556# SPA and TPA are each 8 hex digits.
2557test_arp() {
2558 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2559 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2560 hv=`vif_to_hv $inport`
2561 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2562 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2563 if test $drop != 1; then
e137131a 2564 if test X$reply_ha = X; then
685f4dfe
NS
2565 # Expect to receive the broadcast ARP on the other logical switch ports
2566 # if no reply is expected.
2567 local i j
2568 for i in 1 2 3; do
2569 for j in 1 2 3; do
2570 if test $i$j != $inport; then
2571 echo $request >> $i$j.expected
2572 fi
2573 done
2574 done
2575 else
2576 # Expect to receive the reply, if any.
2577 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2578 echo $reply >> $inport.expected
2579 fi
2580 fi
2581}
2582
2583# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2584# This function is similar to test_ip() except that it sends
2585# ipv6 packet
2586test_ipv6() {
2587 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2588 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2589 shift; shift; shift; shift; shift
2590 hv=`vif_to_hv $inport`
2591 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2592 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2593 for outport; do
e4543cfe 2594 echo $packet >> $outport.expected
685f4dfe
NS
2595 done
2596}
2597
9e687b23
DL
2598# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2599# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2600# of the test packet
2601test_icmpv6() {
2602 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2603 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2604 shift; shift; shift; shift; shift; shift
2605 hv=`vif_to_hv $inport`
2606 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2607 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2608 for outport; do
e4543cfe 2609 echo $packet >> $outport.expected
9e687b23
DL
2610 done
2611}
2612
685f4dfe
NS
2613ip_to_hex() {
2614 printf "%02x%02x%02x%02x" "$@"
2615}
2616
2617# no port security
2618sip=`ip_to_hex 192 168 0 12`
2619tip=`ip_to_hex 192 168 0 13`
2620# the arp packet should be allowed even if lp[123]1 is
2621# not configured with mac f00000000023 and ip 192.168.0.12
2622for i in 1 2 3; do
2623 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2624 for j in 1 2 3; do
2625 if test $i != $j; then
2626 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2627 fi
2628 done
2629done
2630
2631# l2 port security
2632sip=`ip_to_hex 192 168 0 12`
2633tip=`ip_to_hex 192 168 0 13`
2634
2635# arp packet should be allowed since lp22 is configured with
2636# mac f00000000022
2637test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2638
2639# arp packet should not be allowed since lp32 is not configured with
2640# mac f00000000021
2641test_arp 32 f00000000021 f00000000021 $sip $tip 1
2642
2643# arp packet with sha set to f00000000021 should not be allowed
2644# for lp12
2645test_arp 12 f00000000012 f00000000021 $sip $tip 1
2646
2647# ip packets should be allowed and received since lp[123]2 do not
2648# have l3 port security
2649sip=`ip_to_hex 192 168 0 55`
2650tip=`ip_to_hex 192 168 0 66`
2651for i in 1 2 3; do
2652 for j in 1 2 3; do
2653 if test $i != $j; then
2654 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2655 fi
2656 done
2657done
2658
2659# ipv6 packets should be received by lp[123]2
2660# lp[123]1 can send ipv6 traffic as there is no port security
2661sip=fe800000000000000000000000000000
2662tip=ff020000000000000000000000000000
2663
2664for i in 1 2 3; do
2665 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2666done
2667
2668
2669# l2 and l3 port security
2670sip=`ip_to_hex 192 168 0 13`
2671tip=`ip_to_hex 192 168 0 22`
2672# arp packet should be allowed since lp13 is configured with
2673# f00000000013 and 192.168.0.13
2674test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2675
2676# the arp packet should be dropped because lp23 is not configured
2677# with mac f00000000022
2678sip=`ip_to_hex 192 168 0 13`
2679tip=`ip_to_hex 192 168 0 22`
2680test_arp 23 f00000000022 f00000000022 $sip $tip 1
2681
2682# the arp packet should be dropped because lp33 is not configured
2683# with ip 192.168.0.55
2684spa=`ip_to_hex 192 168 0 55`
2685tpa=`ip_to_hex 192 168 0 22`
2686test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2687
2688# ip packets should not be received by lp[123]3 since
2689# l3 port security is enabled
2690sip=`ip_to_hex 192 168 0 55`
2691tip=`ip_to_hex 192 168 0 66`
2692for i in 1 2 3; do
2693 for j in 1 2 3; do
2694 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2695 done
2696done
2697
2698# ipv6 packets should be dropped for lp[123]3 since
2699# it is configured with only ipv4 address
2700sip=fe800000000000000000000000000000
2701tip=ff020000000000000000000000000000
2702
2703for i in 1 2 3; do
2704 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2705done
2706
2707# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2708# lp[123]1 can send ipv6 traffic as there is no port security
2709for i in 1 2 3; do
2710 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2711done
2712
2713# lp13 has extra port security with mac f0000000113 and ipv6 addr
2714# fe80::ea2a:eaff:fe28:0012
2715
2716# ipv4 packet should be dropped for lp13 with mac f0000000113
2717sip=`ip_to_hex 192 168 0 13`
2718tip=`ip_to_hex 192 168 0 23`
2719test_ip 13 f00000000113 f00000000023 $sip $tip
2720
6d53e8a9
BP
2721# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2722# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
2723# lp11 can send ipv6 traffic as there is no port security
2724sip=ee800000000000000000000000000000
2725for i in 1 2 3; do
6d53e8a9
BP
2726 tip=fe80000000000000ea2aeafffe2800${i}3
2727 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
2728done
2729
2730
2731# ipv6 packet should not be received by lp33 with mac f0000000333
2732# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2733# configured with fe80::ea2a:eaff:fe28:0033
2734# lp11 can send ipv6 traffic as there is no port security
2735
2736sip=ee800000000000000000000000000000
2737tip=fe80000000000000ea2aeafffe280023
2738test_ipv6 11 f00000000011 f00000000333 $sip $tip
2739
6d53e8a9
BP
2740# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2741# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
2742# and should be dropped for any other ip6.src
2743# lp21 can receive ipv6 traffic as there is no port security
2744
2745tip=ee800000000000000000000000000000
2746for i in 1 2 3; do
2747 sip=fe80000000000000ea2aeafffe2800${i}3
2748 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2749
9e687b23 2750 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 2751 sip=00000000000000000000000000000000
9e687b23
DL
2752 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2753 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2754 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2755 # Traffic to non-multicast traffic should be dropped
2756 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2757 # Traffic of other ICMPv6 types should be dropped
2758 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
2759
2760 # should be dropped
2761 sip=ae80000000000000ea2aeafffe2800aa
2762 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2763done
2764
31ed1192
JP
2765# configure lsp13 to send and received IPv4 packets with an address range
2766ovn-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 2767
8ff5a966
NS
2768sleep 2
2769
7d9d86ad
NS
2770sip=`ip_to_hex 10 0 0 13`
2771tip=`ip_to_hex 192 168 0 22`
31ed1192 2772# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
2773test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2774
2775sip=`ip_to_hex 10 0 0 14`
2776tip=`ip_to_hex 192 168 0 23`
31ed1192 2777# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
2778# with dst ip 192.168.0.23 should be allowed
2779test_ip 13 f00000000013 f00000000023 $sip $tip 23
2780
2781sip=`ip_to_hex 192 168 0 33`
2782tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
2783# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2784# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
2785test_ip 33 f00000000033 f00000000013 $sip $tip 13
2786
2787sip=`ip_to_hex 192 168 0 33`
2788tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
2789# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2790# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
2791test_ip 33 f00000000033 f00000000013 $sip $tip 13
2792
2793sip=`ip_to_hex 192 168 0 33`
2794tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
2795# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2796# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
2797test_ip 33 f00000000033 f00000000013 $sip $tip
2798
2799sip=`ip_to_hex 192 168 0 33`
2800tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
2801# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2802# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
2803test_ip 33 f00000000033 f00000000013 $sip $tip 13
2804
2805sip=`ip_to_hex 192 168 0 33`
2806tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
2807# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2808# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
2809test_ip 33 f00000000033 f00000000013 $sip $tip
2810
2811sip=`ip_to_hex 192 168 0 33`
2812tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
2813# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2814# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 2815test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 2816
bb0c41d3
RM
2817#dump information including flow counters
2818ovn-nbctl show
2819ovn-sbctl dump-flows -- list multicast_group
2820
2821echo "------ hv1 dump ------"
2822as hv1 ovs-vsctl show
6195e2e7 2823as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2824as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2825
2826echo "------ hv2 dump ------"
2827as hv2 ovs-vsctl show
6195e2e7 2828as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2829as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2830
2831echo "------ hv3 dump ------"
2832as hv3 ovs-vsctl show
6195e2e7 2833as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2834as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2835
685f4dfe
NS
2836# Now check the packets actually received against the ones expected.
2837for i in 1 2 3; do
2838 for j in 1 2 3; do
49d7c759 2839 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
2840 done
2841done
2842
7a8f15e0 2843OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 2844
685f4dfe 2845AT_CLEANUP
509afdc3
GS
2846
2847AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
2848AT_SKIP_IF([test $HAVE_PYTHON = no])
2849ovn_start
2850
2851# Logical network:
2852# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2853# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2854# R2 has ls2 (172.16.1.0/24) connected to it.
2855
fa2a27b2
JP
2856ovn-nbctl lr-add R1
2857ovn-nbctl lr-add R2
509afdc3 2858
ea46a4e9
JP
2859ovn-nbctl ls-add ls1
2860ovn-nbctl ls-add ls2
509afdc3
GS
2861
2862# Connect ls1 to R1
bf44c2cd 2863ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
509afdc3 2864
31ed1192 2865ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 2866 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
509afdc3
GS
2867
2868# Connect ls2 to R2
bf44c2cd 2869ovn-nbctl lrp-add R2 ls2 00:00:00:01:02:04 172.16.1.1/24
509afdc3 2870
31ed1192 2871ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 2872 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
509afdc3
GS
2873
2874# Connect R1 to R2
4685e523
JP
2875ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
2876ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 2877
6d9ecfa9
JP
2878ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
2879ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
2880
2881# Create logical port ls1-lp1 in ls1
31ed1192
JP
2882ovn-nbctl lsp-add ls1 ls1-lp1 \
2883-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
509afdc3
GS
2884
2885# Create logical port ls2-lp1 in ls2
31ed1192
JP
2886ovn-nbctl lsp-add ls2 ls2-lp1 \
2887-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
509afdc3
GS
2888
2889# Create two hypervisor and create OVS ports corresponding to logical ports.
2890net_add n1
2891
2892sim_add hv1
2893as hv1
2894ovs-vsctl add-br br-phys
2895ovn_attach n1 br-phys 192.168.0.1
2896ovs-vsctl -- add-port br-int hv1-vif1 -- \
2897 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
2898 options:tx_pcap=hv1/vif1-tx.pcap \
2899 options:rxq_pcap=hv1/vif1-rx.pcap \
2900 ofport-request=1
2901
2902sim_add hv2
2903as hv2
2904ovs-vsctl add-br br-phys
2905ovn_attach n1 br-phys 192.168.0.2
2906ovs-vsctl -- add-port br-int hv2-vif1 -- \
2907 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
2908 options:tx_pcap=hv2/vif1-tx.pcap \
2909 options:rxq_pcap=hv2/vif1-rx.pcap \
2910 ofport-request=1
2911
2912
2913# Pre-populate the hypervisors' ARP tables so that we don't lose any
2914# packets for ARP resolution (native tunneling doesn't queue packets
2915# for ARP resolution).
2916ovn_populate_arp
2917
2918# Allow some time for ovn-northd and ovn-controller to catch up.
2919# XXX This should be more systematic.
2920sleep 1
2921
2922# Send ip packets between the two ports.
2923ip_to_hex() {
2924 printf "%02x%02x%02x%02x" "$@"
2925}
509afdc3
GS
2926
2927# Packet to send.
2928src_mac="f00000010203"
2929dst_mac="000000010203"
2930src_ip=`ip_to_hex 192 168 1 2`
2931dst_ip=`ip_to_hex 172 16 1 2`
2932packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2933as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2934
2935
2936echo "---------NB dump-----"
2937ovn-nbctl show
2938echo "---------------------"
2939ovn-nbctl list logical_router
2940echo "---------------------"
2941ovn-nbctl list logical_router_port
2942echo "---------------------"
2943
2944echo "---------SB dump-----"
2945ovn-sbctl list datapath_binding
2946echo "---------------------"
2947ovn-sbctl list port_binding
2948echo "---------------------"
2949
2950echo "------ hv1 dump ----------"
8dab1022 2951as hv1 ovs-ofctl show br-int
509afdc3
GS
2952as hv1 ovs-ofctl dump-flows br-int
2953echo "------ hv2 dump ----------"
8dab1022 2954as hv2 ovs-ofctl show br-int
509afdc3
GS
2955as hv2 ovs-ofctl dump-flows br-int
2956
2957# Packet to Expect
2958src_mac="000000010204"
2959dst_mac="f00000010204"
49d7c759 2960echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
509afdc3 2961
49d7c759 2962OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 2963
7a8f15e0 2964OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
2965
2966AT_CLEANUP
5412db30
J
2967
2968
4685e523
JP
2969AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
2970AT_KEYWORDS([router-admin-state])
2971AT_SKIP_IF([test $HAVE_PYTHON = no])
2972ovn_start
2973
2974# Logical network:
2975# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
2976# and 172.16.1.0/24) connected to it.
2977
2978ovn-nbctl lr-add R1
2979
2980ovn-nbctl ls-add ls1
2981
2982# Connect ls1 to R1
bf44c2cd 2983ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
2984ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
2985 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
2986
2987# Create logical port ls1-lp1 in ls1
2988ovn-nbctl lsp-add ls1 ls1-lp1 \
2989 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
2990
2991# Create logical port ls1-lp2 in ls1
2992ovn-nbctl lsp-add ls1 ls1-lp2 \
2993 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
2994
2995# Create one hypervisor and create OVS ports corresponding to logical ports.
2996net_add n1
2997
2998sim_add hv1
2999as hv1
3000ovs-vsctl add-br br-phys
3001ovn_attach n1 br-phys 192.168.0.1
3002ovs-vsctl -- add-port br-int vif1 -- \
3003 set interface vif1 external-ids:iface-id=ls1-lp1 \
3004 options:tx_pcap=hv1/vif1-tx.pcap \
3005 options:rxq_pcap=hv1/vif1-rx.pcap \
3006 ofport-request=1
3007
3008ovs-vsctl -- add-port br-int vif2 -- \
3009 set interface vif2 external-ids:iface-id=ls1-lp2 \
3010 options:tx_pcap=hv1/vif2-tx.pcap \
3011 options:rxq_pcap=hv1/vif2-rx.pcap \
3012 ofport-request=1
3013
3014
3015# Allow some time for ovn-northd and ovn-controller to catch up.
3016# XXX This should be more systematic.
3017sleep 1
3018
3019# Send ip packets between the two ports.
3020ip_to_hex() {
3021 printf "%02x%02x%02x%02x" "$@"
3022}
4685e523
JP
3023
3024# Packet to send.
3025src_mac="f00000010203"
3026dst_mac="000000010203"
3027src_ip=`ip_to_hex 192 168 1 2`
3028dst_ip=`ip_to_hex 172 16 1 2`
3029packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3030as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3031
3032
3033echo "---------NB dump-----"
3034ovn-nbctl show
3035echo "---------------------"
3036ovn-nbctl list logical_router
3037echo "---------------------"
3038ovn-nbctl list logical_router_port
3039echo "---------------------"
3040
3041echo "---------SB dump-----"
3042ovn-sbctl list datapath_binding
3043echo "---------------------"
3044ovn-sbctl list logical_flow
3045echo "---------------------"
3046
3047echo "------ hv1 dump ----------"
3048as hv1 ovs-ofctl dump-flows br-int
3049
3050
3051#Disable router R1
3052ovn-nbctl set Logical_Router R1 enabled=false
3053
3b8cd0ea
BP
3054# Allow some time for ovn-northd and ovn-controller to catch up.
3055# XXX This should be more systematic.
3056sleep 1
3057
4685e523
JP
3058echo "---------SB dump-----"
3059ovn-sbctl list datapath_binding
3060echo "---------------------"
3061ovn-sbctl list logical_flow
3062echo "---------------------"
3063
3064echo "------ hv1 dump ----------"
3065as hv1 ovs-ofctl dump-flows br-int
3066
3067as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3068
3069# Packet to Expect
3070expect_src_mac="000000010203"
3071expect_dst_mac="f00000010204"
49d7c759 3072echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3073
49d7c759 3074OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
3075
3076
3077as hv1
3078OVS_APP_EXIT_AND_WAIT([ovn-controller])
3079OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3080OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3081
3082as ovn-sb
3083OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3084
3085as ovn-nb
3086OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3087
3088as northd
3089OVS_APP_EXIT_AND_WAIT([ovn-northd])
3090
3091as main
3092OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3093OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3094
3095AT_CLEANUP
3096
3097
3098AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3099AT_KEYWORDS([router-admin-state])
3100AT_SKIP_IF([test $HAVE_PYTHON = no])
3101ovn_start
3102
3103# Logical network:
3104# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3105# and has switch ls2 (172.16.1.0/24) connected to it.
3106
fa2a27b2 3107ovn-nbctl lr-add R1
5412db30 3108
ea46a4e9
JP
3109ovn-nbctl ls-add ls1
3110ovn-nbctl ls-add ls2
5412db30
J
3111
3112# Connect ls1 to R1
bf44c2cd 3113ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3114ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3115 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3116
3117# Connect ls2 to R1
bf44c2cd 3118ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3119ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3120 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3121
3122# Create logical port ls1-lp1 in ls1
31ed1192
JP
3123ovn-nbctl lsp-add ls1 ls1-lp1 \
3124-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3125
3126# Create logical port ls2-lp1 in ls2
31ed1192
JP
3127ovn-nbctl lsp-add ls2 ls2-lp1 \
3128-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3129
3130# Create one hypervisor and create OVS ports corresponding to logical ports.
3131net_add n1
3132
3133sim_add hv1
3134as hv1
3135ovs-vsctl add-br br-phys
3136ovn_attach n1 br-phys 192.168.0.1
3137ovs-vsctl -- add-port br-int vif1 -- \
3138 set interface vif1 external-ids:iface-id=ls1-lp1 \
3139 options:tx_pcap=hv1/vif1-tx.pcap \
3140 options:rxq_pcap=hv1/vif1-rx.pcap \
3141 ofport-request=1
3142
3143ovs-vsctl -- add-port br-int vif2 -- \
3144 set interface vif2 external-ids:iface-id=ls2-lp1 \
3145 options:tx_pcap=hv1/vif2-tx.pcap \
3146 options:rxq_pcap=hv1/vif2-rx.pcap \
3147 ofport-request=1
3148
3149
3150# Allow some time for ovn-northd and ovn-controller to catch up.
3151# XXX This should be more systematic.
3152sleep 1
3153
3154# Send ip packets between the two ports.
3155ip_to_hex() {
3156 printf "%02x%02x%02x%02x" "$@"
3157}
5412db30
J
3158
3159# Packet to send.
3160src_mac="f00000010203"
3161dst_mac="000000010203"
3162src_ip=`ip_to_hex 192 168 1 2`
3163dst_ip=`ip_to_hex 172 16 1 2`
3164packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3165as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3166
3167
3168echo "---------NB dump-----"
3169ovn-nbctl show
3170echo "---------------------"
3171ovn-nbctl list logical_router
3172echo "---------------------"
3173ovn-nbctl list logical_router_port
3174echo "---------------------"
3175
3176echo "---------SB dump-----"
3177ovn-sbctl list datapath_binding
3178echo "---------------------"
3179ovn-sbctl list logical_flow
3180echo "---------------------"
3181
3182echo "------ hv1 dump ----------"
3183as hv1 ovs-ofctl dump-flows br-int
3184
5412db30
J
3185#Disable router R1
3186ovn-nbctl set Logical_Router R1 enabled=false
3187
3188echo "---------SB dump-----"
3189ovn-sbctl list datapath_binding
3190echo "---------------------"
3191ovn-sbctl list logical_flow
3192echo "---------------------"
3193
3194echo "------ hv1 dump ----------"
3195as hv1 ovs-ofctl dump-flows br-int
3196
a1361a6e
LR
3197# Allow some time for the disabling of logical router R1 to propagate.
3198# XXX This should be more systematic.
3199sleep 1
3200
5412db30
J
3201as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3202
3203# Packet to Expect
3204expect_src_mac="000000010204"
3205expect_dst_mac="f00000010204"
49d7c759 3206echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3207
49d7c759 3208OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3209
7a8f15e0 3210OVN_CLEANUP([hv1])
5412db30
J
3211
3212AT_CLEANUP
3213
28dc3fe9 3214AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3215AT_SKIP_IF([test $HAVE_PYTHON = no])
3216ovn_start
3217
3218# Logical network:
3219# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3220# network. R1 has switchess foo (192.168.1.0/24)
3221# connected to it.
3222# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3223
fa2a27b2
JP
3224ovn-nbctl lr-add R1
3225ovn-nbctl lr-add R2
28dc3fe9 3226
ea46a4e9
JP
3227ovn-nbctl ls-add foo
3228ovn-nbctl ls-add alice
3229ovn-nbctl ls-add bob
28dc3fe9
SR
3230
3231# Connect foo to R1
bf44c2cd 3232ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3233ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3234 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3235
3236# Connect alice to R2
bf44c2cd 3237ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3238ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3239 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3240
3241# Connect bob to R2
bf44c2cd 3242ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3243ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3244 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3245
3246# Connect R1 to R2
4685e523
JP
3247ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3248ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3249
3250#install static routes
e48ccf3c
JP
3251ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3252ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3253ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3254
3255# Create logical port foo1 in foo
31ed1192
JP
3256ovn-nbctl lsp-add foo foo1 \
3257-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3258
3259# Create logical port alice1 in alice
31ed1192
JP
3260ovn-nbctl lsp-add alice alice1 \
3261-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3262
3263# Create logical port bob1 in bob
31ed1192
JP
3264ovn-nbctl lsp-add bob bob1 \
3265-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3266
3267# Create two hypervisor and create OVS ports corresponding to logical ports.
3268net_add n1
3269
3270sim_add hv1
3271as hv1
3272ovs-vsctl add-br br-phys
3273ovn_attach n1 br-phys 192.168.0.1
3274ovs-vsctl -- add-port br-int hv1-vif1 -- \
3275 set interface hv1-vif1 external-ids:iface-id=foo1 \
3276 options:tx_pcap=hv1/vif1-tx.pcap \
3277 options:rxq_pcap=hv1/vif1-rx.pcap \
3278 ofport-request=1
3279
3280ovs-vsctl -- add-port br-int hv1-vif2 -- \
3281 set interface hv1-vif2 external-ids:iface-id=alice1 \
3282 options:tx_pcap=hv1/vif2-tx.pcap \
3283 options:rxq_pcap=hv1/vif2-rx.pcap \
3284 ofport-request=2
3285
3286sim_add hv2
3287as hv2
3288ovs-vsctl add-br br-phys
3289ovn_attach n1 br-phys 192.168.0.2
3290ovs-vsctl -- add-port br-int hv2-vif1 -- \
3291 set interface hv2-vif1 external-ids:iface-id=bob1 \
3292 options:tx_pcap=hv2/vif1-tx.pcap \
3293 options:rxq_pcap=hv2/vif1-rx.pcap \
3294 ofport-request=1
3295
3296
3297# Pre-populate the hypervisors' ARP tables so that we don't lose any
3298# packets for ARP resolution (native tunneling doesn't queue packets
3299# for ARP resolution).
3300ovn_populate_arp
3301
3302# Allow some time for ovn-northd and ovn-controller to catch up.
3303# XXX This should be more systematic.
3304sleep 1
3305
3306ip_to_hex() {
3307 printf "%02x%02x%02x%02x" "$@"
3308}
28dc3fe9
SR
3309
3310# Send ip packets between foo1 and alice1
3311src_mac="f00000010203"
3312dst_mac="000000010203"
3313src_ip=`ip_to_hex 192 168 1 2`
3314dst_ip=`ip_to_hex 172 16 1 2`
3315packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3316as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3317
3318# Send ip packets between foo1 and bob1
3319src_mac="f00000010203"
3320dst_mac="000000010203"
3321src_ip=`ip_to_hex 192 168 1 2`
3322dst_ip=`ip_to_hex 172 16 2 2`
3323packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3324as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3325
3326echo "---------NB dump-----"
3327ovn-nbctl show
3328echo "---------------------"
3329ovn-nbctl list logical_router
3330echo "---------------------"
3331ovn-nbctl list logical_router_port
3332echo "---------------------"
3333
3334echo "---------SB dump-----"
3335ovn-sbctl list datapath_binding
3336echo "---------------------"
3337ovn-sbctl list port_binding
3338echo "---------------------"
3339
3340echo "------ hv1 dump ----------"
3341as hv1 ovs-ofctl dump-flows br-int
3342echo "------ hv2 dump ----------"
3343as hv2 ovs-ofctl dump-flows br-int
3344
3345# Packet to Expect at bob1
3346src_mac="000000010205"
3347dst_mac="f00000010205"
3348src_ip=`ip_to_hex 192 168 1 2`
3349dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3350echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3351
49d7c759 3352OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3353
3354# Packet to Expect at alice1
3355src_mac="000000010204"
3356dst_mac="f00000010204"
3357src_ip=`ip_to_hex 192 168 1 2`
3358dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3359echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3360
49d7c759 3361OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3362
7a8f15e0 3363OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3364
3365AT_CLEANUP
5412db30 3366
0ee8aaf6 3367AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3368AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3369ovn_start
ea46a4e9 3370ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3371net_add n1
3372sim_add hv
3373as hv
3374ovs-vsctl \
3375 -- add-br br-phys \
3376 -- add-br br-eth0
3377
3378ovn_attach n1 br-phys 192.168.0.1
3379
3380AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3381AT_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])
3382
3383# Create a vif.
31ed1192
JP
3384AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3385AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3386AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3387
3388# Create a localnet port.
31ed1192
JP
3389AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3390AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3391AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3392AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3393
3394AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3395
3396# Wait for packet to be received.
49d7c759
BP
3397echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3398OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6
RR
3399
3400# Delete the localnet ports.
3401AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3402AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3403
7a8f15e0 3404OVN_CLEANUP([hv])
0ee8aaf6
RR
3405
3406AT_CLEANUP
75cf9d2b
GS
3407
3408AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
3409AT_SKIP_IF([test $HAVE_PYTHON = no])
3410ovn_start
3411
3412# Logical network:
3413# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3414# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3415# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3416# connected to it.
3417
fa2a27b2
JP
3418ovn-nbctl lr-add R1
3419ovn-nbctl lr-add R2
3420ovn-nbctl lr-add R3
75cf9d2b 3421
ea46a4e9
JP
3422ovn-nbctl ls-add foo
3423ovn-nbctl ls-add alice
3424ovn-nbctl ls-add bob
3425ovn-nbctl ls-add join
75cf9d2b
GS
3426
3427# Connect foo to R1
31114af7 3428ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3429ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3430 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
3431
3432# Connect alice to R2
31114af7 3433ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3434ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3435 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
3436
3437# Connect bob to R3
31114af7 3438ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 3439ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 3440 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
3441
3442# Connect R1 to join
31114af7 3443ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3444ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3445 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
3446
3447# Connect R2 to join
31114af7 3448ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3449ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3450 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
3451
3452# Connect R3 to join
31114af7 3453ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 3454ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 3455 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
3456
3457#install static routes
e48ccf3c
JP
3458ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3459ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 3460
e48ccf3c
JP
3461ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3462ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 3463
e48ccf3c
JP
3464ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3465ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
3466
3467# Create logical port foo1 in foo
31ed1192
JP
3468ovn-nbctl lsp-add foo foo1 \
3469-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
3470
3471# Create logical port alice1 in alice
31ed1192
JP
3472ovn-nbctl lsp-add alice alice1 \
3473-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
3474
3475# Create logical port bob1 in bob
31ed1192
JP
3476ovn-nbctl lsp-add bob bob1 \
3477-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
3478
3479# Create two hypervisor and create OVS ports corresponding to logical ports.
3480net_add n1
3481
3482sim_add hv1
3483as hv1
3484ovs-vsctl add-br br-phys
3485ovn_attach n1 br-phys 192.168.0.1
3486ovs-vsctl -- add-port br-int hv1-vif1 -- \
3487 set interface hv1-vif1 external-ids:iface-id=foo1 \
3488 options:tx_pcap=hv1/vif1-tx.pcap \
3489 options:rxq_pcap=hv1/vif1-rx.pcap \
3490 ofport-request=1
3491
3492ovs-vsctl -- add-port br-int hv1-vif2 -- \
3493 set interface hv1-vif2 external-ids:iface-id=alice1 \
3494 options:tx_pcap=hv1/vif2-tx.pcap \
3495 options:rxq_pcap=hv1/vif2-rx.pcap \
3496 ofport-request=2
3497
3498sim_add hv2
3499as hv2
3500ovs-vsctl add-br br-phys
3501ovn_attach n1 br-phys 192.168.0.2
3502ovs-vsctl -- add-port br-int hv2-vif1 -- \
3503 set interface hv2-vif1 external-ids:iface-id=bob1 \
3504 options:tx_pcap=hv2/vif1-tx.pcap \
3505 options:rxq_pcap=hv2/vif1-rx.pcap \
3506 ofport-request=1
3507
3508
3509# Pre-populate the hypervisors' ARP tables so that we don't lose any
3510# packets for ARP resolution (native tunneling doesn't queue packets
3511# for ARP resolution).
3512ovn_populate_arp
3513
3514# Allow some time for ovn-northd and ovn-controller to catch up.
3515# XXX This should be more systematic.
3516sleep 1
3517
3518ip_to_hex() {
3519 printf "%02x%02x%02x%02x" "$@"
3520}
75cf9d2b
GS
3521
3522# Send ip packets between foo1 and alice1
3523src_mac="f00000010203"
3524dst_mac="000001010203"
3525src_ip=`ip_to_hex 192 168 1 2`
3526dst_ip=`ip_to_hex 172 16 1 2`
3527packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3528as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3529as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3530
3531# Send ip packets between foo1 and bob1
3532src_mac="f00000010203"
3533dst_mac="000001010203"
3534src_ip=`ip_to_hex 192 168 1 2`
3535dst_ip=`ip_to_hex 10 32 1 2`
3536packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3537as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3538
3539echo "---------NB dump-----"
3540ovn-nbctl show
3541echo "---------------------"
3542ovn-nbctl list logical_router
3543echo "---------------------"
3544ovn-nbctl list logical_router_port
3545echo "---------------------"
3546
3547echo "---------SB dump-----"
3548ovn-sbctl list datapath_binding
3549echo "---------------------"
3550ovn-sbctl list port_binding
3551echo "---------------------"
3552ovn-sbctl dump-flows
3553echo "---------------------"
3554
3555echo "------ hv1 dump ----------"
3556as hv1 ovs-ofctl show br-int
3557as hv1 ovs-ofctl dump-flows br-int
3558echo "------ hv2 dump ----------"
3559as hv2 ovs-ofctl show br-int
3560as hv2 ovs-ofctl dump-flows br-int
3561echo "----------------------------"
3562
3563# Packet to Expect at bob1
3564src_mac="000003010203"
3565dst_mac="f00000010205"
3566src_ip=`ip_to_hex 192 168 1 2`
3567dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 3568echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3569
49d7c759 3570OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
3571
3572# Packet to Expect at alice1
3573src_mac="000002010203"
3574dst_mac="f00000010204"
3575src_ip=`ip_to_hex 192 168 1 2`
3576dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3577echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3578
49d7c759 3579OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 3580
7a8f15e0 3581OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
3582
3583AT_CLEANUP
c1645003 3584
281977f7 3585AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
3586AT_SKIP_IF([test $HAVE_PYTHON = no])
3587ovn_start
3588
3589ovn-nbctl ls-add ls1
3590
3591ovn-nbctl lsp-add ls1 ls1-lp1 \
3592-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3593
3594ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3595
3596ovn-nbctl lsp-add ls1 ls1-lp2 \
3597-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3598
3599ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3600
3601ovn-nbctl ls-add ls2
3602ovn-nbctl lsp-add ls2 ls2-lp1 \
3603-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3604ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3605ovn-nbctl lsp-add ls2 ls2-lp2 \
3606-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3607ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3608
3609ovn-nbctl -- --id=@d1 create DHCP_Options cidr=10.0.0.0/24 \
3610options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3611\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"" \
3612-- add Logical_Switch_Port ls1-lp1 dhcpv4_options @d1 \
3613-- add Logical_Switch_Port ls1-lp2 dhcpv4_options @d1
3614
3615ovn-nbctl -- --id=@d2 create DHCP_Options cidr=30.0.0.0/24 \
3616options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3617\"lease_time\"=\"3600\"" -- add Logical_Switch_Port ls2-lp2 dhcpv4_options @d2
3618
3619net_add n1
3620sim_add hv1
3621
3622as hv1
3623ovs-vsctl add-br br-phys
3624ovn_attach n1 br-phys 192.168.0.1
3625ovs-vsctl -- add-port br-int hv1-vif1 -- \
3626 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3627 options:tx_pcap=hv1/vif1-tx.pcap \
3628 options:rxq_pcap=hv1/vif1-rx.pcap \
3629 ofport-request=1
3630
3631ovs-vsctl -- add-port br-int hv1-vif2 -- \
3632 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3633 options:tx_pcap=hv1/vif2-tx.pcap \
3634 options:rxq_pcap=hv1/vif2-rx.pcap \
3635 ofport-request=2
3636
3637ovs-vsctl -- add-port br-int hv1-vif3 -- \
3638 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3639 options:tx_pcap=hv1/vif3-tx.pcap \
3640 options:rxq_pcap=hv1/vif3-rx.pcap \
3641 ofport-request=3
3642
3643ovs-vsctl -- add-port br-int hv1-vif4 -- \
3644 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3645 options:tx_pcap=hv1/vif4-tx.pcap \
3646 options:rxq_pcap=hv1/vif4-rx.pcap \
3647 ofport-request=4
3648
3649ovn_populate_arp
3650
3651sleep 2
3652
3653as hv1 ovs-vsctl show
3654
281977f7
NS
3655# This shell function sends a DHCP request packet
3656# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3657test_dhcp() {
3658 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4
3659 local request=ffffffffffff${src_mac}080045100110000000008011000000000000ffffffff
3660 # udp header and dhcp header
ab187e7e
BP
3661 request=${request}0044004300fc0000
3662 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 3663 # client hardware padding
ab187e7e 3664 request=${request}00000000000000000000
281977f7 3665 # server hostname
ab187e7e
BP
3666 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3667 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3668 # boot file name
ab187e7e
BP
3669 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3670 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3671 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3672 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3673 # dhcp magic cookie
ab187e7e 3674 request=${request}63825363
281977f7 3675 # dhcp message type
ab187e7e 3676 request=${request}3501${dhcp_type}ff
281977f7
NS
3677
3678 if test $offer_ip != 0; then
3679 local srv_mac=$5 srv_ip=$6 expected_dhcp_opts=$7
3680 # total IP length will be the IP length of the request packet
3681 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3682 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3683 udp_len=`expr $ip_len - 20`
04d60f6e
YT
3684 ip_len=$(printf "%x" $ip_len)
3685 udp_len=$(printf "%x" $udp_len)
281977f7
NS
3686 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3687 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3688 # udp header and dhcp header.
3689 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 3690 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 3691 # your ip address
ab187e7e 3692 reply=${reply}${offer_ip}
281977f7 3693 # next server ip address, relay agent ip address, client mac address
ab187e7e 3694 reply=${reply}0000000000000000${src_mac}
281977f7 3695 # client hardware padding
ab187e7e 3696 reply=${reply}00000000000000000000
281977f7 3697 # server hostname
ab187e7e
BP
3698 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3699 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3700 # boot file name
ab187e7e
BP
3701 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3702 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3703 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3704 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3705 # dhcp magic cookie
ab187e7e 3706 reply=${reply}63825363
281977f7
NS
3707 # dhcp message type
3708 local dhcp_reply_type=02
3709 if test $dhcp_type = 03; then
3710 dhcp_reply_type=05
3711 fi
ab187e7e 3712 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
3713 echo $reply >> $inport.expected
3714 else
3715 shift; shift; shift; shift;
3716 for outport; do
e4543cfe 3717 echo $request >> $outport.expected
281977f7
NS
3718 done
3719 fi
3720 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3721}
3722
3723reset_pcap_file() {
3724 local iface=$1
3725 local pcap_file=$2
3726 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3727options:rxq_pcap=dummy-rx.pcap
3728 rm -f ${pcap_file}*.pcap
3729 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3730options:rxq_pcap=${pcap_file}-rx.pcap
3731}
3732
3733ip_to_hex() {
3734 printf "%02x%02x%02x%02x" "$@"
3735}
3736
3737AT_CAPTURE_FILE([ofctl_monitor0.log])
3738as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3739--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3740
3741echo "---------NB dump-----"
3742ovn-nbctl show
3743echo "---------------------"
3744echo "---------SB dump-----"
3745ovn-sbctl list datapath_binding
3746echo "---------------------"
3747ovn-sbctl list logical_flow
3748echo "---------------------"
3749
3750echo "---------------------"
3751ovn-sbctl dump-flows
3752echo "---------------------"
3753
3754echo "------ hv1 dump ----------"
3755as hv1 ovs-ofctl dump-flows br-int
3756
3757# Send DHCPDISCOVER.
3758offer_ip=`ip_to_hex 10 0 0 4`
3759server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 3760expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
281977f7
NS
3761test_dhcp 1 f00000000001 01 $offer_ip ff1000000001 $server_ip $expected_dhcp_opts
3762
3763# NXT_RESUMEs should be 1.
3764OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3765
3766$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3767cat 1.expected | cut -c -48 > expout
3768AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3769# Skipping the IPv4 checksum.
3770cat 1.expected | cut -c 53- > expout
3771AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3772
3773# ovs-ofctl also resumes the packets and this causes other ports to receive
3774# the DHCP request packet. So reset the pcap files so that its easier to test.
3775reset_pcap_file hv1-vif1 hv1/vif1
3776reset_pcap_file hv1-vif2 hv1/vif2
3777rm -f 1.expected
3778rm -f 2.expected
3779
3780# Send DHCPREQUEST.
3781offer_ip=`ip_to_hex 10 0 0 6`
3782server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 3783expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
281977f7
NS
3784test_dhcp 2 f00000000002 03 $offer_ip ff1000000001 $server_ip $expected_dhcp_opts
3785
3786# NXT_RESUMEs should be 2.
3787OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3788
3789$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3790cat 2.expected | cut -c -48 > expout
3791AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3792# Skipping the IPv4 checksum.
3793cat 2.expected | cut -c 53- > expout
3794AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3795
3796reset_pcap_file hv1-vif1 hv1/vif1
3797reset_pcap_file hv1-vif2 hv1/vif2
3798rm -f 1.expected
3799rm -f 2.expected
3800
3801# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3802# but should be resumed without the reply.
3803# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3804# one from ovn-controller and the other from "ovs-ofctl resume."
3805offer_ip=0
3806test_dhcp 2 f00000000002 08 $offer_ip 1 1
3807
3808# NXT_RESUMEs should be 3.
3809OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3810
3811# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 3812OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
3813
3814reset_pcap_file hv1-vif1 hv1/vif1
3815reset_pcap_file hv1-vif2 hv1/vif2
3816rm -f 1.expected
3817rm -f 2.expected
3818
3819# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3820# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3821
3822test_dhcp 3 f00000000003 01 0 4
3823
3824# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3825# this lport.
3826test_dhcp 4 f00000000004 01 0 3
3827
3828# NXT_RESUMEs should be 3.
3829OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3830
49d7c759
BP
3831OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
3832OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7
NS
3833
3834as hv1
33ac3c83
NS
3835OVS_APP_EXIT_AND_WAIT([ovn-controller])
3836OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3837OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3838
3839as ovn-sb
3840OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3841
3842as ovn-nb
3843OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3844
3845as northd
3846OVS_APP_EXIT_AND_WAIT([ovn-northd])
3847
3848as main
3849OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3850OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3851
3852AT_CLEANUP
3853
40df4566 3854AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
3855AT_SKIP_IF([test $HAVE_PYTHON = no])
3856ovn_start
3857
3858ovn-nbctl ls-add ls1
3859ovn-nbctl lsp-add ls1 ls1-lp1 \
3860-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3861
3862ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3863
3864ovn-nbctl lsp-add ls1 ls1-lp2 \
3865-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3866
3867ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3868
40df4566
ZKL
3869ovn-nbctl lsp-add ls1 ls1-lp3 \
3870-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3871
3872ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3873
33ac3c83
NS
3874ovn-nbctl -- --id=@d1 create DHCP_Options cidr="ae70\:\:/64" \
3875options="\"server_id\"=\"00:00:00:10:00:01\"" \
3876-- add Logical_Switch_Port ls1-lp1 dhcpv6_options @d1 \
3877-- add Logical_Switch_Port ls1-lp2 dhcpv6_options @d1
3878
40df4566
ZKL
3879ovn-nbctl -- --id=@d2 create DHCP_Options cidr="ae70\:\:/64" \
3880options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"" \
3881-- add Logical_Switch_Port ls1-lp3 dhcpv6_options @d2
3882
33ac3c83
NS
3883ovn-nbctl ls-add ls2
3884ovn-nbctl lsp-add ls2 ls2-lp1 \
3885-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
3886ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
3887ovn-nbctl lsp-add ls2 ls2-lp2 \
3888-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
3889ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
3890
3891net_add n1
3892sim_add hv1
3893
3894as hv1
3895ovs-vsctl add-br br-phys
3896ovn_attach n1 br-phys 192.168.0.1
3897ovs-vsctl -- add-port br-int hv1-vif1 -- \
3898 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3899 options:tx_pcap=hv1/vif1-tx.pcap \
3900 options:rxq_pcap=hv1/vif1-rx.pcap \
3901 ofport-request=1
3902
3903ovs-vsctl -- add-port br-int hv1-vif2 -- \
3904 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3905 options:tx_pcap=hv1/vif2-tx.pcap \
3906 options:rxq_pcap=hv1/vif2-rx.pcap \
3907 ofport-request=2
3908
3909ovs-vsctl -- add-port br-int hv1-vif3 -- \
3910 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3911 options:tx_pcap=hv1/vif3-tx.pcap \
3912 options:rxq_pcap=hv1/vif3-rx.pcap \
3913 ofport-request=3
3914
3915ovs-vsctl -- add-port br-int hv1-vif4 -- \
3916 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3917 options:tx_pcap=hv1/vif4-tx.pcap \
3918 options:rxq_pcap=hv1/vif4-rx.pcap \
3919 ofport-request=4
3920
40df4566
ZKL
3921ovs-vsctl -- add-port br-int hv1-vif5 -- \
3922 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
3923 options:tx_pcap=hv1/vif5-tx.pcap \
3924 options:rxq_pcap=hv1/vif5-rx.pcap \
3925 ofport-request=5
3926
33ac3c83
NS
3927ovn_populate_arp
3928
3929sleep 2
3930
3931trim_zeros() {
3932 sed 's/\(00\)\{1,\}$//'
3933}
3934
3935# This shell function sends a DHCPv6 request packet
40df4566
ZKL
3936# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
3937# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
3938# packet should be received twice (one from ovn-controller and the other
3939# from the "ovs-ofctl monitor br-int resume"
3940test_dhcpv6() {
3941 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
3942 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
3943 # dst ip ff02::1:2
ab187e7e 3944 request=${request}ff020000000000000000000000010002
33ac3c83 3945 # udp header and dhcpv6 header
ab187e7e 3946 request=${request}02220223002affff${msg_code}010203
33ac3c83 3947 # Client identifier
ab187e7e 3948 request=${request}0001000a00030001${src_mac}
33ac3c83 3949 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 3950 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
3951 shift; shift; shift; shift; shift;
3952 if test $offer_ip != 0; then
3953 local server_mac=000000100001
3954 local server_lla=fe80000000000000020000fffe100001
3955 local reply_code=07
3956 if test $msg_code = 01; then
3957 reply_code=02
3958 fi
40df4566
ZKL
3959 local msg_len=54
3960 if test $offer_ip = 1; then
3961 msg_len=28
3962 fi
3963 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 3964 # udp header and dhcpv6 header
ab187e7e 3965 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 3966 # Client identifier
ab187e7e 3967 reply=${reply}0001000a00030001${src_mac}
33ac3c83 3968 # IA-NA
40df4566 3969 if test $offer_ip != 1; then
ab187e7e 3970 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 3971 fi
33ac3c83 3972 # Server identifier
ab187e7e 3973 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
3974 echo $reply | trim_zeros >> $inport.expected
3975 else
3976 for outport; do
3977 echo $request | trim_zeros >> $outport.expected
3978 done
3979 fi
3980
3981 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3982}
3983
3984reset_pcap_file() {
3985 local iface=$1
3986 local pcap_file=$2
3987 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3988options:rxq_pcap=dummy-rx.pcap
3989 rm -f ${pcap_file}*.pcap
3990 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3991options:rxq_pcap=${pcap_file}-rx.pcap
3992}
3993
3994AT_CAPTURE_FILE([ofctl_monitor0.log])
3995as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3996--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3997
3998echo "---------NB dump-----"
3999ovn-nbctl show
4000echo "---------------------"
4001echo "---------SB dump-----"
4002ovn-sbctl list datapath_binding
4003echo "---------------------"
4004ovn-sbctl list logical_flow
4005echo "---------------------"
4006
4007echo "---------------------"
4008ovn-sbctl dump-flows
4009echo "---------------------"
4010
4011echo "------ hv1 dump ----------"
4012as hv1 ovs-ofctl dump-flows br-int
4013
4014src_mac=f00000000001
4015src_lla=fe80000000000000f20000fffe000001
4016offer_ip=ae700000000000000000000000000004
4017test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4018
4019# NXT_RESUMEs should be 1.
4020OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4021
4022$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4023# cat 1.expected | trim_zeros > expout
4024cat 1.expected | cut -c -120 > expout
4025AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4026# Skipping the UDP checksum
4027cat 1.expected | cut -c 125- > expout
4028AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4029
4030rm 1.expected
4031
4032# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4033# without any modifications and the packet should be received by ls1-lp1.
4034# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4035# resume and the other from ovs-ofctl monitor resume.
4036
4037reset_pcap_file hv1-vif1 hv1/vif1
4038reset_pcap_file hv1-vif2 hv1/vif2
4039
4040src_mac=f00000000002
4041src_lla=fe80000000000000f20000fffe000002
4042offer_ip=ae700000000000000000000000000005
4043# Set invalid msg_type
4044
4045test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4046
4047# NXT_RESUMEs should be 2.
4048OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4049
4050# vif2-tx.pcap should not have received the DHCPv6 reply packet
4051rm 2.packets
4052$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4053AT_CHECK([cat 2.packets], [0], [])
4054
4055# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4056$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4057cat 1.expected > expout
4058AT_CHECK([cat 1.packets], [0], [expout])
4059
4060# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4061# There should be no DHCPv6 reply from ovn-controller and the request packet
4062# should be received by ls2-lp2.
4063
4064src_mac=f00000000003
4065src_lla=fe80000000000000f20000fffe000003
4066test_dhcpv6 3 $src_mac $src_lla 01 0 4
4067
4068# NXT_RESUMEs should be 2 only.
4069OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4070
4071# vif3-tx.pcap should not have received the DHCPv6 reply packet
4072$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4073AT_CHECK([cat 3.packets], [0], [])
4074
4075# vif4-tx.pcap should have received the DHCPv6 request packet
4076$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4077cat 4.expected > expout
4078AT_CHECK([cat 4.packets], [0], [expout])
4079
40df4566
ZKL
4080# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4081# The DHCPv6 reply should doesn't contian offer_ip.
4082src_mac=f00000000022
4083src_lla=fe80000000000000f20000fffe000022
4084reset_pcap_file hv1-vif5 hv1/vif5
4085test_dhcpv6 5 $src_mac $src_lla 01 1 5
4086
4087# NXT_RESUMEs should be 3.
4088OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4089
4090$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4091# Skipping the UDP checksum
4092cat 5.expected | cut -c 1-120,125- > expout
4093AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4094
33ac3c83 4095as hv1
281977f7
NS
4096OVS_APP_EXIT_AND_WAIT([ovn-controller])
4097OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4098OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4099
4100as ovn-sb
4101OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4102
4103as ovn-nb
4104OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4105
4106as northd
4107OVS_APP_EXIT_AND_WAIT([ovn-northd])
4108
4109as main
4110OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4111OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4112
4113AT_CLEANUP
4114
c1645003 4115AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4116AT_SKIP_IF([test $HAVE_PYTHON = no])
4117ovn_start
4118
4119# Logical network:
4120# Two LRs - R1 and R2 that are connected to each other via LS "join"
4121# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4122# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4123# R2 is a gateway router.
4124
4125
4126
4127# Create two hypervisor and create OVS ports corresponding to logical ports.
4128net_add n1
4129
4130sim_add hv1
4131as hv1
4132ovs-vsctl add-br br-phys
4133ovn_attach n1 br-phys 192.168.0.1
4134ovs-vsctl -- add-port br-int hv1-vif1 -- \
4135 set interface hv1-vif1 external-ids:iface-id=foo1 \
4136 options:tx_pcap=hv1/vif1-tx.pcap \
4137 options:rxq_pcap=hv1/vif1-rx.pcap \
4138 ofport-request=1
4139
4140
4141sim_add hv2
4142as hv2
4143ovs-vsctl add-br br-phys
4144ovn_attach n1 br-phys 192.168.0.2
4145ovs-vsctl -- add-port br-int hv2-vif1 -- \
4146 set interface hv2-vif1 external-ids:iface-id=alice1 \
4147 options:tx_pcap=hv2/vif1-tx.pcap \
4148 options:rxq_pcap=hv2/vif1-rx.pcap \
4149 ofport-request=1
4150
4151# Pre-populate the hypervisors' ARP tables so that we don't lose any
4152# packets for ARP resolution (native tunneling doesn't queue packets
4153# for ARP resolution).
4154ovn_populate_arp
4155
4156ovn-nbctl create Logical_Router name=R1
4157ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4158
ea46a4e9
JP
4159ovn-nbctl ls-add foo
4160ovn-nbctl ls-add alice
4161ovn-nbctl ls-add join
c1645003
GS
4162
4163# Connect foo to R1
31114af7 4164ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4165ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4166 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4167
4168# Connect alice to R2
31114af7 4169ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4170ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4171 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4172
4173# Connect R1 to join
31114af7 4174ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4175ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4176 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4177
4178# Connect R2 to join
31114af7 4179ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4180ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4181 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4182
4183
4184#install static routes
4185ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4186ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4187R1 static_routes @lrt
4188
4189ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4190ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4191R2 static_routes @lrt
4192
4193# Create logical port foo1 in foo
31ed1192
JP
4194ovn-nbctl lsp-add foo foo1 \
4195-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4196
4197# Create logical port alice1 in alice
31ed1192
JP
4198ovn-nbctl lsp-add alice alice1 \
4199-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4200
4201
4202# Allow some time for ovn-northd and ovn-controller to catch up.
4203# XXX This should be more systematic.
4204sleep 2
4205
4206ip_to_hex() {
4207 printf "%02x%02x%02x%02x" "$@"
4208}
c1645003
GS
4209
4210# Send ip packets between foo1 and alice1
4211src_mac="f00000010203"
4212dst_mac="000001010203"
4213src_ip=`ip_to_hex 192 168 1 2`
4214dst_ip=`ip_to_hex 172 16 1 2`
4215packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4216
4217echo "---------NB dump-----"
4218ovn-nbctl show
4219echo "---------------------"
4220ovn-nbctl list logical_router
4221echo "---------------------"
4222ovn-nbctl list logical_router_port
4223echo "---------------------"
4224
4225echo "---------SB dump-----"
4226ovn-sbctl list datapath_binding
4227echo "---------------------"
4228ovn-sbctl list port_binding
4229echo "---------------------"
4230ovn-sbctl dump-flows
4231echo "---------------------"
4232ovn-sbctl list chassis
4233ovn-sbctl list encap
4234echo "---------------------"
4235
c1645003
GS
4236# Packet to Expect at alice1
4237src_mac="000002010203"
4238dst_mac="f00000010204"
4239src_ip=`ip_to_hex 192 168 1 2`
4240dst_ip=`ip_to_hex 172 16 1 2`
4241expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4242
4243
4244as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4245as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4246
ab39371d
RM
4247echo "------ hv1 dump after packet 1 ----------"
4248as hv1 ovs-ofctl show br-int
4249as hv1 ovs-ofctl dump-flows br-int
4250echo "------ hv2 dump after packet 1 ----------"
4251as hv2 ovs-ofctl show br-int
4252as hv2 ovs-ofctl dump-flows br-int
4253echo "----------------------------"
4254
49d7c759
BP
4255echo $expected > expected
4256OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4257
34114cf8
GS
4258# Delete the router and re-create it. Things should work as before.
4259ovn-nbctl lr-del R2
4260ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4261# Connect alice to R2
4262ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4263# Connect R2 to join
4264ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4265
4266ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4267ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4268R2 static_routes @lrt
4269
4270# Wait for ovn-controller to catch up.
4271sleep 1
4272
4273# Send the packet again.
4274as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4275
4276echo "------ hv1 dump after packet 2 ----------"
4277as hv1 ovs-ofctl show br-int
4278as hv1 ovs-ofctl dump-flows br-int
4279echo "------ hv2 dump after packet 2 ----------"
4280as hv2 ovs-ofctl show br-int
4281as hv2 ovs-ofctl dump-flows br-int
4282echo "----------------------------"
4283
49d7c759
BP
4284echo $expected >> expected
4285OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4286
7a8f15e0 4287OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4288
4289AT_CLEANUP
bb3c4568
FF
4290
4291AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4292AT_KEYWORDS([router-icmp-reply])
4293AT_SKIP_IF([test $HAVE_PYTHON = no])
4294ovn_start
4295
4296# Logical network:
4297# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4298# and has switch ls2 (172.16.1.0/24) connected to it.
4299
fa2a27b2 4300ovn-nbctl lr-add R1
bb3c4568 4301
ea46a4e9
JP
4302ovn-nbctl ls-add ls1
4303ovn-nbctl ls-add ls2
bb3c4568
FF
4304
4305# Connect ls1 to R1
31114af7 4306ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4307ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4308 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4309
4310# Connect ls2 to R1
31114af7 4311ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4312ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4313 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4314
4315# Create logical port ls1-lp1 in ls1
31ed1192
JP
4316ovn-nbctl lsp-add ls1 ls1-lp1 \
4317-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4318
4319# Create logical port ls2-lp1 in ls2
31ed1192
JP
4320ovn-nbctl lsp-add ls2 ls2-lp1 \
4321-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4322
4323# Create one hypervisor and create OVS ports corresponding to logical ports.
4324net_add n1
4325
4326sim_add hv1
4327as hv1
4328ovs-vsctl add-br br-phys
4329ovn_attach n1 br-phys 192.168.0.1
4330ovs-vsctl -- add-port br-int vif1 -- \
4331 set interface vif1 external-ids:iface-id=ls1-lp1 \
4332 options:tx_pcap=hv1/vif1-tx.pcap \
4333 options:rxq_pcap=hv1/vif1-rx.pcap \
4334 ofport-request=1
4335
4336ovs-vsctl -- add-port br-int vif2 -- \
4337 set interface vif2 external-ids:iface-id=ls2-lp1 \
4338 options:tx_pcap=hv1/vif2-tx.pcap \
4339 options:rxq_pcap=hv1/vif2-rx.pcap \
4340 ofport-request=1
4341
4342
4343# Allow some time for ovn-northd and ovn-controller to catch up.
4344# XXX This should be more systematic.
4345sleep 1
4346
4347
4348ip_to_hex() {
4349 printf "%02x%02x%02x%02x" "$@"
4350}
bb3c4568
FF
4351for i in 1 2; do
4352 : > vif$i.expected
4353done
4354# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4355#
4356# Causes a packet to be received on INPORT. The packet is an ICMPv4
4357# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4358# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4359# provided, then it should be the ip and icmp checksums of the packet
4360# responded; otherwise, no reply is expected.
4361# In the absence of an ip checksum calculation helpers, this relies
4362# on the caller to provide the checksums for the ip and icmp headers.
4363# XXX This should be more systematic.
4364#
4365# INPORT is an lport number, e.g. 11 for vif11.
4366# ETH_SRC and ETH_DST are each 12 hex digits.
4367# IPV4_SRC and IPV4_DST are each 8 hex digits.
4368# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4369# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4370test_ipv4_icmp_request() {
4371 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4372 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4373 shift; shift; shift; shift; shift; shift; shift
4374 shift; shift
4375
4376 # Use ttl to exercise section 4.2.2.9 of RFC1812
4377 local ip_ttl=01
4378 local icmp_id=5fbf
4379 local icmp_seq=0001
4380 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4381 local icmp_type_code_request=0800
4382 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4383 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4384
4385 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4386 if test X$exp_icmp_chksum != X; then
4387 # Expect to receive the reply, if any. In same port where packet was sent.
4388 # Note: src and dst fields are expected to be reversed.
4389 local icmp_type_code_response=0000
4390 local reply_icmp_ttl=fe
4391 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4392 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4393 echo $reply >> vif$inport.expected
4394 fi
4395}
4396
4397# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4398rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4399rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4400l1_ip=$(ip_to_hex 192 168 1 2)
4401l2_ip=$(ip_to_hex 172 16 1 2)
4402
4403# Ping router ip address that is on same subnet as the logical port
4404test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4405test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4406
4407# Ping router ip address that is on the other side of the logical ports
4408test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4409test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4410
4411echo "---------NB dump-----"
4412ovn-nbctl show
4413echo "---------------------"
4414ovn-nbctl list logical_router
4415echo "---------------------"
4416ovn-nbctl list logical_router_port
4417echo "---------------------"
4418
4419echo "---------SB dump-----"
4420ovn-sbctl list datapath_binding
4421echo "---------------------"
4422ovn-sbctl list logical_flow
4423echo "---------------------"
4424
4425echo "------ hv1 dump ----------"
4426as hv1 ovs-ofctl dump-flows br-int
4427
4428# Now check the packets actually received against the ones expected.
4429for inport in 1 2; do
49d7c759 4430 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4431done
4432
7a8f15e0 4433OVN_CLEANUP([hv1])
bb3c4568
FF
4434
4435AT_CLEANUP
94f79fcb
RB
4436
4437# 1 hypervisor, 1 port
4438# make sure that the port state is properly set to up and back down
4439# when created and deleted.
4440AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
4441ovn_start
4442
4443ovn-nbctl ls-add ls1
4444ovn-nbctl lsp-add ls1 lp1
4445ovn-nbctl lsp-set-addresses lp1 unknown
4446
4447net_add n1
4448sim_add hv1
4449as hv1 ovs-vsctl add-br br-phys
4450as hv1 ovn_attach n1 br-phys 192.168.0.1
4451
4452as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4453OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4454
4455as hv1 ovs-vsctl del-port br-int vif1
4456OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4457
7a8f15e0 4458OVN_CLEANUP([hv1])
94f79fcb 4459
94f79fcb 4460AT_CLEANUP
e75451fe 4461
ccc6e1db
FF
4462# 1 hypervisor, 1 port
4463# make sure that the OF rules created to support a datapath are added/cleared
4464# when logical switch is created and removed.
4465AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 4466AT_KEYWORDS([cleanup])
ccc6e1db
FF
4467ovn_start
4468
4469net_add n1
4470sim_add hv1
4471as hv1 ovs-vsctl add-br br-phys
4472as hv1 ovn_attach n1 br-phys 192.168.0.1
4473
4474# This shell function checks if OF rules in br-int have clauses
4475# related to OVN datapaths. The caller determines if it should find
4476# a match in the output, or not.
4477#
4478# EXPECT_DATAPATH param determines whether flows that refer to
4479# datapath to should be present or not. 0 means
4480# they should not be.
4481# STAGE_INFO param is a simple string to help identify the stage
4482# in the test when this function was invoked.
4483test_datapath_in_of_rules() {
4484 local expect_datapath=$1 stage_info=$2
4485 echo "------ ovn-nbctl show ${stage_info} ------"
4486 ovn-nbctl show
4487 echo "------ ovn-sbctl show ${stage_info} ------"
4488 ovn-sbctl show
4489 echo "------ OF rules ${stage_info} ------"
4490 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4491 # if there is a datapath mentioned in the output, check for the
4492 # magic keyword that represents one, based on the exit status of
4493 # a quiet grep
4494 if test $expect_datapath != 0; then
4618b102 4495 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 4496 else
4618b102 4497 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
4498 fi
4499}
4500
4501test_datapath_in_of_rules 0 "before ls+port create"
4502
4503ovn-nbctl ls-add ls1
4504ovn-nbctl lsp-add ls1 lp1
4505ovn-nbctl lsp-set-addresses lp1 unknown
4506
4507as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4508OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4509
4510test_datapath_in_of_rules 1 "after port is bound"
4511
4512as hv1 ovs-vsctl del-port br-int vif1
4513OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4514
4515ovn-nbctl lsp-set-addresses lp1
4516ovn-nbctl lsp-del lp1
4517ovn-nbctl ls-del ls1
4518
4519# wait for earlier changes to take effect
4520AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4521
4522# ensure OF rules are no longer present. There used to be a bug here.
4523test_datapath_in_of_rules 0 "after lport+ls removal"
4524
4525OVN_CLEANUP([hv1])
4526
4527AT_CLEANUP
4528
f8a8db39 4529AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
4530AT_SKIP_IF([test $HAVE_PYTHON = no])
4531ovn_start
4532
4533#TODO: since patch port for IPv6 logical router port is not ready not,
4534# so we are not going to test vifs on different lswitches cases. Try
4535# to update for that once relevant stuff implemented.
4536
4537# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4538# with. NS packet we test, from one VIF for another VIF, will be replied
4539# by local ovn-controller, but not by target VIF.
4540
4541# Create hypervisors and logical switch lsw0.
4542ovn-nbctl ls-add lsw0
4543net_add n1
4544sim_add hv1
4545as hv1
4546ovs-vsctl add-br br-phys
4547ovn_attach n1 br-phys 192.168.0.2
4548
4549# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4550ovs-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
4551ovn-nbctl lsp-add lsw0 lp1
4552ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4553ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4554
4555# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4556ovs-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
4557ovn-nbctl lsp-add lsw0 lp2
4558ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4559ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4560
4561# Add ACL rule for ICMPv6 on lsw0
4562ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4563ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4564ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4565
4566# Allow some time for ovn-northd and ovn-controller to catch up.
4567# XXX This should be more systematic.
4568sleep 1
4569
4570# Given the name of a logical port, prints the name of the hypervisor
4571# on which it is located.
4572vif_to_hv() {
4573 echo hv1${1%?}
4574}
e75451fe
ZKL
4575for i in 1 2; do
4576 : > $i.expected
4577done
4578
4579# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4580# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4581# vif2 will not receive NS packet, since ovn-controller will reply for it.
4582ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4583na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4584
4585as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 4586echo $na_packet >> 1.expected
e75451fe 4587
e75451fe
ZKL
4588echo "------ hv1 dump ------"
4589as hv1 ovs-vsctl show
4590as hv1 ovs-ofctl -O OpenFlow13 show br-int
4591as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4592
4593for i in 1 2; do
49d7c759 4594 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
4595done
4596
7a8f15e0 4597OVN_CLEANUP([hv1])
e75451fe
ZKL
4598
4599AT_CLEANUP
7417d147
RM
4600
4601AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
4602ovn_start
4603
4604net_add n1
4605
4606sim_add hv1
4607as hv1
4608ovs-vsctl add-br br-phys
4609ovn_attach n1 br-phys 192.168.0.1
4610
4611row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4612ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4613ovn-nbctl destroy Address_Set $row
4614
4615sleep 1
4616
4617# A bug previously existed in the address set support code
4618# that caused ovn-controller to crash after an address set
4619# was updated and then removed. This test case ensures
4620# that ovn-controller is at least still running after
4621# creating, updating, and deleting an address set.
4622AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4623
4624OVN_CLEANUP([hv1])
4625
4626AT_CLEANUP
8639f9be
ND
4627
4628AT_SETUP([ovn -- ipam])
8639f9be
ND
4629AT_SKIP_IF([test $HAVE_PYTHON = no])
4630ovn_start
4631
4632# Add a port to a switch that does not have a subnet set, then set the
4633# subnet which should result in an address being allocated for the port.
4634ovn-nbctl ls-add sw0
4635ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 4636ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
4637AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4638 ["0a:00:00:00:00:01 192.168.1.2"
4639])
4640
4641# Add 9 more ports to sw0, addresses should all be unique.
4642for n in `seq 1 9`; do
11547f85 4643 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4644done
4645AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4646 ["0a:00:00:00:00:02 192.168.1.3"
4647])
4648AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4649 ["0a:00:00:00:00:03 192.168.1.4"
4650])
4651AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4652 ["0a:00:00:00:00:04 192.168.1.5"
4653])
4654AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4655 ["0a:00:00:00:00:05 192.168.1.6"
4656])
4657AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4658 ["0a:00:00:00:00:06 192.168.1.7"
4659])
4660AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4661 ["0a:00:00:00:00:07 192.168.1.8"
4662])
4663AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4664 ["0a:00:00:00:00:08 192.168.1.9"
4665])
4666AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4667 ["0a:00:00:00:00:09 192.168.1.10"
4668])
4669AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4670 ["0a:00:00:00:00:0a 192.168.1.11"
4671])
4672
4673# Trying similar tests with a second switch. MAC addresses should be unique
4674# across both switches but IP's only need to be unique within the same switch.
4675ovn-nbctl ls-add sw1
4676ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 4677ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
4678AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4679 ["0a:00:00:00:00:0b 192.168.1.2"
4680])
4681
4682for n in `seq 11 19`; do
11547f85 4683 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4684done
4685AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4686 ["0a:00:00:00:00:0c 192.168.1.3"
4687])
4688AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4689 ["0a:00:00:00:00:0d 192.168.1.4"
4690])
4691AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4692 ["0a:00:00:00:00:0e 192.168.1.5"
4693])
4694AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4695 ["0a:00:00:00:00:0f 192.168.1.6"
4696])
4697AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4698 ["0a:00:00:00:00:10 192.168.1.7"
4699])
4700AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4701 ["0a:00:00:00:00:11 192.168.1.8"
4702])
4703AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4704 ["0a:00:00:00:00:12 192.168.1.9"
4705])
4706AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4707 ["0a:00:00:00:00:13 192.168.1.10"
4708])
4709AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4710 ["0a:00:00:00:00:14 192.168.1.11"
4711])
4712
4713# Change a port's address to test for multiple ip's for a single address entry
4714# and addresses set by the user.
4715ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
11547f85 4716ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
4717AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4718 ["0a:00:00:00:00:16 192.168.1.13"
4719])
4720
4721# Test for logical router port address management.
4722ovn-nbctl create Logical_Router name=R1
4723ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4724network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4725-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4726-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 4727ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
4728AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4729 ["0a:00:00:00:00:18 192.168.1.15"
4730])
4731
4732# Test for address reuse after logical port is deleted.
4733ovn-nbctl lsp-del p0
11547f85 4734ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
4735AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4736 ["0a:00:00:00:00:19 192.168.1.2"
4737])
4738
4739# Test for multiple addresses to one logical port.
4740ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4741"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 4742ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
4743AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4744 ["0a:00:00:00:00:1c 192.168.1.16"
4745])
4746
4747# Test for exhausting subnet address space.
4748ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 4749ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
4750AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4751 ["0a:00:00:00:00:1d 172.16.1.2"
4752])
4753
11547f85 4754ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be
ND
4755AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
4756 [[[]]
4757])
4758
4759# Test that address management does not add duplicate MAC for lsp/lrp peers.
4760ovn-nbctl create Logical_Router name=R2
4761ovn-nbctl ls-add sw3
4762ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
4763"0a:00:00:00:00:1e"
4764ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4765network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4766-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4767-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 4768ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
4769AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4770 ["0a:00:00:00:00:20 192.168.1.17"
4771])
4772
6374d518
LR
4773# Test static MAC address with dynamically allocated IP
4774ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
4775"fe:dc:ba:98:76:54 dynamic"
4776AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4777 ["fe:dc:ba:98:76:54 192.168.1.18"
4778])
4779
8639f9be
ND
4780as ovn-sb
4781OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4782
4783as ovn-nb
4784OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4785
4786as northd
4787OVS_APP_EXIT_AND_WAIT([ovn-northd])
4788
4789AT_CLEANUP
4790
4791AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
4792AT_SKIP_IF([test $HAVE_PYTHON = no])
4793ovn_start
4794
4795ovn-nbctl lr-add R1
4796
4797# Test for a ping using dynamically allocated addresses.
4798ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
4799ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
4800
4801# Connect foo to R1
4802ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
4803ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4804 options:router-port=foo addresses=\"00:00:00:01:02:03\"
4805
4806# Connect alice to R1
4807ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
4808ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
4809 options:router-port=alice addresses=\"00:00:00:01:02:04\"
4810
4811# Create logical port foo1 in foo
fd3b31e9 4812ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 4813-- lsp-set-addresses foo1 "dynamic"
8bc2c143 4814AT_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
4815
4816# Create logical port alice1 in alice
fd3b31e9 4817ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 4818-- lsp-set-addresses alice1 "dynamic"
8bc2c143 4819AT_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
4820
4821# Create logical port foo2 in foo
fd3b31e9 4822ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 4823-- lsp-set-addresses foo2 "dynamic"
8bc2c143 4824AT_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
4825
4826# Create a hypervisor and create OVS ports corresponding to logical ports.
4827net_add n1
4828
4829sim_add hv1
4830as hv1
4831ovs-vsctl add-br br-phys
4832ovn_attach n1 br-phys 192.168.0.1
4833ovs-vsctl -- add-port br-int hv1-vif1 -- \
4834 set interface hv1-vif1 external-ids:iface-id=foo1 \
4835 options:tx_pcap=hv1/vif1-tx.pcap \
4836 options:rxq_pcap=hv1/vif1-rx.pcap \
4837 ofport-request=1
4838
4839ovs-vsctl -- add-port br-int hv1-vif2 -- \
4840 set interface hv1-vif2 external-ids:iface-id=foo2 \
4841 options:tx_pcap=hv1/vif2-tx.pcap \
4842 options:rxq_pcap=hv1/vif2-rx.pcap \
4843 ofport-request=2
4844
4845ovs-vsctl -- add-port br-int hv1-vif3 -- \
4846 set interface hv1-vif3 external-ids:iface-id=alice1 \
4847 options:tx_pcap=hv1/vif3-tx.pcap \
4848 options:rxq_pcap=hv1/vif3-rx.pcap \
4849 ofport-request=3
4850
4851# Allow some time for ovn-northd and ovn-controller to catch up.
4852# XXX This should be more systematic.
4853sleep 1
4854
4855ip_to_hex() {
4856 printf "%02x%02x%02x%02x" "$@"
4857}
8639f9be
ND
4858
4859# Send ip packets between foo1 and foo2
4860src_mac="0a0000000001"
4861dst_mac="0a0000000003"
4862src_ip=`ip_to_hex 192 168 1 2`
4863dst_ip=`ip_to_hex 192 168 1 3`
4864packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4865as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4866
4867# Send ip packets between foo1 and alice1
4868src_mac="0a0000000001"
4869dst_mac="000000010203"
4870src_ip=`ip_to_hex 192 168 1 2`
4871dst_ip=`ip_to_hex 192 168 2 2`
4872packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4873as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4874
4875echo "---------NB dump-----"
4876ovn-nbctl show
4877echo "---------------------"
4878ovn-nbctl list logical_router
4879echo "---------------------"
4880ovn-nbctl list logical_router_port
4881echo "---------------------"
4882
4883echo "---------SB dump-----"
4884ovn-sbctl list datapath_binding
4885echo "---------------------"
4886ovn-sbctl list port_binding
4887echo "---------------------"
4888
4889echo "------ hv1 dump ----------"
4890as hv1 ovs-ofctl dump-flows br-int
4891
4892# Packet to Expect at foo2
4893src_mac="0a0000000001"
4894dst_mac="0a0000000003"
4895src_ip=`ip_to_hex 192 168 1 2`
4896dst_ip=`ip_to_hex 192 168 1 3`
4897expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4898
e4543cfe
DDP
4899$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
4900echo $expected > expout
8639f9be
ND
4901AT_CHECK([cat received1.packets], [0], [expout])
4902
4903# Packet to Expect at alice1
4904src_mac="000000010204"
4905dst_mac="0a0000000002"
4906src_ip=`ip_to_hex 192 168 1 2`
4907dst_ip=`ip_to_hex 192 168 2 2`
4908expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
4909
e4543cfe
DDP
4910$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
4911echo $expected > expout
8639f9be
ND
4912AT_CHECK([cat received2.packets], [0], [expout])
4913
4914OVN_CLEANUP([hv1])
4915
4916AT_CLEANUP
f5792c3f
NS
4917
4918AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 4919AT_KEYWORDS([vswitchd])
f5792c3f
NS
4920AT_SKIP_IF([test $HAVE_PYTHON = no])
4921ovn_start
4922
4923ovn-nbctl ls-add ls1
4924
4925ovn-nbctl lsp-add ls1 ls1-lp1 \
4926-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4927
4928ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4929
4930net_add n1
4931sim_add hv1
4932
4933as hv1
4934ovs-vsctl add-br br-phys
4935ovn_attach n1 br-phys 192.168.0.1
4936ovs-vsctl -- add-port br-int hv1-vif1 -- \
4937 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4938 options:tx_pcap=hv1/vif1-tx.pcap \
4939 options:rxq_pcap=hv1/vif1-rx.pcap \
4940 ofport-request=1
4941
4942ovn_populate_arp
4943sleep 2
4944
4945as hv1 ovs-vsctl show
4946
4947echo "---------------------"
4948ovn-sbctl dump-flows
4949echo "---------------------"
4950
4951echo "------ hv1 dump ----------"
4952as hv1 ovs-ofctl dump-flows br-int
4953total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4954
4955echo "Total flows before vswitchd restart = " $total_flows
4956
4957# Code taken from ovs-save utility
4958save_flows () {
4959 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
4960 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
4961 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
4962 echo "EOF" >> restore_flows.sh
4963}
4964
4965restart_vswitchd () {
4966 restore_flows=$1
4967
4968 if test $restore_flows = true; then
4969 save_flows
4970 fi
4971
4972 as hv1
4973 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4974
4975 if test $restore_flows = true; then
4976 as hv1
4977 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
4978 fi
4979
4980 as hv1
4981 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
4982 ovs-ofctl dump-flows br-int
4983
4984 if test $restore_flows = true; then
4985 sh ./restore_flows.sh
4986 echo "Flows after restore"
4987 as hv1
4988 ovs-ofctl dump-flows br-int
4989 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
4990 flow-restore-wait="true"
4991 fi
4992}
4993
4994# Save the flows, restart vswitchd and restore the flows
4995restart_vswitchd true
4996OVS_WAIT_UNTIL([
4997 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4998 echo "Total flows after vswitchd restart = " $total_flows_after_restart
4999 test "${total_flows}" = "${total_flows_after_restart}"
5000])
5001
5002# Restart vswitchd without restoring
5003restart_vswitchd false
5004OVS_WAIT_UNTIL([
5005 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5006 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5007 test "${total_flows}" = "${total_flows_after_restart}"
5008])
5009
5010OVN_CLEANUP([hv1])
5011AT_CLEANUP
47021598
CSV
5012
5013AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5014AT_SKIP_IF([test $HAVE_PYTHON = no])
5015ovn_start
5016
5017# Topology: Two LSs - ls1 and ls2 are connected via router r0
5018
5019# Create logical switches
5020ovn-nbctl ls-add ls1
5021ovn-nbctl ls-add ls2
5022
5023# Create router
5024ovn-nbctl create Logical_Router name=lr0
5025
5026# Add router ls1p1 port to gateway router
5027ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5028ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5029 type=router options:router-port=lrp-ls1lp1 \
5030 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5031
5032# Add router ls2p2 port to gateway router
5033ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5034ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5035 type=router options:router-port=lrp-ls2lp1 \
5036 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5037
5038# Set default gateway (nexthop) to 192.168.1.254
5039ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5040
5041# Create logical port ls1lp2 in ls1
5042ovn-nbctl lsp-add ls1 ls1lp2 \
5043-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5044
5045# Create logical port ls2lp2 in ls2
5046ovn-nbctl lsp-add ls2 ls2lp2 \
5047-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5048
5049net_add n1
5050sim_add hv1
5051as hv1
5052ovs-vsctl add-br br-phys
5053ovn_attach n1 br-phys 192.168.0.1
5054ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5055 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5056 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5057 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5058 ofport-request=1
5059ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5060 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5061 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5062 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5063 ofport-request=2
5064
5065# Allow some time for ovn-northd and ovn-controller to catch up.
5066# XXX This should be more systematic.
5067sleep 1
5068
5069echo "---------NB dump-----"
5070ovn-nbctl show
5071echo "---------------------"
5072ovn-nbctl list logical_router
5073echo "---------------------"
5074ovn-nbctl list logical_router_port
5075echo "---------------------"
5076
5077echo "---------SB dump-----"
5078ovn-sbctl list datapath_binding
5079echo "---------------------"
5080ovn-sbctl list port_binding
5081echo "---------------------"
5082ovn-sbctl dump-flows
5083echo "---------------------"
5084ovn-sbctl list chassis
5085ovn-sbctl list encap
5086echo "---------------------"
5087
5088echo "------Flows dump-----"
5089as hv1
5090ovs-ofctl dump-flows
5091echo "---------------------"
5092
5093ip_to_hex() {
5094 printf "%02x%02x%02x%02x" "$@"
5095}
5096
5097src_mac="f00000000003"
5098dst_mac="f00000000001"
5099src_ip=`ip_to_hex 192 168 0 2`
5100dst_ip=`ip_to_hex 8 8 8 8`
5101packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5102
5103# Send IP packet destined to 8.8.8.8 from lsp1lp2
5104as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5105
5106trim_zeros() {
5107 sed 's/\(00\)\{1,\}$//'
5108}
5109
5110# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5111# not 8.8.8.8
5112
5113$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5114expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5115echo $expected > expout
5116AT_CHECK([cat packets], [0], [expout])
5117cat packets
5118
5119OVN_CLEANUP([hv1])
5120
5121AT_CLEANUP
8439c2eb
CSV
5122
5123AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5124AT_SKIP_IF([test $HAVE_PYTHON = no])
5125ovn_start
5126# Create logical switch
5127ovn-nbctl ls-add ls0
5128# Create gateway router
5129ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5130# Add router port to gateway router
5131ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5132ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5133 type=router options:router-port=lrp0-rp addresses='"f0:00:00:00:00:01"'
5134# Add nat-address option
5135ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5136
5137net_add n1
5138sim_add hv1
5139as hv1
5140ovs-vsctl \
5141 -- add-br br-phys \
5142 -- add-br br-eth0
5143
5144ovn_attach n1 br-phys 192.168.0.1
5145
5146AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5147AT_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])
5148
5149# Create a localnet port.
5150AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5151AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5152AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5153AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5154
5155
5156# Wait for packet to be received.
5157OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5158trim_zeros() {
5159 sed 's/\(00\)\{1,\}$//'
5160}
5161$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5162expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5163echo $expected > expout
5164AT_CHECK([sort packets], [0], [expout])
5165cat packets
5166
5167OVN_CLEANUP([hv1])
5168
5169AT_CLEANUP
6e31816f
CSV
5170
5171AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
5172ovn_start
5173net_add n1
5174sim_add hv1
5175as hv1
5176ovs-vsctl -- add-br br-phys
5177ovn_attach n1 br-phys 192.168.0.1
5178# Create logical switch ls0
5179ovn-nbctl ls-add ls0
5180# Create ports lp0, lp1 in ls0
5181ovn-nbctl lsp-add ls0 lp0
5182ovn-nbctl lsp-add ls0 lp1
5183ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5184ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5185dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5186ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5187ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5188ovn-sbctl find MAC_Binding
093aa761 5189# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5190ovn-nbctl lsp-del lp0
5191ovn-sbctl find MAC_Binding
093aa761
BP
5192OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5193# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5194ovn-nbctl ls-del ls0
5195ovn-sbctl find MAC_Binding
093aa761 5196OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
5197
5198OVN_CLEANUP([hv1])
5199
5200AT_CLEANUP
926c34fd
RM
5201
5202AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
5203AT_SKIP_IF([test $HAVE_PYTHON = no])
5204ovn_start
5205
5206# Logical network:
5207# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5208# connected to a router R1.
5209# foo has foo1 to act as a client.
5210# bar has bar1, bar2, bar3 to act as servers.
5211
5212net_add n1
5213
5214sim_add hv1
5215as hv1
5216ovs-vsctl add-br br-phys
5217ovn_attach n1 br-phys 192.168.0.1
5218for i in foo1 bar1 bar2 bar3; do
5219 ovs-vsctl -- add-port br-int $i -- \
5220 set interface $i external-ids:iface-id=$i \
5221 options:tx_pcap=hv1/$i-tx.pcap \
5222 options:rxq_pcap=hv1/$i-rx.pcap
5223done
5224
5225ovn-nbctl create Logical_Router name=R1
5226ovn-nbctl ls-add foo
5227ovn-nbctl ls-add bar
5228
5229# Connect foo to R1
5230ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5231ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5232 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5233
5234# Connect bar to R1
5235ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5236ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5237 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5238
5239# Create logical port foo1 in foo
5240ovn-nbctl lsp-add foo foo1 \
5241-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5242
5243# Create logical port bar1, bar2 and bar3 in bar
5244for i in `seq 1 3`; do
5245 ip=`expr $i + 1`
5246 ovn-nbctl lsp-add bar bar$i \
5247 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5248done
5249
5250OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5251
5252OVN_CLEANUP([hv1])
5253
5254AT_CLEANUP
b511690b
GS
5255
5256AT_SETUP([ovn -- tag allocation])
b511690b
GS
5257ovn_start
5258
5259AT_CHECK([ovn-nbctl ls-add ls0])
5260AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5261AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5262AT_CHECK([ovn-nbctl ls-add ls1])
5263
5264dnl When a tag is provided, no allocation is done
5265AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5266AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5267])
5268dnl The same 'tag' gets created in southbound database.
5269AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5270logical_port="c0"], [0], [3
5271])
5272
5273dnl Allocate tags and see it getting created in both NB and SB
5274AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5275AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5276])
5277AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5278logical_port="c1"], [0], [1
5279])
5280
5281AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5282AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5283])
5284AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5285logical_port="c2"], [0], [2
5286])
5287AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5288AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5289])
5290AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5291logical_port="c3"], [0], [4
5292])
5293
5294dnl A different parent.
5295AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5296AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5297])
5298AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5299logical_port="c4"], [0], [1
5300])
5301
5302AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5303AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5304])
5305AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5306logical_port="c5"], [0], [2
5307])
5308
5309dnl Delete a logical port and create a new one.
5310AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5311AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5312AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5313])
5314AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5315logical_port="c6"], [0], [1
5316])
5317
5318dnl Restart northd to see that the same allocation remains.
5319as northd
5320OVS_APP_EXIT_AND_WAIT([ovn-northd])
5321start_daemon ovn-northd \
5322 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5323 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5324
5325dnl Create a switch to make sure that ovn-northd has run through the main loop.
5326AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5327AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5328])
5329AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5330])
5331AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5332])
5333AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5334])
5335AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5336])
5337AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5338])
5339
5340dnl Create a switch port with a tag that has already been allocated.
5341dnl It should go through fine with a duplicate tag.
5342AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5343AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5344])
5345AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5346logical_port="c7"], [0], [2
5347])
5348AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5349])
5350
5351AT_CHECK([ovn-nbctl ls-add ls2])
5352dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5353dnl gets copied to 'tag'
5354AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5355AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5356])
5357dnl The same 'tag' gets created in southbound database.
5358AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5359logical_port="local0"], [0], [25
5360])
5361dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5362AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5363AT_CHECK([ovn-nbctl lsp-get-tag local1])
5364dnl change the tag_request.
5365AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5366AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5367])
5368
5369AT_CLEANUP
57afd0c0
RR
5370
5371AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
5372ovn_start
5373ovn-nbctl ls-add lsw0
5374net_add n1
5375for i in 1 2; do
5376 sim_add hv$i
5377 as hv$i
5378 ovs-vsctl add-br br-phys
5379 ovn_attach n1 br-phys 192.168.0.$i
5380 ovs-vsctl add-br br-eth0
5381 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5382done
5383
5384# Create a localnet port.
5385AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5386AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5387AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5388AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5389
5390
5391# Create 3 vifs.
5392AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5393AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5394AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5395AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5396AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5397AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5398AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5399AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5400AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5401
5402# Bind the localvif1 to hv1.
5403as hv1
5404AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5405
5406# On hv1, check that there are no flows outputting bcast to tunnel
5407OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5408
1ea9b847 5409# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 5410as hv2
1ea9b847 5411OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
5412
5413# Now bind vif2 on hv2.
5414AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5415
5416# At this point, the broadcast flow on vif2 should be deleted.
5417# because, there is now a localnet vif bound (table=32 programming logic)
5418OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5419
5420# Verify that the local net patch port exists on hv2.
5421OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5422
5423# Now bind vif3 on hv2.
5424AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5425
5426# Verify that the local net patch port still exists on hv2
5427OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5428
5429# Delete localvif2
5430AT_CHECK([ovn-nbctl lsp-del localvif2])
5431
5432# Verify that the local net patch port still exists on hv2,
5433# because, localvif3 is still bound.
5434OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5435
57afd0c0 5436OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
5437
5438AT_CLEANUP
5439
5440AT_SETUP([ovn -- DSCP marking check])
5441AT_KEYWORDS([ovn])
5442ovn_start
5443
5444ovn-nbctl ls-add lsw0
5445ovn-nbctl --wait=sb lsp-add lsw0 lp1
5446ovn-nbctl --wait=sb lsp-add lsw0 lp2
5447ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5448ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5449ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5450ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5451ovn-nbctl --wait=sb sync
5452net_add n1
5453sim_add hv
5454as hv
5455ovs-vsctl add-br br-phys
5456ovn_attach n1 br-phys 192.168.0.1
5457ovs-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
5458ovs-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
5459
5460AT_CAPTURE_FILE([trace])
5461ovn_trace () {
5462 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5463}
5464
5465# Extracts nw_tos from the final flow from ofproto/trace output and prints
5466# it on stdout. Prints "none" if no nw_tos was included.
5467get_final_nw_tos() {
5468 if flow=$(grep '^Final flow:' stdout); then :; else
5469 # The output didn't have a final flow.
5470 return 99
5471 fi
5472
5473 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5474 case $tos in
5475 '') echo none ;;
5476 *) echo $tos ;;
5477 esac
5478}
5479
5480# check_tos TOS
5481#
5482# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
5483check_tos() {
5484 # First check with ovn-trace for logical flows.
5485 echo "checking for tos $1"
5486 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
5487 echo 'output("lp2");') > expout
5488 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])
5489
5490 # Then re-check with ofproto/trace for a physical packet.
5491 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])
5492 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
5493])
5494}
5495
5496# check at L2
5497AT_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");
5498])
5499AT_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])
5500AT_CHECK([get_final_nw_tos], [0], [none
5501])
5502
5503# check at L3 without dscp marking
5504check_tos 0
5505
5506# Mark DSCP with a valid value
5507qos_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)
5508check_tos 48
5509
5510# Update the DSCP marking
5511ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
5512check_tos 63
5513
5514ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
5515check_tos 63
5516
5517# Disable DSCP marking
5518ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
5519check_tos 0
5520
5521OVN_CLEANUP([hv])
57afd0c0 5522AT_CLEANUP
7fff4eb7
LR
5523
5524AT_SETUP([ovn -- read-only sb db:ptcp access])
5525AT_SKIP_IF([test $HAVE_PYTHON = no])
5526
5527: > .$1.db.~lock~
5528ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5529
5530# Add read-only remote to sb ovsdb-server
5531AT_CHECK(
5532 [ovsdb-tool transact ovn-sb.db \
5533 ['["OVN_Southbound",
5534 {"op": "insert",
5535 "table": "SB_Global",
5536 "row": {
5537 "connections": ["set", [["named-uuid", "xyz"]]]}},
5538 {"op": "insert",
5539 "table": "Connection",
5540 "uuid-name": "xyz",
5541 "row": {"target": "ptcp:0:127.0.0.1",
5542 "read_only": true}}]']], [0], [ignore], [ignore])
5543
5544start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
5545
5546PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5547
5548# read-only accesses should succeed
5549AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
5550AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
5551
5552# write access should fail
5553AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
5554[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
5555])
5556
5557OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5558AT_CLEANUP
5559
5560AT_SETUP([ovn -- read-only sb db:pssl access])
5561AT_SKIP_IF([test $HAVE_PYTHON = no])
5562AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5563PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5564AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5565\\]"])
5566
5567: > .$1.db.~lock~
5568ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5569
5570# Add read-only remote to sb ovsdb-server
5571AT_CHECK(
5572 [ovsdb-tool transact ovn-sb.db \
5573 ['["OVN_Southbound",
5574 {"op": "insert",
5575 "table": "SB_Global",
5576 "row": {
5577 "connections": ["set", [["named-uuid", "xyz"]]]}},
5578 {"op": "insert",
5579 "table": "Connection",
5580 "uuid-name": "xyz",
5581 "row": {"target": "pssl:0:127.0.0.1",
5582 "read_only": true}}]']], [0], [ignore], [ignore])
5583
5584start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
5585 --remote=db:OVN_Southbound,SB_Global,connections \
5586 --private-key="$PKIDIR/testpki-privkey2.pem" \
5587 --certificate="$PKIDIR/testpki-cert2.pem" \
5588 --ca-cert="$PKIDIR/testpki-cacert.pem" \
5589 ovn-sb.db
5590
5591PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5592
5593# read-only accesses should succeed
5594AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5595 --private-key=$PKIDIR/testpki-privkey.pem \
5596 --certificate=$PKIDIR/testpki-cert.pem \
5597 --ca-cert=$PKIDIR/testpki-cacert.pem \
5598 list SB_Global], [0], [stdout], [ignore])
5599AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5600 --private-key=$PKIDIR/testpki-privkey.pem \
5601 --certificate=$PKIDIR/testpki-cert.pem \
5602 --ca-cert=$PKIDIR/testpki-cacert.pem \
5603 list Connection], [0], [stdout], [ignore])
5604
5605# write access should fail
5606AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5607 --private-key=$PKIDIR/testpki-privkey.pem \
5608 --certificate=$PKIDIR/testpki-cert.pem \
5609 --ca-cert=$PKIDIR/testpki-cacert.pem \
5610 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
5611[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
5612])
5613
5614OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5615AT_CLEANUP
5616
821302cf
LR
5617AT_SETUP([ovn -- nb connection/ssl commands])
5618AT_SKIP_IF([test $HAVE_PYTHON = no])
5619AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5620PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5621AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5622\\]"])
5623
5624: > .$1.db.~lock~
5625ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
5626
5627# Start nb db server using db connection/ssl entries (unpopulated initially)
5628start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
5629 --remote=db:OVN_Northbound,NB_Global,connections \
5630 --private-key=db:OVN_Northbound,SSL,private_key \
5631 --certificate=db:OVN_Northbound,SSL,certificate \
5632 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
5633 ovn-nb.db
5634
5635# Populate SSL configuration entries in nb db
5636AT_CHECK(
5637 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
5638 $PKIDIR/testpki-cert.pem \
5639 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
5640
5641# Populate a passive SSL connection in nb db
5642AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
5643
5644PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5645
5646# Verify SSL connetivity to nb db server
5647AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5648 --private-key=$PKIDIR/testpki-privkey.pem \
5649 --certificate=$PKIDIR/testpki-cert.pem \
5650 --ca-cert=$PKIDIR/testpki-cacert.pem \
5651 list NB_Global],
5652 [0], [stdout], [ignore])
5653AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5654 --private-key=$PKIDIR/testpki-privkey.pem \
5655 --certificate=$PKIDIR/testpki-cert.pem \
5656 --ca-cert=$PKIDIR/testpki-cacert.pem \
5657 list Connection],
5658 [0], [stdout], [ignore])
5659AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5660 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
5661 --certificate=$PKIDIR/testpki-cert.pem \
5662 --ca-cert=$PKIDIR/testpki-cacert.pem \
5663 get-connection],
5664 [0], [stdout], [ignore])
5665
5666OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5667AT_CLEANUP
5668
5669AT_SETUP([ovn -- sb connection/ssl commands])
5670AT_SKIP_IF([test $HAVE_PYTHON = no])
5671AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5672PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5673AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5674\\]"])
5675
5676: > .$1.db.~lock~
5677ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5678
5679# Start sb db server using db connection/ssl entries (unpopulated initially)
5680start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
5681 --remote=db:OVN_Southbound,SB_Global,connections \
5682 --private-key=db:OVN_Southbound,SSL,private_key \
5683 --certificate=db:OVN_Southbound,SSL,certificate \
5684 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
5685 ovn-sb.db
5686
5687# Populate SSL configuration entries in sb db
5688AT_CHECK(
5689 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
5690 $PKIDIR/testpki-cert.pem \
5691 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
5692
5693# Populate a passive SSL connection in sb db
5694AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
5695
5696PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5697
5698# Verify SSL connetivity to sb db server
5699AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5700 --private-key=$PKIDIR/testpki-privkey.pem \
5701 --certificate=$PKIDIR/testpki-cert.pem \
5702 --ca-cert=$PKIDIR/testpki-cacert.pem \
5703 list SB_Global],
5704 [0], [stdout], [ignore])
5705AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5706 --private-key=$PKIDIR/testpki-privkey.pem \
5707 --certificate=$PKIDIR/testpki-cert.pem \
5708 --ca-cert=$PKIDIR/testpki-cacert.pem \
5709 list Connection],
5710 [0], [stdout], [ignore])
5711AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5712 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
5713 --certificate=$PKIDIR/testpki-cert.pem \
5714 --ca-cert=$PKIDIR/testpki-cacert.pem \
5715 get-connection],
5716 [0], [stdout], [ignore])
5717
5718OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5719AT_CLEANUP
5720
75fd74f8
GS
5721AT_SETUP([ovn -- nested containers])
5722ovn_start
5723
5724# Physical network:
5725# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
5726
5727# Logical network:
5728# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
5729# and "bar" (192.168.2.0/24). They are all connected to router R1.
5730
5731ovn-nbctl lr-add R1
5732ovn-nbctl ls-add mgmt
5733ovn-nbctl ls-add foo
5734ovn-nbctl ls-add bar
5735
5736# Connect mgmt to R1
5737ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
5738ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
5739 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
5740
5741# Connect foo to R1
5742ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5743ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5744 options:router-port=foo addresses=\"00:00:00:01:02:03\"
5745
5746# Connect bar to R1
5747ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
5748ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
5749 options:router-port=bar addresses=\"00:00:00:01:02:04\"
5750
5751# "mgmt" has VM1 and VM2 connected
5752ovn-nbctl lsp-add mgmt vm1 \
5753-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
5754
5755ovn-nbctl lsp-add mgmt vm2 \
5756-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
5757
5758# "foo1" and "foo2" are containers belonging to switch "foo"
5759# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
5760ovn-nbctl lsp-add foo foo1 vm1 1 \
5761-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
5762
5763ovn-nbctl lsp-add foo foo2 vm2 2 \
5764-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
5765
5766# "bar1" and "bar2" are containers belonging to switch "bar"
5767# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
5768ovn-nbctl lsp-add bar bar1 vm1 2 \
5769-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
5770
5771ovn-nbctl lsp-add bar bar2 vm2 1 \
5772-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
5773
5774# bar3 is a standalone VM belonging to switch "bar"
5775ovn-nbctl lsp-add bar bar3 \
5776-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
5777
5778# Create two hypervisor and create OVS ports corresponding to logical ports.
5779net_add n1
5780
5781sim_add hv1
5782as hv1
5783ovs-vsctl add-br br-phys
5784ovn_attach n1 br-phys 192.168.0.1
5785ovs-vsctl -- add-port br-int vm1 -- \
5786 set interface vm1 external-ids:iface-id=vm1 \
5787 options:tx_pcap=hv1/vm1-tx.pcap \
5788 options:rxq_pcap=hv1/vm1-rx.pcap \
5789 ofport-request=1
5790
5791ovs-vsctl -- add-port br-int bar3 -- \
5792 set interface bar3 external-ids:iface-id=bar3 \
5793 options:tx_pcap=hv1/bar3-tx.pcap \
5794 options:rxq_pcap=hv1/bar3-rx.pcap \
5795 ofport-request=2
5796
5797sim_add hv2
5798as hv2
5799ovs-vsctl add-br br-phys
5800ovn_attach n1 br-phys 192.168.0.2
5801ovs-vsctl -- add-port br-int vm2 -- \
5802 set interface vm2 external-ids:iface-id=vm2 \
5803 options:tx_pcap=hv2/vm2-tx.pcap \
5804 options:rxq_pcap=hv2/vm2-rx.pcap \
5805 ofport-request=1
5806
5807# Pre-populate the hypervisors' ARP tables so that we don't lose any
5808# packets for ARP resolution (native tunneling doesn't queue packets
5809# for ARP resolution).
5810ovn_populate_arp
5811
5812# Allow some time for ovn-northd and ovn-controller to catch up.
5813# XXX This should be more systematic.
5814sleep 1
5815
5816ip_to_hex() {
5817 printf "%02x%02x%02x%02x" "$@"
5818}
5819
5820# Send ip packets between foo1 and foo2 (same switch, different HVs and
5821# different VLAN tags).
5822src_mac="f00000010205"
5823dst_mac="f00000010206"
5824src_ip=`ip_to_hex 192 168 1 2`
5825dst_ip=`ip_to_hex 192 168 1 3`
5826packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5827as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5828
5829# expected packet at foo2
5830packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5831echo $packet > expected
5832OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
5833
5834# Send ip packets between foo1 and bar2 (different switch, different HV)
5835src_mac="f00000010205"
5836dst_mac="000000010203"
5837src_ip=`ip_to_hex 192 168 1 2`
5838dst_ip=`ip_to_hex 192 168 2 3`
5839packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5840as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5841
5842# expected packet at bar2
5843src_mac="000000010204"
5844dst_mac="f00000010208"
5845packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5846echo $packet >> expected
5847OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
5848
5849# Send ip packets between foo1 and bar1
5850# (different switch, loopback to same vm but different tag)
5851src_mac="f00000010205"
5852dst_mac="000000010203"
5853src_ip=`ip_to_hex 192 168 1 2`
5854dst_ip=`ip_to_hex 192 168 2 2`
5855packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5856as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5857
5858# expected packet at bar1
5859src_mac="000000010204"
5860dst_mac="f00000010207"
5861packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5862echo $packet > expected1
5863OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
5864
5865# Send ip packets between bar1 and bar3
5866# (same switch. But one is container and another is a standalone VM)
5867src_mac="f00000010207"
5868dst_mac="f00000010209"
5869src_ip=`ip_to_hex 192 168 2 2`
5870dst_ip=`ip_to_hex 192 168 2 3`
5871packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5872as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5873
5874# expected packet at bar3
5875packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5876echo $packet > expected
5877OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
5878
5879# Send ip packets between foo1 and vm1.
5880(different switch, container to the VM hosting it.)
5881src_mac="f00000010205"
5882dst_mac="000000010203"
5883src_ip=`ip_to_hex 192 168 1 2`
5884dst_ip=`ip_to_hex 172 16 1 2`
5885packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5886as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5887
5888# expected packet at vm1
5889src_mac="000000010202"
5890dst_mac="f00000010203"
5891packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5892echo $packet >> expected1
5893OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
5894
5895# Send packets from vm1 to bar1.
5896(different switch, A hosting VM to a container inside it)
5897src_mac="f00000010203"
5898dst_mac="000000010202"
5899src_ip=`ip_to_hex 172 16 1 2`
5900dst_ip=`ip_to_hex 192 168 2 2`
5901packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5902as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5903
5904# expected packet at vm1
5905src_mac="000000010204"
5906dst_mac="f00000010207"
5907packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5908echo $packet >> expected1
5909OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
5910
5911OVN_CLEANUP([hv1],[hv2])
5912
5913AT_CLEANUP
440a9f4b
GS
5914
5915AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
5916AT_SKIP_IF([test $HAVE_PYTHON = no])
5917ovn_start
5918
5919# Logical network:
5920# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
5921# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
5922# (192.168.2.0/24) connected to it.
5923#
5924# R2 and R3 are gateway routers.
5925# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
5926# connected to it. Note how both alice and bob have the same subnet behind it.
5927# We are trying to simulate external network via those 2 switches. In real
5928# world the switch ports of these switches will have addresses set as "unknown"
5929# to make them learning switches. Or those switches will be "localnet" ones.
5930
5931# Create three hypervisors and create OVS ports corresponding to logical ports.
5932net_add n1
5933
5934sim_add hv1
5935as hv1
5936ovs-vsctl add-br br-phys
5937ovn_attach n1 br-phys 192.168.0.1
5938ovs-vsctl -- add-port br-int hv1-vif1 -- \
5939 set interface hv1-vif1 external-ids:iface-id=foo1 \
5940 options:tx_pcap=hv1/vif1-tx.pcap \
5941 options:rxq_pcap=hv1/vif1-rx.pcap \
5942 ofport-request=1
5943
5944ovs-vsctl -- add-port br-int hv1-vif2 -- \
5945 set interface hv1-vif2 external-ids:iface-id=bar1 \
5946 options:tx_pcap=hv1/vif2-tx.pcap \
5947 options:rxq_pcap=hv1/vif2-rx.pcap \
5948 ofport-request=2
5949
5950sim_add hv2
5951as hv2
5952ovs-vsctl add-br br-phys
5953ovn_attach n1 br-phys 192.168.0.2
5954ovs-vsctl -- add-port br-int hv2-vif1 -- \
5955 set interface hv2-vif1 external-ids:iface-id=alice1 \
5956 options:tx_pcap=hv2/vif1-tx.pcap \
5957 options:rxq_pcap=hv2/vif1-rx.pcap \
5958 ofport-request=1
5959
5960sim_add hv3
5961as hv3
5962ovs-vsctl add-br br-phys
5963ovn_attach n1 br-phys 192.168.0.3
5964ovs-vsctl -- add-port br-int hv3-vif1 -- \
5965 set interface hv3-vif1 external-ids:iface-id=bob1 \
5966 options:tx_pcap=hv3/vif1-tx.pcap \
5967 options:rxq_pcap=hv3/vif1-rx.pcap \
5968 ofport-request=1
5969
5970
5971ovn-nbctl create Logical_Router name=R1
5972ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5973ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
5974
5975ovn-nbctl ls-add foo
5976ovn-nbctl ls-add bar
5977ovn-nbctl ls-add alice
5978ovn-nbctl ls-add bob
5979ovn-nbctl ls-add join
5980
5981# Connect foo to R1
5982ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5983ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5984 options:router-port=foo addresses=\"00:00:01:01:02:03\"
5985
5986# Connect bar to R1
5987ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
5988ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
5989 options:router-port=bar addresses=\"00:00:01:01:02:04\"
5990
5991# Connect alice to R2
5992ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5993ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
5994 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
5995
5996# Connect bob to R3
5997ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
5998ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
5999 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6000
6001# Connect R1 to join
6002ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6003ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6004 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6005
6006# Connect R2 to join
6007ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6008ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6009 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6010
6011# Connect R3 to join
6012ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6013ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6014 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6015
6016# Install static routes with source ip address as the policy for routing.
6017# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6018ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6019ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6020
6021# Install static routes with destination ip address as the policy for routing.
6022ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6023
6024ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6025
6026# Create logical port foo1 in foo
6027ovn-nbctl lsp-add foo foo1 \
6028-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6029
6030# Create logical port bar1 in bar
6031ovn-nbctl lsp-add bar bar1 \
6032-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6033
6034# Create logical port alice1 in alice
6035ovn-nbctl lsp-add alice alice1 \
6036-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6037
6038# Create logical port bob1 in bob
6039ovn-nbctl lsp-add bob bob1 \
6040-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6041
6042# Pre-populate the hypervisors' ARP tables so that we don't lose any
6043# packets for ARP resolution (native tunneling doesn't queue packets
6044# for ARP resolution).
6045ovn_populate_arp
6046
6047# Allow some time for ovn-northd and ovn-controller to catch up.
6048# XXX This should be more systematic.
6049sleep 1
6050
6051ip_to_hex() {
6052 printf "%02x%02x%02x%02x" "$@"
6053}
6054trim_zeros() {
6055 sed 's/\(00\)\{1,\}$//'
6056}
6057
6058# Send ip packets between foo1 and bar1
6059# (East-west traffic should flow normally)
6060src_mac="f00000010203"
6061dst_mac="000001010203"
6062src_ip=`ip_to_hex 192 168 1 2`
6063dst_ip=`ip_to_hex 192 168 2 2`
6064packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6065as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6066
6067# Send ip packets between foo1 and alice1
6068src_mac="f00000010203"
6069dst_mac="000001010203"
6070src_ip=`ip_to_hex 192 168 1 2`
6071dst_ip=`ip_to_hex 172 16 1 3`
6072packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6073as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6074#as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6075
6076# Send ip packets between bar1 and bob1
6077src_mac="f00000010204"
6078dst_mac="000001010204"
6079src_ip=`ip_to_hex 192 168 2 2`
6080dst_ip=`ip_to_hex 172 16 1 4`
6081packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6082as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6083#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6084
6085# Packet to expect at bar1
6086src_mac="000001010204"
6087dst_mac="f00000010204"
6088src_ip=`ip_to_hex 192 168 1 2`
6089dst_ip=`ip_to_hex 192 168 2 2`
6090expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6091echo $expected > expected
6092OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6093
6094# Packet to Expect at alice1
6095src_mac="000002010203"
6096dst_mac="f00000010205"
6097src_ip=`ip_to_hex 192 168 1 2`
6098dst_ip=`ip_to_hex 172 16 1 3`
6099expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6100echo $expected > expected
6101OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6102
6103# Packet to Expect at bob1
6104src_mac="000003010203"
6105dst_mac="f00000010206"
6106src_ip=`ip_to_hex 192 168 2 2`
6107dst_ip=`ip_to_hex 172 16 1 4`
6108expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6109echo $expected > expected
6110OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6111
6112for sim in hv1 hv2 hv3; do
6113 as $sim
6114 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6115 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6116 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6117done
6118
6119as ovn-sb
6120OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6121
6122as ovn-nb
6123OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6124
6125as northd
6126OVS_APP_EXIT_AND_WAIT([ovn-northd])
6127
6128as main
6129OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6130OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6131
6132AT_CLEANUP