]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
stopwatch: Fix qsort comparison function.
[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"`
697f5993
BP
20 OVS_WAIT_UNTIL(
21 [$PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 echo "rcv_n=$rcv_n exp_n=$exp_n"
24 test $rcv_n -ge $exp_n])
e4543cfe 25 sort $exp_text > expout
49d7c759
BP
26 }
27])
28m4_define([OVN_CHECK_PACKETS],
29 [ovn_check_packets__ "$1" "$2"
30 AT_CHECK([sort $rcv_text], [0], [expout])])
31
f295c17b 32AT_BANNER([OVN components])
10b1662b
BP
33
34AT_SETUP([ovn -- lexer])
35dnl For lines without =>, input and expected output are identical.
36dnl For lines with =>, input precedes => and expected output follows =>.
37AT_DATA([test-cases.txt], [dnl
38foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
39"abc\u0020def" => "abc def"
40" => error("Input ends inside quoted string.")dnl "
41
2c5cbb15
RB
42$foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
43$1 => error("`$' must be followed by a valid identifier.") 1
44
10b1662b
BP
45a/*b*/c => a c
46a//b c => a
47a/**/b => a b
48a/*/b => a error("`/*' without matching `*/'.")
49a/*/**/b => a b
50a/b => a error("`/' is only valid as part of `//' or `/*'.") b
51
520 1 12345 18446744073709551615
5318446744073709551616 => error("Decimal constants must be less than 2**64.")
549999999999999999999999 => error("Decimal constants must be less than 2**64.")
5501 => error("Decimal constants must not have leading zeros.")
56
570/0
580/1
591/0 => error("Value contains unmasked 1-bits.")
601/1
61128/384
621/3
631/ => error("Integer constant expected.")
64
651/0x123 => error("Value and mask have incompatible formats.")
66
670x1234
680x01234 => 0x1234
690x0 => 0
700x000 => 0
710xfedcba9876543210
720XFEDCBA9876543210 => 0xfedcba9876543210
730xfedcba9876543210fedcba9876543210
10b1662b
BP
740x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
750x => error("Hex digits expected following 0x.")
760X => error("Hex digits expected following 0X.")
770x0/0x0 => 0/0
780x0/0x1 => 0/0x1
790x1/0x0 => error("Value contains unmasked 1-bits.")
800xffff/0x1ffff
810x. => error("Invalid syntax in hexadecimal constant.")
82
83192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
84256.1.2.3 => error("Invalid numeric constant.")
85192.168.0.0/16
86192.168.0.0/255.255.0.0 => 192.168.0.0/16
87192.168.0.0/255.255.255.0 => 192.168.0.0/24
88192.168.0.0/255.255.0.255
89192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
90192.168.0.0/32
91192.168.0.0/255.255.255.255 => 192.168.0.0/32
52c0fc39 921.2.3.4:5 => 1.2.3.4 : 5
10b1662b
BP
93
94::
95::1
96ff00::1234 => ff00::1234
972001:db8:85a3::8a2e:370:7334
982001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
992001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
100::ffff:192.0.2.128
101::ffff:c000:0280 => ::ffff:192.0.2.128
102::1/::1
103::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
104::1/128
105ff00::/8
106ff00::/ff00:: => ff00::/8
107
10801:23:45:67:ab:cd
10901:23:45:67:AB:CD => 01:23:45:67:ab:cd
110fe:dc:ba:98:76:54
111FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
11201:00:00:00:00:00/01:00:00:00:00:00
113ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
114fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
115ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
116fe:x => error("Invalid numeric constant.")
11700:01:02:03:04:x => error("Invalid numeric constant.")
118
a20c96c6 119# Test that operators are tokenized as expected, even without white space.
52c0fc39 120(){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
10b1662b
BP
121& => error("`&' is only valid as part of `&&'.")
122| => error("`|' is only valid as part of `||'.")
56091efe 123- => error("`-' is only valid as part of `--'.")
10b1662b
BP
124
125^ => error("Invalid character `^' in input.")
126])
127AT_CAPTURE_FILE([input.txt])
128sed 's/ =>.*//' test-cases.txt > input.txt
129sed 's/.* => //' test-cases.txt > expout
130AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
131AT_CLEANUP
e0840f11 132
7700eea0
BP
133dnl The OVN expression parser needs to know what fields overlap with one
134dnl another. This test therefore verifies that all the smaller registers
135dnl are defined as terms of subfields of the larger ones.
136dnl
137dnl When we add or remove registers this test needs to be updated, of course.
138AT_SETUP([ovn -- registers])
139AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
140[[reg0 = xxreg0[96..127]
141reg1 = xxreg0[64..95]
142reg2 = xxreg0[32..63]
143reg3 = xxreg0[0..31]
144reg4 = xxreg1[96..127]
145reg5 = xxreg1[64..95]
146reg6 = xxreg1[32..63]
147reg7 = xxreg1[0..31]
148reg8 = xreg4[32..63]
149reg9 = xreg4[0..31]
150xreg0 = xxreg0[64..127]
151xreg1 = xxreg0[0..63]
152xreg2 = xxreg1[64..127]
153xreg3 = xxreg1[0..63]
154xreg4 = OXM_OF_PKT_REG4
155xxreg0 = NXM_NX_XXREG0
156xxreg1 = NXM_NX_XXREG1
157]])
158AT_CLEANUP
159
2277b860
BP
160dnl Check that the OVN conntrack field definitions are correct.
161AT_SETUP([ovn -- conntrack fields])
162AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
858c2f76
GS
163[[ct.dnat = ct_state[7]
164ct.est = ct_state[1]
2277b860
BP
165ct.inv = ct_state[4]
166ct.new = ct_state[0]
167ct.rel = ct_state[2]
168ct.rpl = ct_state[3]
858c2f76 169ct.snat = ct_state[6]
2277b860
BP
170ct.trk = ct_state[5]
171ct_label = NXM_NX_CT_LABEL
b73db61d 172ct_label.blocked = ct_label[0]
2277b860
BP
173ct_mark = NXM_NX_CT_MARK
174ct_state = NXM_NX_CT_STATE
175]])
176AT_CLEANUP
177
fb8635c5 178AT_SETUP([ovn -- composition])
42d36b58
AZ
179AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
180AT_CLEANUP
181
e0840f11
BP
182AT_SETUP([ovn -- expression parser])
183dnl For lines without =>, input and expected output are identical.
184dnl For lines with =>, input precedes => and expected output follows =>.
185AT_DATA([test-cases.txt], [[
186eth.type == 0x800
187eth.type==0x800 => eth.type == 0x800
188eth.type[0..15] == 0x800 => eth.type == 0x800
189
190vlan.present
191vlan.present == 1 => vlan.present
192!(vlan.present == 0) => vlan.present
193!(vlan.present != 1) => vlan.present
194!vlan.present
195vlan.present == 0 => !vlan.present
196vlan.present != 1 => !vlan.present
197!(vlan.present == 1) => !vlan.present
198!(vlan.present != 0) => !vlan.present
199
200eth.dst[0]
201eth.dst[0] == 1 => eth.dst[0]
202eth.dst[0] != 0 => eth.dst[0]
203!(eth.dst[0] == 0) => eth.dst[0]
204!(eth.dst[0] != 1) => eth.dst[0]
205
206!eth.dst[0]
207eth.dst[0] == 0 => !eth.dst[0]
208eth.dst[0] != 1 => !eth.dst[0]
209!(eth.dst[0] == 1) => !eth.dst[0]
210!(eth.dst[0] != 0) => !eth.dst[0]
211
212vlan.tci[12..15] == 0x3
213vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
214vlan.tci[12..15] != 0x3
215vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
216
217!vlan.pcp => vlan.pcp == 0
218!(vlan.pcp) => vlan.pcp == 0
219vlan.pcp == 0x4
220vlan.pcp != 0x4
221vlan.pcp > 0x4
222vlan.pcp >= 0x4
223vlan.pcp < 0x4
224vlan.pcp <= 0x4
225!(vlan.pcp != 0x4) => vlan.pcp == 0x4
226!(vlan.pcp == 0x4) => vlan.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
2310x4 == vlan.pcp => vlan.pcp == 0x4
2320x4 != vlan.pcp => 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
237!(0x4 != vlan.pcp) => vlan.pcp == 0x4
238!(0x4 == 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
2441 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
2451 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
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
2494 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
2504 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
2514 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
2524 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
253!(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
254!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
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!(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
259!(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
260!(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
261!(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
262
263vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
264vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
265
266vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
267vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
268
269vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
270vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
271vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
272
273ip4.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
274ip6.src == ::1 => ip6.src == 0x1
275
276ip4.src == 1.2.3.4 => ip4.src == 0x1020304
277ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
278ip6.src == ::1 => ip6.src == 0x1
279
2801
2810
282!1 => 0
283!0 => 1
284
285inport == "eth0"
286!(inport != "eth0") => inport == "eth0"
287
474756fc
YS
288(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => 0
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 306$name => Syntax error at `$name' expecting address set name.
3d2848ba 307@name => Syntax error at `@name' expecting port group name.
2c5cbb15 308
e0840f11
BP
309123 == xyzzy => Syntax error at `xyzzy' expecting field name.
310xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311
312inport[1] == 1 => Cannot select subfield of string field inport.
313
314eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
315eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
316eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317
318eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319
320eth.type[5..1] => Invalid bit range 5 to 1.
321
322eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323
324eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325
326eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327
328!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329
330123 => Syntax error at end of input expecting relational operator.
331
332123 x => Syntax error at `x' expecting relational operator.
333
334{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335
336eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337
338(1 x) => Syntax error at `x' expecting `)'.
339
340!0x800 != eth.type => Missing parentheses around operand of !.
341
342eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343
344eth.dst == {} => Syntax error at `}' expecting constant.
345
346eth.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).
347
3b7cb7e1 348ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
e0840f11
BP
349
3501 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
8b34ccda 351
9aef3c1b 352eth.dst[40] x => Syntax error at `x' expecting end of input.
ea382567
RB
353
354ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
355eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
474756fc
YS
356
357((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => Parentheses nested too deeply.
f54c5e59
BP
358
359ct_label > $set4 => Only == and != operators may be used to compare a field against an empty value set.
e0840f11
BP
360]])
361sed 's/ =>.*//' test-cases.txt > input.txt
362sed 's/.* => //' test-cases.txt > expout
363AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
364AT_CLEANUP
365
366AT_SETUP([ovn -- expression annotation])
367dnl Input precedes =>, expected output follows =>.
32157c87 368dnl Empty lines and lines starting with # are ignored.
e0840f11
BP
369AT_DATA([test-cases.txt], [[
370ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
371ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
372ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
32157c87 373ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
e0840f11
BP
374ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
375
32157c87
JS
376# Nested expressions over a single symbol should be annotated with symbol's
377# prerequisites only once, at the top level.
378tcp.dst == 1 || (tcp.dst >= 2 && tcp.dst <= 3) => (tcp.dst == 0x1 || (tcp.dst >= 0x2 && tcp.dst <= 0x3)) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
379
e0840f11
BP
380ip => eth.type == 0x800 || eth.type == 0x86dd
381ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
382ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
383ip > 0 => Only == and != operators may be used with nominal field ip.
384!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
385ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
386
387vlan.present => vlan.tci[12]
388!vlan.present => !vlan.tci[12]
389
390!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
391vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
7700eea0 392!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
e0840f11
BP
393
394ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
395!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
396ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
397
398bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
399self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
400mutual_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'.
401mutual_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'.
402]])
403sed 's/ =>.*//' test-cases.txt > input.txt
404sed 's/.* => //' test-cases.txt > expout
405AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
406AT_CLEANUP
407
9d4aecca 408AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 409AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 410 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
411])
412AT_CLEANUP
413
9d4aecca 414AT_SETUP([ovn -- 2-term expression conversion])
e0840f11 415AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
8c3caa2c 416 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
417])
418AT_CLEANUP
419
9d4aecca 420AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 421AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
8c3caa2c 422 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
423])
424AT_CLEANUP
425
9d4aecca
BP
426AT_SETUP([ovn -- 3-term numeric expression simplification])
427AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
8c3caa2c 428 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
429])
430AT_CLEANUP
431
9d4aecca
BP
432AT_SETUP([ovn -- 4-term string expression simplification])
433AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
434 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
435])
436AT_CLEANUP
437
9d4aecca
BP
438AT_SETUP([ovn -- 3-term mixed expression simplification])
439AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
8c3caa2c 440 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
441])
442AT_CLEANUP
443
97ba1d55
BP
444AT_SETUP([ovn -- simplification special cases])
445simplify() {
446 echo "$1" | ovstest test-ovn simplify-expr
447}
448AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
449])
a3d79068
BP
450AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
451])
33f15d17
BP
452AT_CHECK([simplify 'tcp.dst >= 0'], [0],
453 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
454])
455AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
456 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
457])
458AT_CHECK([simplify 'tcp.dst > 0'], [0],
459 [[(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)
460]])
461AT_CHECK([simplify 'tcp.dst < 65535'], [0],
462 [[(!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)
463]])
97ba1d55
BP
464AT_CLEANUP
465
ba8d3816
MS
466AT_SETUP([ovn -- is_chassis_resident simplification])
467simplify() {
468 echo "$1" | ovstest test-ovn simplify-expr
469}
470AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
471])
472AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
473])
474AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
475])
476AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
477])
478AT_CLEANUP
479
9d4aecca
BP
480AT_SETUP([ovn -- 4-term numeric expression normalization])
481AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
8c3caa2c 482 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
483])
484AT_CLEANUP
485
9d4aecca
BP
486AT_SETUP([ovn -- 4-term string expression normalization])
487AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
488 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
489])
490AT_CLEANUP
491
492AT_SETUP([ovn -- 4-term mixed expression normalization])
493AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
8c3caa2c 494 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
9d4aecca
BP
495])
496AT_CLEANUP
497
498AT_SETUP([ovn -- 5-term numeric expression normalization])
499AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
8c3caa2c 500 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
9d4aecca
BP
501])
502AT_CLEANUP
503
504AT_SETUP([ovn -- 5-term string expression normalization])
505AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
506 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
507])
508AT_CLEANUP
509
510AT_SETUP([ovn -- 5-term mixed expression normalization])
511AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
8c3caa2c 512 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
513])
514AT_CLEANUP
515
516AT_SETUP([ovn -- 4-term numeric expressions to flows])
8c3caa2c 517AT_KEYWORDS([expression])
9d4aecca 518AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
8c3caa2c 519 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
9d4aecca
BP
520])
521AT_CLEANUP
522
523AT_SETUP([ovn -- 4-term string expressions to flows])
8c3caa2c 524AT_KEYWORDS([expression])
9d4aecca
BP
525AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
526 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
527])
528AT_CLEANUP
529
530AT_SETUP([ovn -- 4-term mixed expressions to flows])
8c3caa2c 531AT_KEYWORDS([expression])
9d4aecca 532AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
8c3caa2c 533 [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
534])
535AT_CLEANUP
536
537AT_SETUP([ovn -- 3-term numeric expressions to flows])
8c3caa2c 538AT_KEYWORDS([expression])
9d4aecca 539AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
8c3caa2c 540 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
541])
542AT_CLEANUP
f386a8a7
BP
543
544AT_SETUP([ovn -- converting expressions to flows -- string fields])
8c3caa2c 545AT_KEYWORDS([expression])
f386a8a7
BP
546expr_to_flow () {
547 echo "$1" | ovstest test-ovn expr-to-flows | sort
548}
cc5e28d8 549AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 550])
cc5e28d8 551AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
552])
553AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
554])
555AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
556ip,reg14=0x5
557ipv6,reg14=0x5
f386a8a7
BP
558])
559AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
560ip,reg14=0x6
561ipv6,reg14=0x6
f386a8a7
BP
562])
563AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
564])
565AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
566[reg14=0x5
567reg14=0x6
568reg14=0xfffe
f386a8a7
BP
569])
570AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
571ip,reg14=0x5
572ip,reg14=0x6
573ipv6,reg14=0x5
574ipv6,reg14=0x6
f386a8a7 575])
9d4aecca
BP
576AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
577(no flows)
578])
f386a8a7 579AT_CLEANUP
3b7cb7e1 580
2c5cbb15 581AT_SETUP([ovn -- converting expressions to flows -- address sets])
8c3caa2c 582AT_KEYWORDS([expression])
2c5cbb15
RB
583expr_to_flow () {
584 echo "$1" | ovstest test-ovn expr-to-flows | sort
585}
586AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
587ip,nw_src=10.0.0.1
588ip,nw_src=10.0.0.2
589ip,nw_src=10.0.0.3
590])
591AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
592ip,nw_src=10.0.0.1
593ip,nw_src=10.0.0.2
594ip,nw_src=10.0.0.3
595])
596AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
597ip,nw_src=1.2.3.4
598ip,nw_src=10.0.0.1
599ip,nw_src=10.0.0.2
600ip,nw_src=10.0.0.3
601])
602AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
603ip,nw_src=1.2.0.0/20
604ip,nw_src=10.0.0.1
605ip,nw_src=10.0.0.2
606ip,nw_src=10.0.0.3
607ip,nw_src=5.5.5.0/24
608])
609AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
610ipv6,ipv6_src=::1
611ipv6,ipv6_src=::2
612ipv6,ipv6_src=::3
613])
614AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
615ipv6,ipv6_src=::1
616ipv6,ipv6_src=::2
617ipv6,ipv6_src=::3
618ipv6,ipv6_src=::4
619])
620AT_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
621dl_src=00:00:00:00:00:01
622dl_src=00:00:00:00:00:02
623dl_src=00:00:00:00:00:03
624])
625AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
626dl_src=00:00:00:00:00:01
627dl_src=00:00:00:00:00:02
628dl_src=00:00:00:00:00:03
629])
ea382567
RB
630AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
631dl_src=00:00:00:00:00:01
632dl_src=00:00:00:00:00:02
633dl_src=00:00:00:00:00:03
634dl_src=ba:be:be:ef:de:ad
635])
f3a4e992
HZ
636AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
637(no flows)
638])
639AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
640ip,nw_src=1.2.3.4
641])
642AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
643ip,nw_src=1.2.3.4
644])
645AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
646
647])
648AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
649ip,nw_src=0.0.0.0/1.0.0.0
650ip,nw_src=128.0.0.0/1
651ip,nw_src=16.0.0.0/16.0.0.0
652ip,nw_src=2.0.0.0/2.0.0.0
653ip,nw_src=32.0.0.0/32.0.0.0
654ip,nw_src=4.0.0.0/4.0.0.0
655ip,nw_src=64.0.0.0/64.0.0.0
656ip,nw_src=8.0.0.0/8.0.0.0
657])
658AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
659ip,nw_src=0.0.0.0/1.0.0.0
660ip,nw_src=128.0.0.0/1
661ip,nw_src=16.0.0.0/16.0.0.0
662ip,nw_src=2.0.0.0/2.0.0.0
663ip,nw_src=32.0.0.0/32.0.0.0
664ip,nw_src=4.0.0.0/4.0.0.0
665ip,nw_src=64.0.0.0/64.0.0.0
666ip,nw_src=8.0.0.0/8.0.0.0
667])
2c5cbb15
RB
668AT_CLEANUP
669
3d2848ba
HZ
670AT_SETUP([ovn -- converting expressions to flows -- port groups])
671AT_KEYWORDS([expression])
672expr_to_flow () {
673 echo "$1" | ovstest test-ovn expr-to-flows | sort
674}
675AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
676reg15=0x11
677reg15=0x12
678reg15=0x13
679])
680AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
681(no flows)
682])
683AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
684reg15=0x11
685])
686AT_CLEANUP
687
55b25947
NS
688AT_SETUP([ovn -- converting expressions to flows -- conjunction])
689AT_KEYWORDS([conjunction])
690expr_to_flow () {
691 echo "$1" | ovstest test-ovn expr-to-flows | sort
692}
693
694lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
695ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
696AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
697conj_id=1,ip
698ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
699ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
700ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
701ip,nw_src=10.0.0.1: conjunction(1, 1/2)
702ip,nw_src=10.0.0.2: conjunction(1, 1/2)
703ip,nw_src=10.0.0.3: conjunction(1, 1/2)
704])
705
706lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
707AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
708ct_state=+est+trk,ct_label=0x1/0x1,ip
709ct_state=+est+trk,ct_label=0x1/0x1,ipv6
710ct_state=-est+trk,ip
711ct_state=-est+trk,ipv6
712])
713
714lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
715ip4.dst == {20.0.0.1, 20.0.0.2}"
716AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
717conj_id=1,ip
718ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
719ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
720ip,nw_src=10.0.0.1: conjunction(1, 1/2)
721ip,nw_src=10.0.0.2: conjunction(1, 1/2)
722ip,nw_src=10.0.0.3: conjunction(1, 1/2)
723])
724
725lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
726ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
727tcp.dst >= 1000 && tcp.dst <= 1010"
728
729AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
730conj_id=1,tcp
731tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
732tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
733tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
734tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
735tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
736tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
737tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
738tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
739tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
740tcp,tp_dst=1000: conjunction(1, 2/3)
741tcp,tp_dst=1001: conjunction(1, 2/3)
742tcp,tp_dst=1010: conjunction(1, 2/3)
743])
744
745lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
746((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
747tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
748|| ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
749
750AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
751conj_id=1,tcp
752ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
753ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
754ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
755ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
756ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
757ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
758tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
759tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
760tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
761tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
762tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
763tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
764tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
765tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
766tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
767tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
768tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
769tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
770tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
771tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
772tcp,tp_dst=1000: conjunction(1, 2/4)
773tcp,tp_dst=1001: conjunction(1, 2/4)
774tcp,tp_dst=2000: conjunction(1, 2/4)
775tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
776tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
777tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
778tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
779tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
780tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
781tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
782tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
783tcp,tp_src=1000: conjunction(1, 3/4)
784tcp,tp_src=1001: conjunction(1, 3/4)
785tcp,tp_src=2000: conjunction(1, 3/4)
786])
787AT_CLEANUP
788
3b7cb7e1 789AT_SETUP([ovn -- action parsing])
d5a76da4
BP
790dnl Unindented text is input (a set of OVN logical actions).
791dnl Indented text is expected output.
792AT_DATA([test-cases.txt],
793[[# drop
794drop;
795 encodes as drop
796drop; next;
797 Syntax error at `next' expecting end of input.
798next; drop;
799 Syntax error at `drop' expecting action.
5f822129
BP
800
801# output
d5a76da4
BP
802output;
803 encodes as resubmit(,64)
5f822129
BP
804
805# next
d5a76da4 806next;
00c875d0 807 encodes as resubmit(,19)
d5a76da4 808next(11);
8f5de083 809 formats as next;
00c875d0 810 encodes as resubmit(,19)
d5a76da4 811next(0);
00c875d0
MS
812 encodes as resubmit(,8)
813next(23);
d5a76da4
BP
814 encodes as resubmit(,31)
815
816next();
4c99cb18 817 Syntax error at `)' expecting "pipeline" or "table".
d5a76da4
BP
818next(10;
819 Syntax error at `;' expecting `)'.
00c875d0
MS
820next(24);
821 "next" action cannot advance beyond table 23.
5f822129 822
4c99cb18
BP
823next(table=11);
824 formats as next;
00c875d0 825 encodes as resubmit(,19)
4c99cb18
BP
826next(pipeline=ingress);
827 formats as next;
00c875d0 828 encodes as resubmit(,19)
4c99cb18
BP
829next(table=11, pipeline=ingress);
830 formats as next;
00c875d0 831 encodes as resubmit(,19)
4c99cb18
BP
832next(pipeline=ingress, table=11);
833 formats as next;
00c875d0 834 encodes as resubmit(,19)
4c99cb18
BP
835
836next(pipeline=egress);
837 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
838
839next(table=10);
840 formats as next(10);
00c875d0 841 encodes as resubmit(,18)
4c99cb18 842
5f822129 843# Loading a constant value.
d5a76da4
BP
844tcp.dst=80;
845 formats as tcp.dst = 80;
846 encodes as set_field:80->tcp_dst
847 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
848eth.dst[40] = 1;
849 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
850vlan.pcp = 2;
851 encodes as set_field:0x4000/0xe000->vlan_tci
852 has prereqs vlan.tci[12]
853vlan.tci[13..15] = 2;
854 encodes as set_field:0x4000/0xe000->vlan_tci
855inport = "";
856 encodes as set_field:0->reg14
857ip.ttl=4;
858 formats as ip.ttl = 4;
859 encodes as set_field:4->nw_ttl
860 has prereqs eth.type == 0x800 || eth.type == 0x86dd
861outport="eth0"; next; outport="LOCAL"; next;
8f5de083 862 formats as outport = "eth0"; next; outport = "LOCAL"; next;
00c875d0 863 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
d5a76da4
BP
864
865inport[1] = 1;
866 Cannot select subfield of string field inport.
867ip.proto[1] = 1;
868 Cannot select subfield of nominal field ip.proto.
869eth.dst[40] == 1;
870 Syntax error at `==' expecting `=' or `<->'.
871ip = 1;
872 Predicate symbol ip used where lvalue required.
873ip.proto = 6;
874 Field ip.proto is not modifiable.
875inport = {"a", "b"};
876 Syntax error at `{' expecting constant.
877inport = {};
878 Syntax error at `{' expecting constant.
879bad_prereq = 123;
880 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
881self_recurse = 123;
882 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'.
883vlan.present = 0;
884 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
885
886# Moving one field into another.
d5a76da4
BP
887reg0=reg1;
888 formats as reg0 = reg1;
889 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
890vlan.pcp = reg0[0..2];
891 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
892 has prereqs vlan.tci[12]
893reg0[10] = vlan.pcp[1];
894 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
895 has prereqs vlan.tci[12]
896outport = inport;
897 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
898
899reg0[0] = vlan.present;
900 Predicate symbol vlan.present used where lvalue required.
901reg0 = reg1[0..10];
902 Can't assign 11-bit value to 32-bit destination.
903inport = reg0;
904 Can't assign integer field (reg0) to string field (inport).
905inport = big_string;
906 String fields inport and big_string are incompatible for assignment.
907ip.proto = reg0[0..7];
908 Field ip.proto is not modifiable.
5f822129
BP
909
910# Exchanging fields.
d5a76da4
BP
911reg0 <-> reg1;
912 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]
913vlan.pcp <-> reg0[0..2];
914 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]
915 has prereqs vlan.tci[12]
916reg0[10] <-> vlan.pcp[1];
917 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
918 has prereqs vlan.tci[12]
919outport <-> inport;
920 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
921
922reg0[0] <-> vlan.present;
923 Predicate symbol vlan.present used where lvalue required.
924reg0 <-> reg1[0..10];
925 Can't exchange 32-bit field with 11-bit field.
926inport <-> reg0;
927 Can't exchange string field (inport) with integer field (reg0).
928inport <-> big_string;
929 String fields inport and big_string are incompatible for exchange.
930ip.proto <-> reg0[0..7];
931 Field ip.proto is not modifiable.
932reg0[0..7] <-> ip.proto;
933 Field ip.proto is not modifiable.
5f822129
BP
934
935# TTL decrement.
d5a76da4
BP
936ip.ttl--;
937 encodes as dec_ttl
938 has prereqs ip
939ip.ttl
940 Syntax error at end of input expecting `--'.
5f822129 941
467085fd 942# load balancing.
d5a76da4 943ct_lb;
00c875d0 944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
945 has prereqs ip
946ct_lb();
947 formats as ct_lb;
00c875d0 948 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
949 has prereqs ip
950ct_lb(192.168.1.2:80, 192.168.1.3:80);
951 encodes as group:1
952 has prereqs ip
953ct_lb(192.168.1.2, 192.168.1.3, );
954 formats as ct_lb(192.168.1.2, 192.168.1.3);
955 encodes as group:2
956 has prereqs ip
9d236afa
MM
957ct_lb(fd0f::2, fd0f::3, );
958 formats as ct_lb(fd0f::2, fd0f::3);
959 encodes as group:3
960 has prereqs ip
d5a76da4
BP
961
962ct_lb(192.168.1.2:);
963 Syntax error at `)' expecting port number.
964ct_lb(192.168.1.2:123456);
965 Syntax error at `123456' expecting port number.
966ct_lb(foo);
9d236afa
MM
967 Syntax error at `foo' expecting IP address.
968ct_lb([192.168.1.2]);
969 Syntax error at `192.168.1.2' expecting IPv6 address.
d5a76da4
BP
970
971# ct_next
972ct_next;
00c875d0 973 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
d5a76da4
BP
974 has prereqs ip
975
976# ct_commit
977ct_commit;
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
979 has prereqs ip
980ct_commit();
981 formats as ct_commit;
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
983 has prereqs ip
984ct_commit(ct_mark=1);
985 formats as ct_commit(ct_mark=0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
987 has prereqs ip
988ct_commit(ct_mark=1/1);
989 formats as ct_commit(ct_mark=0x1/0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
991 has prereqs ip
992ct_commit(ct_label=1);
993 formats as ct_commit(ct_label=0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
995 has prereqs ip
996ct_commit(ct_label=1/1);
997 formats as ct_commit(ct_label=0x1/0x1);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
999 has prereqs ip
1000ct_commit(ct_mark=1, ct_label=2);
1001 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
1002 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
1003 has prereqs ip
1004
1005ct_commit(ct_label=0x01020304050607080910111213141516);
1006 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1008 has prereqs ip
1009ct_commit(ct_label=0x181716151413121110090807060504030201);
1010 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1011 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1012 has prereqs ip
1013ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1015 has prereqs ip
1016ct_commit(ct_label=18446744073709551615);
1017 formats as ct_commit(ct_label=0xffffffffffffffff);
1018 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1019 has prereqs ip
1020ct_commit(ct_label=18446744073709551616);
1021 Decimal constants must be less than 2**64.
1022
1023# ct_dnat
1024ct_dnat;
00c875d0 1025 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
d5a76da4
BP
1026 has prereqs ip
1027ct_dnat(192.168.1.2);
00c875d0 1028 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
d5a76da4
BP
1029 has prereqs ip
1030
1031ct_dnat(192.168.1.2, 192.168.1.3);
1032 Syntax error at `,' expecting `)'.
1033ct_dnat(foo);
1034 Syntax error at `foo' expecting IPv4 address.
1035ct_dnat(foo, bar);
1036 Syntax error at `foo' expecting IPv4 address.
1037ct_dnat();
1038 Syntax error at `)' expecting IPv4 address.
1039
1040# ct_snat
1041ct_snat;
00c875d0 1042 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
d5a76da4
BP
1043 has prereqs ip
1044ct_snat(192.168.1.2);
00c875d0 1045 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
d5a76da4
BP
1046 has prereqs ip
1047
1048ct_snat(192.168.1.2, 192.168.1.3);
1049 Syntax error at `,' expecting `)'.
1050ct_snat(foo);
1051 Syntax error at `foo' expecting IPv4 address.
1052ct_snat(foo, bar);
1053 Syntax error at `foo' expecting IPv4 address.
1054ct_snat();
1055 Syntax error at `)' expecting IPv4 address.
de297547 1056
db0e819b
BP
1057# ct_clear
1058ct_clear;
1059 encodes as ct_clear
1060
b3bd2c33 1061# clone
8f5de083 1062clone { ip4.dst = 255.255.255.255; output; }; next;
00c875d0 1063 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
b3bd2c33
BP
1064 has prereqs eth.type == 0x800
1065
6335d074 1066# arp
8a41ad8e
BP
1067arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1068 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
d5a76da4 1069 has prereqs ip4
bac29564
BP
1070arp { };
1071 formats as arp { drop; };
1072 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1073 has prereqs ip4
6335d074 1074
0bac7164 1075# get_arp
d5a76da4
BP
1076get_arp(outport, ip4.dst);
1077 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[]
1078 has prereqs eth.type == 0x800
1079get_arp(inport, reg0);
1080 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[]
1081
1082get_arp;
1083 Syntax error at `;' expecting `('.
1084get_arp();
1085 Syntax error at `)' expecting field name.
1086get_arp(inport);
1087 Syntax error at `)' expecting `,'.
1088get_arp(inport ip4.dst);
1089 Syntax error at `ip4.dst' expecting `,'.
1090get_arp(inport, ip4.dst;
1091 Syntax error at `;' expecting `)'.
1092get_arp(inport, eth.dst);
1093 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1094get_arp(inport, outport);
1095 Cannot use string field outport where numeric field is required.
1096get_arp(reg0, ip4.dst);
1097 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
1098
1099# put_arp
d5a76da4
BP
1100put_arp(inport, arp.spa, arp.sha);
1101 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[]
1102 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 1103
42814145 1104# put_dhcp_opts
d5a76da4
BP
1105reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1106 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)
6f016174
MM
1107reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org",wpad="https://example.org");
1108 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", wpad = "https://example.org");
1109 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.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67,pause)
d5a76da4
BP
1110reg0[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);
1111 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);
1112 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)
1113
1114reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1115 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1116reg1[0] = put_dhcp_opts();
1117 put_dhcp_opts requires offerip to be specified.
1118reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1119 Syntax error at `x' expecting DHCPv4 option name.
1120reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1121 put_dhcp_opts requires offerip to be specified.
1122reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1123 Syntax error at `"hi"'.
1124reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1125 Syntax error at `xyzzy' expecting DHCPv4 option name.
1126reg1[0] = put_dhcp_opts(offerip="xyzzy");
1127 DHCPv4 option offerip requires numeric value.
1128reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1129 DHCPv4 option domain requires string value.
42814145 1130
b1a3a6a4
NS
1131# nd_ns
1132nd_ns { nd.target = xxreg0; output; };
1133 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1134 has prereqs ip6
1135
1136nd_ns { };
1137 formats as nd_ns { drop; };
1138 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1139 has prereqs ip6
1140
f8a8db39 1141# nd_na
d5a76da4
BP
1142nd_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; };
1143 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1144 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)
1145 has prereqs nd_ns
c9756229
NS
1146# nd_na_router
1147nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1148 formats as nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1149 encodes as controller(userdata=00.00.00.0c.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)
1150 has prereqs nd_ns
e75451fe 1151
c34a87b6 1152# get_nd
d5a76da4
BP
1153get_nd(outport, ip6.dst);
1154 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[]
1155 has prereqs eth.type == 0x86dd
1156get_nd(inport, xxreg0);
1157 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[]
1158get_nd;
1159 Syntax error at `;' expecting `('.
1160get_nd();
1161 Syntax error at `)' expecting field name.
1162get_nd(inport);
1163 Syntax error at `)' expecting `,'.
1164get_nd(inport ip6.dst);
1165 Syntax error at `ip6.dst' expecting `,'.
1166get_nd(inport, ip6.dst;
1167 Syntax error at `;' expecting `)'.
1168get_nd(inport, eth.dst);
1169 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1170get_nd(inport, outport);
1171 Cannot use string field outport where numeric field is required.
1172get_nd(xxreg0, ip6.dst);
1173 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
1174
1175# put_nd
d5a76da4
BP
1176put_nd(inport, nd.target, nd.sll);
1177 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[]
32157c87 1178 has prereqs (icmp6.type == 0x87 || 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 1179
01cfdb2f 1180# put_dhcpv6_opts
d5a76da4 1181reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
a55dacac 1182 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
1183reg1[0] = put_dhcpv6_opts();
1184 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1185reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1186 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
a55dacac 1187 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
1188reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1189 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
a55dacac 1190 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 1191reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
a55dacac 1192 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
1193reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1194 Syntax error at `x' expecting DHCPv6 option name.
1195reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1196 Syntax error at `"hi"'.
1197reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1198 Syntax error at `xyzzy' expecting DHCPv6 option name.
1199reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1200 DHCPv6 option ia_addr requires numeric value.
1201reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1202 DHCPv6 option domain_search requires string value.
01cfdb2f 1203
a6095f81
BS
1204# set_queue
1205set_queue(0);
1206 encodes as set_queue:0
1207set_queue(61440);
1208 encodes as set_queue:61440
1209set_queue(65535);
1210 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1211
ea991ad2
NS
1212# dns_lookup
1213reg1[0] = dns_lookup();
1214 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1215 has prereqs udp
1216reg1[0] = dns_lookup("foo");
1217 dns_lookup doesn't take any parameters
1218
66d89287
GL
1219# set_meter
1220set_meter(0);
1221 Rate 0 for set_meter is not in valid.
1222set_meter(1);
1223 encodes as meter:1
1224set_meter(100, 1000);
1225 encodes as meter:2
1226set_meter(100, 1000, );
1227 Syntax error at `,' expecting `)'.
1228set_meter(4294967295, 4294967295);
1229 encodes as meter:3
1230
977433d8
JP
1231# log
1232log(verdict=allow, severity=warning);
1233 encodes as controller(userdata=00.00.00.07.00.00.00.00.00.04)
1234log(name="test1", verdict=drop, severity=info);
1235 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31)
1236log(verdict=drop, severity=info, meter="meter1");
1237 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06,meter_id=4)
1238log(name="test1", verdict=drop, severity=info, meter="meter1");
1239 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31,meter_id=4)
1240log(verdict=drop);
1241 formats as log(verdict=drop, severity=info);
1242 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06)
1243log(verdict=bad_verdict, severity=info);
1244 Syntax error at `bad_verdict' unknown verdict.
1245log(verdict=drop, severity=bad_severity);
1246 Syntax error at `bad_severity' unknown severity.
1247log(severity=notice);
1248 Syntax error at `;' expecting verdict.
1249
52ed5fcc
NS
1250# put_nd_ra_opts
1251reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1252 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
1253 has prereqs ip6
1254reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1255 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
1256 has prereqs ip6
1257reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1258 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
1259 has prereqs ip6
1260reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1261 slla option not present
1262reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1263 prefix option can't be set when address mode is dhcpv6_stateful.
1264reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1265 prefix option can't be set when address mode is dhcpv6_stateful.
1266reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1267 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1268reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1269 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1270reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1271 Syntax error at `dhcpv6_stateless' expecting constant.
1272reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1273 Invalid value for "prefix" option
1274reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1275 Invalid value for "addr_mode" option
1276reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1277 IPv6 ND RA option mtu requires numeric value.
1278reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1279 Invalid value for "mtu" option
1280
bc3d6a63
LB
1281# icmp4
1282icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1283 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1284 has prereqs ip4
1285
1286icmp4 { };
1287 formats as icmp4 { drop; };
1288 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1289 has prereqs ip4
1290
3e7fa1e3
LB
1291# icmp6
1292icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1293 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1294 has prereqs ip6
1295
1296icmp6 { };
1297 formats as icmp6 { drop; };
1298 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1299 has prereqs ip6
1300
22b65e4d
LB
1301# tcp_reset
1302tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1303 encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1304 has prereqs tcp
1305
1306tcp_reset { };
1307 formats as tcp_reset { drop; };
1308 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1309 has prereqs tcp
1310
5f822129 1311# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
1312ip4.src = ip6.src[0..31];
1313 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1314 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1315ip4.src <-> ip6.src[0..31];
1316 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[]
1317 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1318
1319# Miscellaneous negative tests.
1320;
1321 Syntax error at `;'.
1322xyzzy;
1323 Syntax error at `xyzzy' expecting action.
1324next; 123;
1325 Syntax error at `123'.
1326next; xyzzy;
1327 Syntax error at `xyzzy' expecting action.
1328next
9aef3c1b 1329 Syntax error at end of input expecting `;'.
3b7cb7e1 1330]])
d5a76da4
BP
1331sed '/^[[ ]]/d' test-cases.txt > input.txt
1332cp test-cases.txt expout
3b7cb7e1
BP
1333AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1334AT_CLEANUP
f295c17b
BP
1335
1336AT_BANNER([OVN end-to-end tests])
1337
9975d7be
BP
1338# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1339AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1340AT_KEYWORDS([ovnarp])
f295c17b
BP
1341AT_SKIP_IF([test $HAVE_PYTHON = no])
1342ovn_start
1343
1344# Create hypervisors hv[123].
9975d7be 1345# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1346# Add all of the vifs to a single logical switch lsw0.
1347# Turn on port security on all the vifs except vif[123]1.
1348# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1349# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1350ovn-nbctl ls-add lsw0
f295c17b
BP
1351net_add n1
1352for i in 1 2 3; do
1353 sim_add hv$i
1354 as hv$i
1355 ovs-vsctl add-br br-phys
1356 ovn_attach n1 br-phys 192.168.0.$i
1357
1358 for j in 1 2 3; do
1359 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 1360 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1361 if test $j = 1; then
31ed1192 1362 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1363 else
7dc88496
NS
1364 if test $j = 3; then
1365 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1366 else
1367 ip_addrs="192.168.0.$i$j"
1368 fi
31ed1192
JP
1369 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1370 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1371 fi
1372 done
1373done
1374ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1375ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1376ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1377ovn-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\"
1378ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b 1379
3d2848ba
HZ
1380get_lsp_uuid () {
1381 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1382}
1383
1384ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1385ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1386
f295c17b
BP
1387# Pre-populate the hypervisors' ARP tables so that we don't lose any
1388# packets for ARP resolution (native tunneling doesn't queue packets
1389# for ARP resolution).
74868f2c 1390OVN_POPULATE_ARP
f295c17b
BP
1391
1392# Allow some time for ovn-northd and ovn-controller to catch up.
1393# XXX This should be more systematic.
1394sleep 1
611099dc 1395
fc6f9978
HZ
1396# Make sure there is no attempt to adding duplicated flows by ovn-controller
1397AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1398AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1399AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1400
57d143eb
HZ
1401# Given the name of a logical port, prints the name of the hypervisor
1402# on which it is located.
1403vif_to_hv() {
1404 echo hv${1%?}
1405}
1406
f295c17b
BP
1407# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1408#
1409# This shell function causes a packet to be received on INPORT. The packet's
1410# content has Ethernet destination DST and source SRC (each exactly 12 hex
1411# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1412# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1413# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1414for i in 1 2 3; do
1415 for j in 1 2 3; do
1416 : > $i$j.expected
1417 done
1418done
1419test_packet() {
1420 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1421 hv=`vif_to_hv $inport`
f295c17b
BP
1422 vif=vif$inport
1423 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1424 for outport; do
e4543cfe 1425 echo $packet >> $outport.expected
f295c17b
BP
1426 done
1427}
1428
57d143eb
HZ
1429# test_arp INPORT SHA SPA TPA [REPLY_HA]
1430#
1431# Causes a packet to be received on INPORT. The packet is an ARP
1432# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1433# it should be the hardware address of the target to expect to receive in an
1434# ARP reply; otherwise no reply is expected.
1435#
31ed1192 1436# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1437# SHA and REPLY_HA are each 12 hex digits.
1438# SPA and TPA are each 8 hex digits.
1439test_arp() {
1440 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1441 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1442 hv=`vif_to_hv $inport`
1443 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1444
92f9822b 1445 if test X$reply_ha = X; then
57d143eb
HZ
1446 # Expect to receive the broadcast ARP on the other logical switch ports
1447 # if no reply is expected.
1448 local i j
1449 for i in 1 2 3; do
1450 for j in 1 2 3; do
1451 if test $i$j != $inport; then
1452 echo $request >> $i$j.expected
1453 fi
1454 done
1455 done
1456 else
1457 # Expect to receive the reply, if any.
1458 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1459 echo $reply >> $inport.expected
1460 fi
1461}
1462
1463ip_to_hex() {
1464 printf "%02x%02x%02x%02x" "$@"
1465}
1466
f295c17b
BP
1467# Send packets between all pairs of source and destination ports:
1468#
31ed1192
JP
1469# 1. Unicast packets are delivered to exactly one logical switch port
1470# (except that packets destined to their input ports are dropped).
f295c17b 1471#
31ed1192
JP
1472# 2. Broadcast and multicast are delivered to all logical switch ports
1473# except the input port.
f295c17b 1474#
ea46a4e9 1475# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1476# MAC address.
1477#
ea46a4e9 1478# 4. The switch drops all packets with a VLAN tag.
f295c17b 1479#
ea46a4e9 1480# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1481# affects behavior when port security is turned off, since otherwise port
1482# security would drop the packet anyway.)
1483#
ea46a4e9 1484# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1485# switch ports with "unknown" among their MAC addresses (and port
1486# security disabled).
f295c17b 1487#
ea46a4e9 1488# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1489#
ea46a4e9 1490# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1491#
9fcb6a18
BP
1492# 9. OVN generates responses to ARP requests for known IPs, except for
1493# requests from a port for the port's own IP.
57d143eb
HZ
1494#
1495# 10. No response to ARP requests for unknown IPs.
4acd1e87 1496
f295c17b
BP
1497for is in 1 2 3; do
1498 for js in 1 2 3; do
1499 s=$is$js
1500 bcast=
4d5c43d5
JP
1501 unknown=
1502 bacl2=
1503 bacl3=
f295c17b
BP
1504 for id in 1 2 3; do
1505 for jd in 1 2 3; do
1506 d=$id$jd
1507
1508 if test $d != $s; then unicast=$d; else unicast=; fi
1509 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1510
1511 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1512 impersonate=$d
1513 else
1514 impersonate=
1515 fi
f295c17b
BP
1516 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1517
4d5c43d5
JP
1518 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1519 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1520 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1521 # Source of 11, 21, or 31 and dest of 33 should be dropped
1522 # due to the 4th ACL that uses address_set(set1).
1523 acl4=
1524 else
1525 acl4=$d
1526 fi
3d2848ba
HZ
1527 if test $d = $s || test $d = 22 || test $d = 33; then
1528 # dest of 22 and 33 should be dropped
1529 # due to the 5th ACL that uses port_group(pg1).
1530 acl5=
1531 else
1532 acl5=$d
1533 fi
f295c17b
BP
1534 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1535 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1536 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1537 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
3d2848ba 1538 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
f295c17b
BP
1539
1540 test_packet $s f000000000$d f00000000055 810000091234 #4
1541 test_packet $s f000000000$d 0100000000$s $s$d #5
1542
4d5c43d5
JP
1543 if test $d != $s && test $jd = 1; then
1544 unknown="$unknown $d"
1545 fi
f295c17b
BP
1546 bcast="$bcast $unicast"
1547 bacl2="$bacl2 $acl2"
1548 bacl3="$bacl3 $acl3"
57d143eb 1549
db02f370 1550 sip=`ip_to_hex 192 168 0 $is$js`
57d143eb
HZ
1551 tip=`ip_to_hex 192 168 0 $id$jd`
1552 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1553 if test $d != $s; then
1554 reply_ha=f000000000$d
1555 else
1556 reply_ha=
1557 fi
1558 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1559 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1560
1561 if test $jd = 3; then
31ed1192 1562 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1563 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1564 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1565 fi
f295c17b
BP
1566 done
1567 done
1568
4d5c43d5 1569 # Broadcast and multicast.
f295c17b
BP
1570 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1571 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1572 if test $js = 1; then
f295c17b
BP
1573 bcast_impersonate=$bcast
1574 else
4d5c43d5
JP
1575 bcast_impersonate=
1576 fi
f295c17b
BP
1577 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1578
1579 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1580
1581 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1582 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1583 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1584 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1585 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1586 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1587 done
1588done
1589
7dc88496
NS
1590# set address for lp13 with invalid characters.
1591# lp13 should be configured with only 192.168.0.13.
31ed1192 1592ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1593
1594# Allow some time for ovn-northd and ovn-controller to catch up.
1595# XXX This should be more systematic.
1596sleep 1
1597
7dc88496
NS
1598sip=`ip_to_hex 192 168 0 11`
1599tip=`ip_to_hex 192 168 0 13`
1600test_arp 11 f00000000011 $sip $tip f00000000013
1601
1602tip=`ip_to_hex 192 169 0 13`
1603#arp request for 192.169.0.13 should be flooded
1604test_arp 11 f00000000011 $sip $tip
1605
91125642 1606# dump information and flows with counters
bb0c41d3
RM
1607ovn-sbctl dump-flows -- list multicast_group
1608
1609echo "------ hv1 dump ------"
1610as hv1 ovs-vsctl show
1611as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1612
1613echo "------ hv2 dump ------"
1614as hv2 ovs-vsctl show
1615as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1616
1617echo "------ hv3 dump ------"
1618as hv3 ovs-vsctl show
1619as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1620
f295c17b
BP
1621# Now check the packets actually received against the ones expected.
1622for i in 1 2 3; do
1623 for j in 1 2 3; do
49d7c759 1624 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1625 done
1626done
fcde56f5 1627
7a8f15e0 1628OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1629
f295c17b 1630AT_CLEANUP
eb6b08eb 1631
4acd1e87
BP
1632AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1633AT_SKIP_IF([test $HAVE_PYTHON = no])
1634ovn_start
1635
1636# Create a logical switch and some logical ports.
1637# Turn on port security on all lports except ls1.
1638# Make ls1 a destination for unknown MACs.
1639# Add some ACLs for Ethertypes 1234, 1235, 1236.
1640ovn-nbctl ls-add lsw0
1641ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1642for i in 1 2 3; do
1643 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1644done
1645ovn-nbctl --wait=sb sync
1646for i in 1 2 3; do
4acd1e87
BP
1647 ovn-sbctl lsp-bind lp$i hv0
1648 if test $i = 1; then
abb37b6b 1649 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1650 else
abb37b6b
FF
1651 if test $i = 3; then
1652 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1653 else
1654 ip_addrs="192.168.0.$i"
1655 fi
a8e2addc
LR
1656 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1657 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
4acd1e87
BP
1658 fi
1659done
1660ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1661ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1662ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1663ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1664ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1665
1666ovn-nbctl --wait=sb sync
1667on_exit 'kill `cat ovn-trace.pid`'
1668ovn-trace --detach --pidfile --no-chdir
1669
1670# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1671#
1672# This shell function causes a packet to be received on INPORT. The packet's
1673# content has Ethernet destination DST and source SRC (each exactly 12 hex
1674# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1675# more) list the VIFs on which the packet should be received. INPORT and the
1676# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1677test_packet() {
1678 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1679 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1680 while :; do
abb37b6b
FF
1681 case $1 in # (
1682 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1683 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1684 *) break ;;
1685 esac
4acd1e87
BP
1686 done
1687 for outport; do
abb37b6b 1688 echo "output(\"lp$outport\");"
4acd1e87
BP
1689 done > expout
1690
1691 AT_CAPTURE_FILE([trace])
1692 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1693}
1694
1695# test_arp INPORT SHA SPA TPA [REPLY_HA]
1696#
1697# Causes a packet to be received on INPORT. The packet is an ARP
1698# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1699# it should be the hardware address of the target to expect to receive in an
1700# ARP reply; otherwise no reply is expected.
1701#
1702# INPORT is an logical switch port number, e.g. 11 for vif11.
1703# SHA and REPLY_HA are each 12 hex digits.
1704# SPA and TPA are each 8 hex digits.
1705test_arp() {
1706 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1707
1708 local request="inport == \"lp$inport\"
1709 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1710 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1711 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1712
1713 if test -z "$reply_ha"; then
1714 reply=
abb37b6b
FF
1715 local i
1716 for i in 1 2 3; do
1717 if test $i != $inport; then
1718 reply="${reply}output(\"lp$i\");
4acd1e87 1719"
abb37b6b
FF
1720 fi
1721 done
4acd1e87
BP
1722 else
1723 reply="\
1724eth.dst = $sha;
1725eth.src = $reply_ha;
1726arp.op = 2;
1727arp.tha = $sha;
1728arp.sha = $reply_ha;
1729arp.tpa = $spa;
1730arp.spa = $tpa;
1731output(\"lp$inport\");
1732"
1733 fi
1734
1735 AT_CAPTURE_FILE([trace])
1736 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1737}
1738
1739# Send packets between all pairs of source and destination ports:
1740#
1741# 1. Unicast packets are delivered to exactly one logical switch port
1742# (except that packets destined to their input ports are dropped).
1743#
1744# 2. Broadcast and multicast are delivered to all logical switch ports
1745# except the input port.
1746#
1747# 3. When port security is turned on, the switch drops packets from the wrong
1748# MAC address.
1749#
1750# 4. The switch drops all packets with a VLAN tag.
1751#
1752# 5. The switch drops all packets with a multicast source address. (This only
1753# affects behavior when port security is turned off, since otherwise port
1754# security would drop the packet anyway.)
1755#
1756# 6. The switch delivers packets with an unknown destination to logical
1757# switch ports with "unknown" among their MAC addresses (and port
1758# security disabled).
1759#
1760# 7. The switch drops unicast packets that violate an ACL.
1761#
1762# 8. The switch drops multicast and broadcast packets that violate an ACL.
1763#
9fcb6a18
BP
1764# 9. OVN generates responses to ARP requests for known IPs, except for
1765# requests from a port for the port's own IP.
4acd1e87
BP
1766#
1767# 10. No response to ARP requests for unknown IPs.
1768
1769for s in 1 2 3; do
1770 bcast=
1771 unknown=
1772 bacl2=
1773 bacl3=
1774 for d in 1 2 3; do
abb37b6b
FF
1775 echo
1776 echo "lp$s -> lp$d"
1777 if test $d != $s; then unicast=$d; else unicast=; fi
1778 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1779
1780 if test $d != $s && test $s = 1; then
1781 impersonate=$d
1782 else
1783 impersonate=
1784 fi
1785 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1786
1787 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1788 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1789 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1790 # Source of 1 or 2 and dest of 3 should be dropped
1791 # due to the 4th ACL that uses address_set(set1).
1792 acl4=
1793 else
1794 acl4=$d
1795 fi
1796
1797 #7, acl1 to acl4:
1798 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1799 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1800 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1801 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1802
1803 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1804 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1805
1806 if test $d != $s && test $d = 1; then
1807 unknown="$unknown $d"
1808 fi
1809 bcast="$bcast $unicast"
1810 bacl2="$bacl2 $acl2"
1811 bacl3="$bacl3 $acl3"
1812
1813 sip=192.168.0.$s
1814 tip=192.168.0.$d
1815 tip_unknown=11.11.11.11
9fcb6a18
BP
1816 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1817 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1818 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1819
1820 if test $d = 3; then
1821 # lp3 has an additional ip 192.169.0.[123]3.
1822 tip=192.169.0.$d
9fcb6a18 1823 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1824 fi
4acd1e87
BP
1825 done
1826
1827 # Broadcast and multicast.
1828 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1829 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1830 if test $s = 1; then
abb37b6b 1831 bcast_impersonate=$bcast
4acd1e87 1832 else
abb37b6b 1833 bcast_impersonate=
4acd1e87
BP
1834 fi
1835 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1836
1837 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1838
1839 #8, acl1 to acl3:
1840 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1841 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1842 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1843
1844 #8, acl1 to acl3:
1845 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1846 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1847 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1848done
1849
1850AT_CLEANUP
1851
7277bc83
RB
1852# 2 hypervisors, 4 logical ports per HV
1853# 2 locally attached networks (one flat, one vlan tagged over same device)
1854# 2 ports per HV on each network
e90aeb57 1855AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1856AT_SKIP_IF([test $HAVE_PYTHON = no])
1857ovn_start
1858
ea46a4e9
JP
1859# In this test cases we create 3 switches, all connected to same
1860# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1861# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1862# of VIF port name indicates the hypervisor it is bound to, e.g.
1863# lp23 means VIF 3 on hv2.
1864#
ea46a4e9 1865# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1866# - ls1:
1867# - untagged
ea46a4e9 1868# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1869#
1870# - ls2:
1871# - tagged with VLAN 101
ea46a4e9 1872# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1873# - ls3:
1874# - untagged
ea46a4e9 1875# - ports: lp15, lp25
0ee7f7f1 1876#
ea46a4e9 1877# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1878# physical network.
1879
1880for i in 1 2 3; do
ea46a4e9
JP
1881 ls_name=ls$i
1882 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1883 ln_port_name=ln$i
1884 if test $i -eq 2; then
ea46a4e9 1885 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1886 else
ea46a4e9 1887 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1888 fi
31ed1192
JP
1889 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1890 ovn-nbctl lsp-set-type $ln_port_name localnet
1891 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1892done
d79fc5f4 1893
69b72264
BP
1894# lsp_to_ls LSP
1895#
1896# Prints the name of the logical switch that contains LSP.
1897lsp_to_ls () {
1898 case $1 in dnl (
5a0e4aec
BP
1899 lp?[[12]]) echo ls1 ;; dnl (
1900 lp?[[34]]) echo ls2 ;; dnl (
1901 lp?5) echo ls3 ;; dnl (
1902 *) AT_FAIL_IF([:]) ;;
69b72264
BP
1903 esac
1904}
1905
d79fc5f4
RB
1906net_add n1
1907for i in 1 2; do
1908 sim_add hv$i
1909 as hv$i
1910 ovs-vsctl add-br br-phys
1911 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1912 ovn_attach n1 br-phys 192.168.0.$i
1913
0ee7f7f1 1914 for j in 1 2 3 4 5; do
d79fc5f4
RB
1915 ovs-vsctl add-port br-int vif$i$j -- \
1916 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1917 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1918 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1919 ofport-request=$i$j
1920
31ed1192 1921 lsp_name=lp$i$j
5a0e4aec 1922 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 1923
ea46a4e9 1924 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1925 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1926 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1927
31ed1192 1928 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1929 done
1930done
69b72264
BP
1931ovn-nbctl --wait=sb sync
1932ovn-sbctl dump-flows
d79fc5f4 1933
74868f2c 1934OVN_POPULATE_ARP
d79fc5f4
RB
1935
1936# XXX This is now the 3rd copy of these functions in this file ...
1937
1938# Given the name of a logical port, prints the name of the hypervisor
1939# on which it is located.
1940vif_to_hv() {
1941 echo hv${1%?}
1942}
1943#
69b72264 1944# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
1945#
1946# This shell function causes a packet to be received on INPORT. The packet's
1947# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
1948# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1949# logical switch port numbers, e.g. 11 for vif11.
1950#
1951# EOUT is the end-to-end output port, that is, where the packet will end up
1952# after possibly bouncing through one or more localnet ports. LOUT is the
1953# logical output port, which might be a localnet port, as seen by ovn-trace
1954# (which doesn't know what localnet ports are connected to and therefore can't
1955# figure out the end-to-end answer).
d79fc5f4 1956for i in 1 2; do
0ee7f7f1 1957 for j in 1 2 3 4 5; do
d79fc5f4
RB
1958 : > $i$j.expected
1959 done
1960done
1961test_packet() {
69b72264
BP
1962 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1963 echo "$@"
1964
1965 # First try tracing the packet.
1966 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1967 if test $lout != drop; then
1968 echo "output(\"$lout\");"
1969 fi > expout
1970 AT_CAPTURE_FILE([trace])
1971 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1972
1973 # Then actually send a packet, for an end-to-end test.
1974 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
1975 hv=`vif_to_hv $inport`
1976 vif=vif$inport
1977 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
1978 if test $eout != drop; then
1979 echo $packet >> ${eout#lp}.expected
1980 fi
d79fc5f4
RB
1981}
1982
7277bc83
RB
1983# lp11 and lp21 are on the same network (phys, untagged)
1984# and on different hypervisors
69b72264
BP
1985test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1986test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 1987
7277bc83
RB
1988# lp11 and lp12 are on the same network (phys, untagged)
1989# and on the same hypervisor
69b72264
BP
1990test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1991test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
1992
1993# lp13 and lp23 are on the same network (phys, VLAN 101)
1994# and on different hypervisors
69b72264
BP
1995test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1996test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
1997
1998# lp13 and lp14 are on the same network (phys, VLAN 101)
1999# and on the same hypervisor
69b72264
BP
2000test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
2001test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 2002
0ee7f7f1 2003# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 2004# same hypervisor, and on different switches
69b72264
BP
2005test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2006test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
2007
2008# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 2009# different hypervisors, and on different switches
69b72264
BP
2010test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2011test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 2012
d79fc5f4 2013# Ports that should not be able to communicate
69b72264
BP
2014test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2015test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2016test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2017test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2018test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2019test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2020test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2021test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 2022
d79fc5f4
RB
2023# Dump a bunch of info helpful for debugging if there's a failure.
2024
2025echo "------ OVN dump ------"
2026ovn-nbctl show
2027ovn-sbctl show
2028
2029echo "------ hv1 dump ------"
2030as hv1 ovs-vsctl show
2031as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2032
2033echo "------ hv2 dump ------"
2034as hv2 ovs-vsctl show
2035as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2036
2037# Now check the packets actually received against the ones expected.
2038for i in 1 2; do
0ee7f7f1 2039 for j in 1 2 3 4 5; do
49d7c759 2040 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
2041 done
2042done
2043
7a8f15e0 2044OVN_CLEANUP([hv1],[hv2])
d9c8c57c 2045
d79fc5f4
RB
2046AT_CLEANUP
2047
91125642
FF
2048AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2049AT_KEYWORDS([vtep])
eb6b08eb
JP
2050AT_SKIP_IF([test $HAVE_PYTHON = no])
2051ovn_start
2052
2053# Configure the Northbound database
ea46a4e9 2054ovn-nbctl ls-add lsw0
eb6b08eb 2055
31ed1192
JP
2056ovn-nbctl lsp-add lsw0 lp1
2057ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 2058
31ed1192
JP
2059ovn-nbctl lsp-add lsw0 lp2
2060ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 2061
31ed1192
JP
2062ovn-nbctl lsp-add lsw0 lp-vtep
2063ovn-nbctl lsp-set-type lp-vtep vtep
2064ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2065ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 2066
77adbb62
DB
2067# lpr, lr and lrp1 are used for the ARP request handling test only.
2068ovn-nbctl lsp-add lsw0 lpr
2069ovn-nbctl lr-add lr
2070ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2071ovn-nbctl set Logical_Switch_Port lpr type=router \
2072 options:router-port=lrp1 \
2073 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2074
2075
eb6b08eb
JP
2076net_add n1 # Network to connect hv1, hv2, and vtep
2077net_add n2 # Network to connect vtep and hv3
2078
2079# Create hypervisor hv1 connected to n1
2080sim_add hv1
2081as hv1
2082ovs-vsctl add-br br-phys
2083ovn_attach n1 br-phys 192.168.0.1
2084ovs-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
2085
2086# Create hypervisor hv2 connected to n1
2087sim_add hv2
2088as hv2
2089ovs-vsctl add-br br-phys
2090ovn_attach n1 br-phys 192.168.0.2
2091ovs-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
2092
2093
2094# Start the vtep emulator with a leg in both networks
2095sim_add vtep
2096as vtep
2097
2098ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2099ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2100
2101ovs-vsctl add-br br-phys
2102net_attach n1 br-phys
2103
2104mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2105arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2106ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2107ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2108
2109ovs-vsctl add-br br-vtep
2110net_attach n2 br-vtep
2111
2112vtep-ctl add-ps br-vtep
2113vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2114vtep-ctl add-ls lsw0
2115
2116start_daemon ovs-vtep br-vtep
2117start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2118
8cdc4312 2119OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 2120
475f0a2c
DB
2121OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2122 grep -- source`"])
2123# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
2124sleep 1
2125
2126# Add hv3 on the other side of the vtep
2127sim_add hv3
2128as hv3
2129ovs-vsctl add-br br-phys
2130net_attach n2 br-phys
2131
2132ovs-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
2133
2134# Pre-populate the hypervisors' ARP tables so that we don't lose any
2135# packets for ARP resolution (native tunneling doesn't queue packets
2136# for ARP resolution).
74868f2c 2137OVN_POPULATE_ARP
eb6b08eb
JP
2138
2139# Allow some time for ovn-northd and ovn-controller to catch up.
2140# XXX This should be more systematic.
2141sleep 1
6977df72 2142
eb6b08eb
JP
2143# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2144#
2145# This shell function causes a packet to be received on INPORT. The packet's
2146# content has Ethernet destination DST and source SRC (each exactly 12 hex
2147# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2148# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2149# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
2150for i in 1 2 3; do
2151 : > $i.expected
2152done
2153test_packet() {
2154 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2155 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2156 hv=hv$inport
2157 vif=vif$inport
2158 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2159 for outport; do
e4543cfe 2160 echo $packet >> $outport.expected
eb6b08eb
JP
2161 done
2162}
2163
2164# Send packets between all pairs of source and destination ports:
2165#
31ed1192
JP
2166# 1. Unicast packets are delivered to exactly one logical switch port
2167# (except that packets destined to their input ports are dropped).
eb6b08eb 2168#
31ed1192
JP
2169# 2. Broadcast and multicast are delivered to all logical switch ports
2170# except the input port.
eb6b08eb 2171#
ea46a4e9 2172# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
2173# switch ports with "unknown" among their MAC addresses (and port
2174# security disabled).
eb6b08eb
JP
2175for s in 1 2 3; do
2176 bcast=
2177 unknown=
2178 for d in 1 2 3; do
2179 if test $d != $s; then unicast=$d; else unicast=; fi
2180 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2181
2182 # The vtep (vif3) is the only one configured for "unknown"
2183 if test $d != $s && test $d = 3; then
2184 unknown="$unknown $d"
2185 fi
2186 bcast="$bcast $unicast"
2187 done
2188
2189 # Broadcast and multicast.
46ed1382
DB
2190 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2191 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
2192
2193 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2194done
2195
77adbb62
DB
2196# ARP request should not be responded to by logical switch router
2197# type arp responder on HV1 and HV2 and should reach directly to
2198# vif1 and vif2
2199ip_to_hex() {
2200 printf "%02x%02x%02x%02x" "$@"
2201}
2202sha=f00000000003
2203spa=`ip_to_hex 192 168 1 2`
2204tpa=`ip_to_hex 192 168 1 1`
2205request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2206as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2207echo $request >> 1.expected
2208echo $request >> 2.expected
2209
bb0c41d3
RM
2210# dump information with counters
2211echo "------ OVN dump ------"
2212ovn-nbctl show
2213ovn-sbctl show
2214
77adbb62
DB
2215echo "---------SB dump-----"
2216ovn-sbctl list datapath_binding
2217echo "---------------------"
2218ovn-sbctl list port_binding
2219echo "---------------------"
2220ovn-sbctl dump-flows
2221
bb0c41d3
RM
2222echo "------ hv1 dump ------"
2223as hv1 ovs-vsctl show
6195e2e7 2224as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2225as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2226
2227echo "------ hv2 dump ------"
2228as hv2 ovs-vsctl show
6195e2e7 2229as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2230as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2231
2232echo "------ hv3 dump ------"
2233as hv3 ovs-vsctl show
6754e92d
FF
2234# note: hv3 has no logical port bind, thus it should not have br-int
2235AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2236[ovs-ofctl: br-int is not a bridge or a socket
2237])
bb0c41d3 2238
eb6b08eb
JP
2239# Now check the packets actually received against the ones expected.
2240for i in 1 2 3; do
49d7c759 2241 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 2242done
fcde56f5
LR
2243
2244# Gracefully terminate daemons
7a8f15e0
LR
2245OVN_CLEANUP([hv1],[hv2],[vtep])
2246OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 2247
eb6b08eb 2248AT_CLEANUP
9975d7be 2249
184bc3ca
RB
2250# Similar test to "hardware GW"
2251AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2252AT_SKIP_IF([test $HAVE_PYTHON = no])
2253ovn_start
2254
2255# Configure the Northbound database
2256ovn-nbctl ls-add lsw0
2257
2258ovn-nbctl lsp-add lsw0 lp1
2259ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2260
2261ovn-nbctl lsp-add lsw0 lp2
2262ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2263
2264ovn-nbctl lsp-add lsw0 lp-gw
2265ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 2266ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
2267ovn-nbctl lsp-set-addresses lp-gw unknown
2268
2269net_add n1 # Network to connect hv1, hv2, and gw
2270net_add n2 # Network to connect gw and hv3
2271
2272# Create hypervisor hv1 connected to n1
2273sim_add hv1
2274as hv1
2275ovs-vsctl add-br br-phys
2276ovn_attach n1 br-phys 192.168.0.1
2277ovs-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
2278
2279# Create hypervisor hv2 connected to n1
2280sim_add hv2
2281as hv2
2282ovs-vsctl add-br br-phys
2283ovn_attach n1 br-phys 192.168.0.2
2284ovs-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
2285
2286# Create hypervisor hv_gw connected to n1 and n2
2287# connect br-phys bridge to n1; connect hv-gw bridge to n2
2288sim_add hv_gw
2289as hv_gw
2290ovs-vsctl add-br br-phys
2291ovn_attach n1 br-phys 192.168.0.3
2292ovs-vsctl add-br br-phys2
2293net_attach n2 br-phys2
2294ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2295
184bc3ca
RB
2296# Add hv3 on the other side of the GW
2297sim_add hv3
2298as hv3
2299ovs-vsctl add-br br-phys
2300net_attach n2 br-phys
2301ovs-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
2302
2303
2304# Pre-populate the hypervisors' ARP tables so that we don't lose any
2305# packets for ARP resolution (native tunneling doesn't queue packets
2306# for ARP resolution).
74868f2c 2307OVN_POPULATE_ARP
184bc3ca
RB
2308
2309# Allow some time for ovn-northd and ovn-controller to catch up.
2310# XXX This should be more systematic.
2311sleep 1
2312
2313# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2314#
2315# This shell function causes a packet to be received on INPORT. The packet's
2316# content has Ethernet destination DST and source SRC (each exactly 12 hex
2317# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2318# more) list the VIFs on which the packet should be received. INPORT and the
2319# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
2320for i in 1 2 3; do
2321 : > $i.expected
2322done
2323test_packet() {
2324 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2325 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2326 hv=hv$inport
2327 vif=vif$inport
2328 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2329 for outport; do
e4543cfe 2330 echo $packet >> $outport.expected
184bc3ca
RB
2331 done
2332}
2333
2334# Send packets between all pairs of source and destination ports:
2335#
2336# 1. Unicast packets are delivered to exactly one lport (except that packets
2337# destined to their input ports are dropped).
2338#
2339# 2. Broadcast and multicast are delivered to all lports except the input port.
2340#
2341# 3. The lswitch delivers packets with an unknown destination to lports with
2342# "unknown" among their MAC addresses (and port security disabled).
2343for s in 1 2 3 ; do
2344 bcast=
2345 unknown=
2346 for d in 1 2 3 ; do
2347 if test $d != $s; then unicast=$d; else unicast=; fi
2348 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2349
2350 # The vtep (vif3) is the only one configured for "unknown"
2351 if test $d != $s && test $d = 3; then
2352 unknown="$unknown $d"
2353 fi
2354 bcast="$bcast $unicast"
2355 done
2356
2357 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2358 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2359 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2360done
2361
184bc3ca
RB
2362echo "------ ovn-nbctl show ------"
2363ovn-nbctl show
2364echo "------ ovn-sbctl show ------"
2365ovn-sbctl show
2366
2367echo "------ hv1 ------"
2368as hv1 ovs-vsctl show
2369echo "------ hv1 br-int ------"
2370as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2371echo "------ hv1 br-phys ------"
2372as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2373
2374echo "------ hv2 ------"
2375as hv2 ovs-vsctl show
2376echo "------ hv2 br-int ------"
2377as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2378echo "------ hv2 br-phys ------"
2379as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2380
2381echo "------ hv_gw ------"
2382as hv_gw ovs-vsctl show
2383echo "------ hv_gw br-phys ------"
2384as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2385echo "------ hv_gw br-phys2 ------"
2386as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2387
2388echo "------ hv3 ------"
2389as hv3 ovs-vsctl show
2390echo "------ hv3 br-phys ------"
2391as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2392
2393# Now check the packets actually received against the ones expected.
2394for i in 1 2 3; do
49d7c759 2395 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2396done
2397AT_CLEANUP
2398
9975d7be
BP
2399# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2400AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2401AT_SKIP_IF([test $HAVE_PYTHON = no])
2402ovn_start
2403
2404# Logical network:
2405#
2406# Three logical switches ls1, ls2, ls3.
86e98048
BP
2407# One logical router lr0 connected to ls[123],
2408# with nine subnets, three per logical switch:
2409#
2410# lrp11 on ls1 for subnet 192.168.11.0/24
2411# lrp12 on ls1 for subnet 192.168.12.0/24
2412# lrp13 on ls1 for subnet 192.168.13.0/24
2413# ...
2414# lrp33 on ls3 for subnet 192.168.33.0/24
2415#
2416# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2417# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2418for i in 1 2 3; do
ea46a4e9 2419 ovn-nbctl ls-add ls$i
9975d7be 2420 for j in 1 2 3; do
86e98048 2421 for k in 1 2 3; do
31ed1192
JP
2422 # Add "unknown" to MAC addresses for lp?11, so packets for
2423 # MAC-IP bindings discovered via ARP later have somewhere to go.
2424 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2425
2426 ovn-nbctl \
2427 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
2428 -- lsp-set-addresses lp$i$j$k \
2429 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
86e98048
BP
2430 done
2431 done
2432done
2433
fa2a27b2 2434ovn-nbctl lr-add lr0
86e98048
BP
2435for i in 1 2 3; do
2436 for j in 1 2 3; do
bf44c2cd 2437 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2438 ovn-nbctl \
31ed1192 2439 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2440 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2441 options:router-port=lrp$i$j \
86e98048 2442 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2443 done
2444done
2445
80f408f4 2446ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2447 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2448
9975d7be
BP
2449# Physical network:
2450#
2451# Three hypervisors hv[123].
86e98048
BP
2452# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2453# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2454# lp?3[123] all on hv3.
2455
9975d7be
BP
2456
2457# Given the name of a logical port, prints the name of the hypervisor
2458# on which it is located.
2459vif_to_hv() {
2460 case $1 in dnl (
86e98048
BP
2461 ?11) echo 1 ;; dnl (
2462 ?12 | ?21 | ?22) echo 2 ;; dnl (
2463 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2464 esac
2465}
2466
86e98048
BP
2467# Given the name of a logical port, prints the name of its logical router
2468# port, e.g. "vif_to_lrp 123" yields 12.
2469vif_to_lrp() {
2470 echo ${1%?}
2471}
2472
2473# Given the name of a logical port, prints the name of its logical
2474# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2475vif_to_ls() {
86e98048 2476 echo ${1%??}
e3393e3f
BP
2477}
2478
9975d7be
BP
2479net_add n1
2480for i in 1 2 3; do
2481 sim_add hv$i
2482 as hv$i
2483 ovs-vsctl add-br br-phys
2484 ovn_attach n1 br-phys 192.168.0.$i
2485done
2486for i in 1 2 3; do
2487 for j in 1 2 3; do
86e98048 2488 for k in 1 2 3; do
269ecccc
JP
2489 hv=`vif_to_hv $i$j$k`
2490 as hv$hv ovs-vsctl \
2491 -- add-port br-int vif$i$j$k \
2492 -- set Interface vif$i$j$k \
2493 external-ids:iface-id=lp$i$j$k \
2494 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2495 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2496 ofport-request=$i$j$k
86e98048 2497 done
9975d7be
BP
2498 done
2499done
2500
2501# Pre-populate the hypervisors' ARP tables so that we don't lose any
2502# packets for ARP resolution (native tunneling doesn't queue packets
2503# for ARP resolution).
74868f2c 2504OVN_POPULATE_ARP
9975d7be
BP
2505
2506# Allow some time for ovn-northd and ovn-controller to catch up.
2507# XXX This should be more systematic.
2508sleep 1
2509
e3393e3f 2510# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2511#
2512# This shell function causes a packet to be received on INPORT. The packet's
2513# content has Ethernet destination DST and source SRC (each exactly 12 hex
2514# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2515# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2516# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2517for i in 1 2 3; do
2518 for j in 1 2 3; do
86e98048
BP
2519 for k in 1 2 3; do
2520 : > $i$j$k.expected
269ecccc 2521 done
9975d7be
BP
2522 done
2523done
e3393e3f 2524test_ip() {
9975d7be
BP
2525 # This packet has bad checksums but logical L3 routing doesn't check.
2526 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2527 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2528 shift; shift; shift; shift; shift
2529 hv=hv`vif_to_hv $inport`
2530 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2531 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2532 in_ls=`vif_to_ls $inport`
2533 in_lrp=`vif_to_lrp $inport`
9975d7be 2534 for outport; do
269ecccc 2535 out_ls=`vif_to_ls $outport`
86e98048 2536 if test $in_ls = $out_ls; then
9975d7be
BP
2537 # Ports on the same logical switch receive exactly the same packet.
2538 echo $packet
2539 else
2540 # Routing decrements TTL and updates source and dest MAC
2541 # (and checksum).
269ecccc 2542 out_lrp=`vif_to_lrp $outport`
86e98048 2543 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2544 fi >> $outport.expected
9975d7be
BP
2545 done
2546}
2547
d7abfe39
LB
2548# test_arp INPORT SHA SPA TPA [REPLY_HA]
2549#
2550# Causes a packet to be received on INPORT. The packet is an ARP
2551# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2552# it should be the hardware address of the target to expect to receive in an
2553# ARP reply; otherwise no reply is expected.
2554#
2555# INPORT is an logical switch port number, e.g. 11 for vif11.
2556# SHA and REPLY_HA are each 12 hex digits.
2557# SPA and TPA are each 8 hex digits.
2558test_arp() {
2559 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2560 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2561 hv=hv`vif_to_hv $inport`
2562 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2563 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2564
2565 # Expect to receive the broadcast ARP on the other logical switch ports if
2566 # IP address is not configured to the switch patch port.
2567 local i=`vif_to_ls $inport`
2568 local j k
2569 for j in 1 2 3; do
2570 for k in 1 2 3; do
2571 # 192.168.33.254 is configured to the switch patch port for lrp33,
2572 # so no ARP flooding expected for it.
2573 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2574 echo $request >> $i$j$k.expected
2575 fi
2576 done
2577 done
2578
2579 # Expect to receive the reply, if any.
2580 if test X$reply_ha != X; then
2581 lrp=`vif_to_lrp $inport`
2582 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2583 echo $reply >> $inport.expected
2584 fi
2585}
2586
e3393e3f 2587as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2588as hv1 ovn-sbctl list port_binding
2589as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2590as hv1 ovn-sbctl dump-flows
2591as hv1 ovs-ofctl dump-flows br-int
2592
e3393e3f 2593# Send IP packets between all pairs of source and destination ports:
9975d7be 2594#
31ed1192
JP
2595# 1. Unicast IP packets are delivered to exactly one logical switch port
2596# (except that packets destined to their input ports are dropped).
9975d7be 2597#
31ed1192
JP
2598# 2. Broadcast IP packets are delivered to all logical switch ports
2599# except the input port.
86e98048
BP
2600ip_to_hex() {
2601 printf "%02x%02x%02x%02x" "$@"
2602}
9975d7be 2603for is in 1 2 3; do
269ecccc
JP
2604 for js in 1 2 3; do
2605 for ks in 1 2 3; do
2606 bcast=
2607 s=$is$js$ks
2608 smac=f00000000$s
2609 sip=`ip_to_hex 192 168 $is$js $ks`
2610 for id in 1 2 3; do
2611 for jd in 1 2 3; do
2612 for kd in 1 2 3; do
2613 d=$id$jd$kd
2614 dip=`ip_to_hex 192 168 $id$jd $kd`
2615 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2616 if test $d != $s; then unicast=$d; else unicast=; fi
2617
2618 test_ip $s $smac $dmac $sip $dip $unicast #1
2619
2620 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2621 done
2622 done
9975d7be 2623 done
269ecccc
JP
2624 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2625 done
2626 done
e3393e3f
BP
2627done
2628
d7abfe39
LB
2629: > mac_bindings.expected
2630
0bac7164
BP
2631# 3. Send an IP packet from every logical port to every other subnet,
2632# to an IP address that does not have a static IP-MAC binding.
2633# This should generate a broadcast ARP request for the destination
2634# IP address in the destination subnet.
d7abfe39 2635# Moreover generate an ARP reply for each of the IP addresses ARPed
0bac7164 2636for is in 1 2 3; do
269ecccc
JP
2637 for js in 1 2 3; do
2638 for ks in 1 2 3; do
2639 s=$is$js$ks
2640 smac=f00000000$s
2641 sip=`ip_to_hex 192 168 $is$js $ks`
2642 for id in 1 2 3; do
2643 for jd in 1 2 3; do
2644 if test $is$js = $id$jd; then
2645 continue
2646 fi
2647
2648 # Send the packet.
2649 dmac=00000000ff$is$js
2650 # Calculate a 4th octet for the destination that is
2651 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2652 # that have static MAC bindings, and fits in the range
2653 # 0-255.
2654 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2655 dip=`ip_to_hex 192 168 $id$jd $o4`
2656 test_ip $s $smac $dmac $sip $dip
2657
2658 # Every LP on the destination subnet's lswitch should
2659 # receive the ARP request.
2660 lrmac=00000000ff$id$jd
2661 lrip=`ip_to_hex 192 168 $id$jd 254`
2662 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2663 for jd2 in 1 2 3; do
2664 for kd in 1 2 3; do
e4543cfe 2665 echo $arp >> $id$jd2$kd.expected
0bac7164 2666 done
269ecccc 2667 done
d7abfe39
LB
2668 if test $(vif_to_hv ${is}${js}${ks}) = $(vif_to_hv ${id}${jd}1); then
2669 hmac=8000000000$o4
2670 rmac=00000000ff$id$jd
2671 echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
2672 fi
2673
2674 host_mac=8000000000$o4
2675 lrmac=00000000ff$id$jd
2676
2677 arp_reply=${lrmac}${host_mac}08060001080006040002${host_mac}${dip}${lrmac}${lrip}
2678
2679 hv=hv`vif_to_hv ${id}${jd}1`
2680 as $hv ovs-appctl netdev-dummy/receive vif${id}${jd}1 $arp_reply
2681
2682 host_ip_pretty=192.168.$id$jd.$o4
2683 host_mac_pretty=80:00:00:00:00:$o4
2684 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
0bac7164 2685 done
269ecccc 2686 done
0bac7164 2687 done
269ecccc 2688 done
0bac7164
BP
2689done
2690
e3393e3f
BP
2691# Test router replies to ARP requests from all source ports:
2692#
0bac7164 2693# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2694#
0bac7164 2695# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2696# in its subnet.
2697#
054008ad 2698# 6. No reply to query for IP address other than router IP.
e3393e3f 2699#
054008ad 2700# 7. No reply to query from another subnet.
e3393e3f 2701for i in 1 2 3; do
269ecccc
JP
2702 for j in 1 2 3; do
2703 for k in 1 2 3; do
2704 smac=f00000000$i$j$k # Source MAC
2705 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2706 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2707 rmac=00000000ff$i$j # Router MAC
2708 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
054008ad
HZ
2709 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2710
2711 test_arp $i$j$k $smac $sip $rip $rmac #4
2712 test_arp $i$j$k $smac $otherip $rip $rmac #5
2713 test_arp $i$j$k $smac $sip $otherip #6
2714
2715 # When rip is 192.168.33.254, ARP request from externalip won't be
2716 # filtered, because 192.168.33.254 is configured to switch peer port
2717 # for lrp33.
2718 lrp33_rsp=
2719 if test $i = 3 && test $j = 3; then
2720 lrp33_rsp=$rmac
2721 fi
2722 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2723
b0684540
HZ
2724 # MAC binding should be learned from ARP request.
2725 host_mac_pretty=f0:00:00:00:0$i:$j$k
2726
2727 host_ip_pretty=192.168.$i$j.$k
2728 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2729
2730 # mac_binding is learned and overwritten so only the last one remains.
2731 if test $k = 3; then
2732 # lrp33 will not learn from ARP request, because 192.168.33.254 is
2733 # configured to switch peer port for lrp33.
2734 if test $i != 3 || test $j != 3; then
2735 host_ip_pretty=192.168.$i$j.55
2736 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2737 fi
2738 fi
2739
0bac7164 2740 done
269ecccc 2741 done
0bac7164
BP
2742done
2743
0bac7164 2744
9975d7be
BP
2745# Allow some time for packet forwarding.
2746# XXX This can be improved.
2747sleep 1
2748
d7abfe39 2749# 8. Send an IP packet from every logical port to every other subnet. These
0bac7164
BP
2750# are the same packets already sent as #3, but now the destinations' IP-MAC
2751# bindings have been discovered via ARP, so instead of provoking an ARP
2752# request, these packets now get routed to their destinations (which don't
2753# have static MAC bindings, so they go to the port we've designated as
2754# accepting "unknown" MACs.)
2755for is in 1 2 3; do
269ecccc
JP
2756 for js in 1 2 3; do
2757 for ks in 1 2 3; do
2758 s=$is$js$ks
2759 smac=f00000000$s
2760 sip=`ip_to_hex 192 168 $is$js $ks`
2761 for id in 1 2 3; do
2762 for jd in 1 2 3; do
2763 if test $is$js = $id$jd; then
2764 continue
2765 fi
2766
2767 # Send the packet.
2768 dmac=00000000ff$is$js
2769 # Calculate a 4th octet for the destination that is
2770 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2771 # that have static MAC bindings, and fits in the range
2772 # 0-255.
2773 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2774 dip=`ip_to_hex 192 168 $id$jd $o4`
2775 test_ip $s $smac $dmac $sip $dip
2776
2777 # Expect the packet egress.
2778 host_mac=8000000000$o4
2779 outport=${id}11
2780 out_lrp=$id$jd
e4543cfe 2781 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2782 done
269ecccc 2783 done
0bac7164 2784 done
269ecccc 2785 done
0bac7164
BP
2786done
2787
0bac7164
BP
2788ovn-sbctl -f csv -d bare --no-heading \
2789 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2790
9975d7be
BP
2791# Now check the packets actually received against the ones expected.
2792for i in 1 2 3; do
2793 for j in 1 2 3; do
86e98048 2794 for k in 1 2 3; do
abb37b6b
FF
2795 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2796 [$i$j$k.expected])
86e98048 2797 done
9975d7be
BP
2798 done
2799done
fcde56f5 2800
0bac7164
BP
2801# Check the MAC bindings against those expected.
2802AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2803])
2804
fcde56f5 2805# Gracefully terminate daemons
7a8f15e0 2806OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2807
9975d7be 2808AT_CLEANUP
685f4dfe 2809
b0684540
HZ
2810AT_SETUP([ovn -- IP relocation using GARP request])
2811AT_SKIP_IF([test $HAVE_PYTHON = no])
2812ovn_start
2813
2814# Logical network:
2815#
2816# Two logical switches ls1, ls2.
2817# One logical router lr0 connected to ls[12],
2818# with 2 subnets, 1 per logical switch:
2819#
2820# lrp1 on ls1 for subnet 192.168.1.1/24
2821# lrp2 on ls2 for subnet 192.168.2.1/24
2822#
2823# 4 VIFs, 2 per LS lp[12][12], first digit being LS.
2824# VIFs' fixed IP addresses are 192.168.[12].1[12].
2825#
2826# There is a secondary IP 192.168.1.100 that is unknown in NB and learned
2827# through ARP only, and it can move between lp11 and lp12.
2828#
2829ovn-nbctl lr-add lr0
2830for i in 1 2 ; do
2831 ovn-nbctl ls-add ls$i
2832 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
2833 ovn-nbctl \
2834 -- lsp-add ls$i lrp$i-attachment \
2835 -- set Logical_Switch_Port lrp$i-attachment type=router \
2836 options:router-port=lrp$i \
2837 addresses=router
2838 for j in 1 2; do
2839 ovn-nbctl \
2840 -- lsp-add ls$i lp$i$j \
2841 -- lsp-set-addresses lp$i$j \
2842 "f0:00:00:00:00:$i$j 192.168.$i.1$j"
2843 done
2844done
2845
2846# Physical network:
2847# 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
2848
2849# Given the name of a logical port, prints the name of the hypervisor
2850# on which it is located, e.g. "vif_to_hv 12" yields 2.
2851vif_to_hv() {
2852 echo ${1#?}
2853}
2854
2855# Given the name of a logical port, prints the name of its logical router
2856# port, e.g. "vif_to_lrp 12" yields 1.
2857vif_to_lrp() {
2858 echo ${1%?}
2859}
2860
2861# Given the name of a logical port, prints the name of its logical
2862# switch, e.g. "vif_to_ls 12" yields 1.
2863vif_to_ls() {
2864 echo ${1%?}
2865}
2866
2867net_add n1
2868for i in 1 2; do
2869 sim_add hv$i
2870 as hv$i
2871 ovs-vsctl add-br br-phys
2872 ovn_attach n1 br-phys 192.168.0.$i
2873done
2874for i in 1 2; do
2875 for j in 1 2; do
2876 hv=`vif_to_hv $i$j`
2877 as hv$hv ovs-vsctl \
2878 -- add-port br-int vif$i$j \
2879 -- set Interface vif$i$j \
2880 external-ids:iface-id=lp$i$j \
2881 options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
2882 options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
2883 ofport-request=$i$j
2884 done
2885done
2886
2887# Pre-populate the hypervisors' ARP tables so that we don't lose any
2888# packets for ARP resolution (native tunneling doesn't queue packets
2889# for ARP resolution).
2890OVN_POPULATE_ARP
2891
2892# Allow some time for ovn-northd and ovn-controller to catch up.
2893# XXX This should be more systematic.
2894sleep 1
2895
2896# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2897#
2898# This shell function causes a packet to be received on INPORT. The packet's
2899# content has Ethernet destination DST and source SRC (each exactly 12 hex
2900# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2901# more) list the VIFs on which the packet should be received. INPORT and the
2902# OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
2903for i in 1 2; do
2904 for j in 1 2; do
2905 : > $i$j.expected
2906 done
2907done
2908test_ip() {
2909 # This packet has bad checksums but logical L3 routing doesn't check.
2910 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2911 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2912 shift; shift; shift; shift; shift
2913 hv=hv`vif_to_hv $inport`
2914 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2915 in_ls=`vif_to_ls $inport`
2916 in_lrp=`vif_to_lrp $inport`
2917 for outport; do
2918 out_ls=`vif_to_ls $outport`
2919 if test $in_ls = $out_ls; then
2920 # Ports on the same logical switch receive exactly the same packet.
2921 echo $packet
2922 else
2923 # Routing decrements TTL and updates source and dest MAC
2924 # (and checksum).
2925 out_lrp=`vif_to_lrp $outport`
2926 echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2927 fi >> $outport.expected
2928 done
2929}
2930
2931# test_arp INPORT SHA SPA TPA [REPLY_HA]
2932#
2933# Causes a packet to be received on INPORT. The packet is an ARP
2934# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2935# it should be the hardware address of the target to expect to receive in an
2936# ARP reply; otherwise no reply is expected.
2937#
2938# INPORT is an logical switch port number, e.g. 11 for vif11.
2939# SHA and REPLY_HA are each 12 hex digits.
2940# SPA and TPA are each 8 hex digits.
2941test_arp() {
2942 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2943 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2944 hv=hv`vif_to_hv $inport`
2945 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2946
2947 # Expect to receive the broadcast ARP on the other logical switch ports if
2948 # IP address is not configured to the switch patch port.
2949 local i=`vif_to_ls $inport`
2950 local j
2951 for j in 1 2; do
2952 if test $i$j != $inport; then
2953 echo $request >> $i$j$k.expected
2954 fi
2955 done
2956
2957 # Expect to receive the reply, if any.
2958 if test X$reply_ha != X; then
2959 lrp=`vif_to_lrp $inport`
2960 local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2961 echo $reply >> $inport.expected
2962 fi
2963}
2964
2965ip_to_hex() {
2966 printf "%02x%02x%02x%02x" "$@"
2967}
2968
2969# lp11 send GARP request to announce ownership of 192.168.1.100.
2970
2971sha=f00000000011
2972spa=`ip_to_hex 192 168 1 100`
2973tpa=$spa
2974test_arp 11 $sha $spa $tpa
2975OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
2976ovn-nbctl --wait=hv sync
2977
2978# Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
2979
2980smac=f00000000021
2981dmac=00000000ff02
2982sip=`ip_to_hex 192 168 2 11`
2983dip=`ip_to_hex 192 168 1 100`
2984test_ip 21 $smac $dmac $sip $dip 11
2985
2986# lp12 send GARP request to announce ownership of 192.168.1.100.
2987
2988sha=f00000000012
2989test_arp 12 $sha $spa $tpa
2990OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
2991ovn-nbctl --wait=hv sync
2992
2993# Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
2994
2995test_ip 21 $smac $dmac $sip $dip 12
2996
2997# Now check the packets actually received against the ones expected.
2998for i in 1 2; do
2999 for j in 1 2; do
3000 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
3001 [$i$j.expected])
3002 done
3003done
3004
3005# Gracefully terminate daemons
3006OVN_CLEANUP([hv1], [hv2])
3007
3008AT_CLEANUP
3009
685f4dfe
NS
3010# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
3011AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
3012AT_SKIP_IF([test $HAVE_PYTHON = no])
3013ovn_start
3014
3015# Create hypervisors hv[123].
3016# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
3017# Add all of the vifs to a single logical switch lsw0.
3018# Turn off port security on vifs vif[123]1
3019# Turn on l2 port security on vifs vif[123]2
3020# Turn of l2 and l3 port security on vifs vif[123]3
3021# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 3022ovn-nbctl ls-add lsw0
685f4dfe
NS
3023net_add n1
3024for i in 1 2 3; do
3025 sim_add hv$i
3026 as hv$i
3027 ovs-vsctl add-br br-phys
3028 ovn_attach n1 br-phys 192.168.0.$i
3029
3030 for j in 1 2 3; do
3031 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 3032 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 3033 if test $j = 1; then
31ed1192 3034 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 3035 elif test $j = 2; then
31ed1192
JP
3036 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
3037 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
3038 else
3039 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
3040 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3041 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
3042 fi
3043 done
3044done
3045
685f4dfe
NS
3046# Pre-populate the hypervisors' ARP tables so that we don't lose any
3047# packets for ARP resolution (native tunneling doesn't queue packets
3048# for ARP resolution).
74868f2c 3049OVN_POPULATE_ARP
685f4dfe
NS
3050
3051# Allow some time for ovn-northd and ovn-controller to catch up.
3052# XXX This should be more systematic.
3053sleep 1
685f4dfe
NS
3054
3055# Given the name of a logical port, prints the name of the hypervisor
3056# on which it is located.
3057vif_to_hv() {
3058 echo hv${1%?}
3059}
3060
685f4dfe
NS
3061for i in 1 2 3; do
3062 for j in 1 2 3; do
3063 : > $i$j.expected
3064 done
3065done
3066
3067# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3068#
3069# This shell function causes an ip packet to be received on INPORT.
3070# The packet's content has Ethernet destination DST and source SRC
3071# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
3072# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
3073# be received. INPORT and the OUTPORTs are specified as logical switch
3074# port numbers, e.g. 11 for vif11.
685f4dfe
NS
3075test_ip() {
3076 # This packet has bad checksums but logical L3 routing doesn't check.
3077 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 3078 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
3079 shift; shift; shift; shift; shift
3080 hv=`vif_to_hv $inport`
3081 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3082 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3083 for outport; do
e4543cfe 3084 echo $packet >> $outport.expected
685f4dfe
NS
3085 done
3086}
3087
3088# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
3089#
3090# Causes a packet to be received on INPORT. The packet is an ARP
3091# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3092# it should be the hardware address of the target to expect to receive in an
3093# ARP reply; otherwise no reply is expected.
3094#
31ed1192 3095# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
3096# SHA and REPLY_HA are each 12 hex digits.
3097# SPA and TPA are each 8 hex digits.
3098test_arp() {
3099 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
3100 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3101 hv=`vif_to_hv $inport`
3102 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3103 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
3104 if test $drop != 1; then
e137131a 3105 if test X$reply_ha = X; then
685f4dfe
NS
3106 # Expect to receive the broadcast ARP on the other logical switch ports
3107 # if no reply is expected.
3108 local i j
3109 for i in 1 2 3; do
3110 for j in 1 2 3; do
3111 if test $i$j != $inport; then
3112 echo $request >> $i$j.expected
3113 fi
3114 done
3115 done
3116 else
3117 # Expect to receive the reply, if any.
3118 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3119 echo $reply >> $inport.expected
3120 fi
3121 fi
3122}
3123
3124# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3125# This function is similar to test_ip() except that it sends
3126# ipv6 packet
3127test_ipv6() {
3128 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3129 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
3130 shift; shift; shift; shift; shift
3131 hv=`vif_to_hv $inport`
3132 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3133 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3134 for outport; do
e4543cfe 3135 echo $packet >> $outport.expected
685f4dfe
NS
3136 done
3137}
3138
9e687b23
DL
3139# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
3140# This function is similar to test_ipv6() except it specifies the ICMPv6 type
3141# of the test packet
3142test_icmpv6() {
3143 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
3144 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
3145 shift; shift; shift; shift; shift; shift
3146 hv=`vif_to_hv $inport`
3147 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3148 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3149 for outport; do
e4543cfe 3150 echo $packet >> $outport.expected
9e687b23
DL
3151 done
3152}
3153
685f4dfe
NS
3154ip_to_hex() {
3155 printf "%02x%02x%02x%02x" "$@"
3156}
3157
3158# no port security
3159sip=`ip_to_hex 192 168 0 12`
3160tip=`ip_to_hex 192 168 0 13`
3161# the arp packet should be allowed even if lp[123]1 is
3162# not configured with mac f00000000023 and ip 192.168.0.12
3163for i in 1 2 3; do
3164 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
3165 for j in 1 2 3; do
3166 if test $i != $j; then
3167 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
3168 fi
3169 done
3170done
3171
3172# l2 port security
3173sip=`ip_to_hex 192 168 0 12`
3174tip=`ip_to_hex 192 168 0 13`
3175
3176# arp packet should be allowed since lp22 is configured with
3177# mac f00000000022
3178test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
3179
3180# arp packet should not be allowed since lp32 is not configured with
3181# mac f00000000021
3182test_arp 32 f00000000021 f00000000021 $sip $tip 1
3183
3184# arp packet with sha set to f00000000021 should not be allowed
3185# for lp12
3186test_arp 12 f00000000012 f00000000021 $sip $tip 1
3187
3188# ip packets should be allowed and received since lp[123]2 do not
3189# have l3 port security
3190sip=`ip_to_hex 192 168 0 55`
3191tip=`ip_to_hex 192 168 0 66`
3192for i in 1 2 3; do
3193 for j in 1 2 3; do
3194 if test $i != $j; then
3195 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3196 fi
3197 done
3198done
3199
3200# ipv6 packets should be received by lp[123]2
3201# lp[123]1 can send ipv6 traffic as there is no port security
3202sip=fe800000000000000000000000000000
3203tip=ff020000000000000000000000000000
3204
3205for i in 1 2 3; do
3206 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3207done
3208
3209
3210# l2 and l3 port security
3211sip=`ip_to_hex 192 168 0 13`
3212tip=`ip_to_hex 192 168 0 22`
3213# arp packet should be allowed since lp13 is configured with
3214# f00000000013 and 192.168.0.13
3215test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3216
3217# the arp packet should be dropped because lp23 is not configured
3218# with mac f00000000022
3219sip=`ip_to_hex 192 168 0 13`
3220tip=`ip_to_hex 192 168 0 22`
3221test_arp 23 f00000000022 f00000000022 $sip $tip 1
3222
3223# the arp packet should be dropped because lp33 is not configured
3224# with ip 192.168.0.55
3225spa=`ip_to_hex 192 168 0 55`
3226tpa=`ip_to_hex 192 168 0 22`
3227test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3228
3229# ip packets should not be received by lp[123]3 since
3230# l3 port security is enabled
3231sip=`ip_to_hex 192 168 0 55`
3232tip=`ip_to_hex 192 168 0 66`
3233for i in 1 2 3; do
3234 for j in 1 2 3; do
3235 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3236 done
3237done
3238
3239# ipv6 packets should be dropped for lp[123]3 since
3240# it is configured with only ipv4 address
3241sip=fe800000000000000000000000000000
3242tip=ff020000000000000000000000000000
3243
3244for i in 1 2 3; do
3245 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3246done
3247
3248# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3249# lp[123]1 can send ipv6 traffic as there is no port security
3250for i in 1 2 3; do
3251 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3252done
3253
3254# lp13 has extra port security with mac f0000000113 and ipv6 addr
3255# fe80::ea2a:eaff:fe28:0012
3256
3257# ipv4 packet should be dropped for lp13 with mac f0000000113
3258sip=`ip_to_hex 192 168 0 13`
3259tip=`ip_to_hex 192 168 0 23`
3260test_ip 13 f00000000113 f00000000023 $sip $tip
3261
6d53e8a9
BP
3262# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3263# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
3264# lp11 can send ipv6 traffic as there is no port security
3265sip=ee800000000000000000000000000000
3266for i in 1 2 3; do
6d53e8a9
BP
3267 tip=fe80000000000000ea2aeafffe2800${i}3
3268 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
3269done
3270
3271
3272# ipv6 packet should not be received by lp33 with mac f0000000333
3273# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3274# configured with fe80::ea2a:eaff:fe28:0033
3275# lp11 can send ipv6 traffic as there is no port security
3276
3277sip=ee800000000000000000000000000000
3278tip=fe80000000000000ea2aeafffe280023
3279test_ipv6 11 f00000000011 f00000000333 $sip $tip
3280
6d53e8a9
BP
3281# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3282# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
3283# and should be dropped for any other ip6.src
3284# lp21 can receive ipv6 traffic as there is no port security
3285
3286tip=ee800000000000000000000000000000
3287for i in 1 2 3; do
3288 sip=fe80000000000000ea2aeafffe2800${i}3
3289 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3290
9e687b23 3291 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 3292 sip=00000000000000000000000000000000
9e687b23
DL
3293 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3294 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3295 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3296 # Traffic to non-multicast traffic should be dropped
3297 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3298 # Traffic of other ICMPv6 types should be dropped
3299 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
3300
3301 # should be dropped
3302 sip=ae80000000000000ea2aeafffe2800aa
3303 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3304done
3305
31ed1192
JP
3306# configure lsp13 to send and received IPv4 packets with an address range
3307ovn-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 3308
8ff5a966
NS
3309sleep 2
3310
7d9d86ad
NS
3311sip=`ip_to_hex 10 0 0 13`
3312tip=`ip_to_hex 192 168 0 22`
31ed1192 3313# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
3314test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3315
3316sip=`ip_to_hex 10 0 0 14`
3317tip=`ip_to_hex 192 168 0 23`
31ed1192 3318# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
3319# with dst ip 192.168.0.23 should be allowed
3320test_ip 13 f00000000013 f00000000023 $sip $tip 23
3321
3322sip=`ip_to_hex 192 168 0 33`
3323tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
3324# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3325# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
3326test_ip 33 f00000000033 f00000000013 $sip $tip 13
3327
3328sip=`ip_to_hex 192 168 0 33`
3329tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
3330# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3331# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
3332test_ip 33 f00000000033 f00000000013 $sip $tip 13
3333
3334sip=`ip_to_hex 192 168 0 33`
3335tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
3336# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3337# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
3338test_ip 33 f00000000033 f00000000013 $sip $tip
3339
3340sip=`ip_to_hex 192 168 0 33`
3341tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
3342# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3343# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
3344test_ip 33 f00000000033 f00000000013 $sip $tip 13
3345
3346sip=`ip_to_hex 192 168 0 33`
3347tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
3348# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3349# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
3350test_ip 33 f00000000033 f00000000013 $sip $tip
3351
3352sip=`ip_to_hex 192 168 0 33`
3353tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
3354# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3355# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 3356test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 3357
bb0c41d3
RM
3358#dump information including flow counters
3359ovn-nbctl show
3360ovn-sbctl dump-flows -- list multicast_group
3361
3362echo "------ hv1 dump ------"
3363as hv1 ovs-vsctl show
6195e2e7 3364as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3365as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3366
3367echo "------ hv2 dump ------"
3368as hv2 ovs-vsctl show
6195e2e7 3369as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3370as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3371
3372echo "------ hv3 dump ------"
3373as hv3 ovs-vsctl show
6195e2e7 3374as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3375as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3376
685f4dfe
NS
3377# Now check the packets actually received against the ones expected.
3378for i in 1 2 3; do
3379 for j in 1 2 3; do
49d7c759 3380 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
3381 done
3382done
3383
7a8f15e0 3384OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 3385
685f4dfe 3386AT_CLEANUP
509afdc3
GS
3387
3388AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
3389AT_SKIP_IF([test $HAVE_PYTHON = no])
3390ovn_start
3391
3392# Logical network:
3393# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3394# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3395# R2 has ls2 (172.16.1.0/24) connected to it.
3396
3c1ae70a
JP
3397ls1_lp1_mac="f0:00:00:01:02:03"
3398rp_ls1_mac="00:00:00:01:02:03"
3399rp_ls2_mac="00:00:00:01:02:04"
3400ls2_lp1_mac="f0:00:00:01:02:04"
3401
3402ls1_lp1_ip="192.168.1.2"
3403ls2_lp1_ip="172.16.1.2"
3404
fa2a27b2
JP
3405ovn-nbctl lr-add R1
3406ovn-nbctl lr-add R2
509afdc3 3407
ea46a4e9
JP
3408ovn-nbctl ls-add ls1
3409ovn-nbctl ls-add ls2
509afdc3
GS
3410
3411# Connect ls1 to R1
3c1ae70a 3412ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
509afdc3 3413
31ed1192 3414ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3c1ae70a 3415 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
509afdc3
GS
3416
3417# Connect ls2 to R2
3c1ae70a 3418ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
509afdc3 3419
31ed1192 3420ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3c1ae70a 3421 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
509afdc3
GS
3422
3423# Connect R1 to R2
4685e523
JP
3424ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3425ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 3426
6d9ecfa9
JP
3427ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3428ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
3429
3430# Create logical port ls1-lp1 in ls1
31ed1192 3431ovn-nbctl lsp-add ls1 ls1-lp1 \
3c1ae70a 3432-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
509afdc3
GS
3433
3434# Create logical port ls2-lp1 in ls2
31ed1192 3435ovn-nbctl lsp-add ls2 ls2-lp1 \
3c1ae70a 3436-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
509afdc3
GS
3437
3438# Create two hypervisor and create OVS ports corresponding to logical ports.
3439net_add n1
3440
3441sim_add hv1
3442as hv1
3443ovs-vsctl add-br br-phys
3444ovn_attach n1 br-phys 192.168.0.1
3445ovs-vsctl -- add-port br-int hv1-vif1 -- \
3446 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3447 options:tx_pcap=hv1/vif1-tx.pcap \
3448 options:rxq_pcap=hv1/vif1-rx.pcap \
3449 ofport-request=1
3450
3451sim_add hv2
3452as hv2
3453ovs-vsctl add-br br-phys
3454ovn_attach n1 br-phys 192.168.0.2
3455ovs-vsctl -- add-port br-int hv2-vif1 -- \
3456 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3457 options:tx_pcap=hv2/vif1-tx.pcap \
3458 options:rxq_pcap=hv2/vif1-rx.pcap \
3459 ofport-request=1
3460
3461
3462# Pre-populate the hypervisors' ARP tables so that we don't lose any
3463# packets for ARP resolution (native tunneling doesn't queue packets
3464# for ARP resolution).
74868f2c 3465OVN_POPULATE_ARP
509afdc3
GS
3466
3467# Allow some time for ovn-northd and ovn-controller to catch up.
3468# XXX This should be more systematic.
3469sleep 1
3470
509afdc3 3471# Packet to send.
3c1ae70a
JP
3472packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3473 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3474 udp && udp.src==53 && udp.dst==4369"
3475as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
509afdc3
GS
3476
3477
3478echo "---------NB dump-----"
3479ovn-nbctl show
3480echo "---------------------"
3481ovn-nbctl list logical_router
3482echo "---------------------"
3483ovn-nbctl list logical_router_port
3484echo "---------------------"
3485
3486echo "---------SB dump-----"
3487ovn-sbctl list datapath_binding
3488echo "---------------------"
3489ovn-sbctl list port_binding
3490echo "---------------------"
3491
3492echo "------ hv1 dump ----------"
8dab1022 3493as hv1 ovs-ofctl show br-int
509afdc3
GS
3494as hv1 ovs-ofctl dump-flows br-int
3495echo "------ hv2 dump ----------"
8dab1022 3496as hv2 ovs-ofctl show br-int
509afdc3
GS
3497as hv2 ovs-ofctl dump-flows br-int
3498
3499# Packet to Expect
3c1ae70a
JP
3500# The TTL should be decremented by 2.
3501packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3502 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3503 udp && udp.src==53 && udp.dst==4369"
3504echo $packet | ovstest test-ovn expr-to-packets > expected
509afdc3 3505
49d7c759 3506OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 3507
7ebfcd3d
NS
3508AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3509grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3510])
3511
3512# Disable the ls2-lp1 port.
3513ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3514
3515AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3516grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3517])
3518
3519# Generate the packet destined for ls2-lp1 and it should not be delivered.
3520# Packet to send.
3521packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3522 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3523 udp && udp.src==53 && udp.dst==4369"
3524
3525as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3526# The 2nd packet sent shound not be received.
3527OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3528
7a8f15e0 3529OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
3530
3531AT_CLEANUP
5412db30
J
3532
3533
4685e523
JP
3534AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3535AT_KEYWORDS([router-admin-state])
3536AT_SKIP_IF([test $HAVE_PYTHON = no])
3537ovn_start
3538
3539# Logical network:
3540# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3541# and 172.16.1.0/24) connected to it.
3542
3543ovn-nbctl lr-add R1
3544
3545ovn-nbctl ls-add ls1
3546
3547# Connect ls1 to R1
bf44c2cd 3548ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
3549ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3550 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3551
3552# Create logical port ls1-lp1 in ls1
3553ovn-nbctl lsp-add ls1 ls1-lp1 \
3554 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3555
3556# Create logical port ls1-lp2 in ls1
3557ovn-nbctl lsp-add ls1 ls1-lp2 \
3558 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3559
3560# Create one hypervisor and create OVS ports corresponding to logical ports.
3561net_add n1
3562
3563sim_add hv1
3564as hv1
3565ovs-vsctl add-br br-phys
3566ovn_attach n1 br-phys 192.168.0.1
3567ovs-vsctl -- add-port br-int vif1 -- \
3568 set interface vif1 external-ids:iface-id=ls1-lp1 \
3569 options:tx_pcap=hv1/vif1-tx.pcap \
3570 options:rxq_pcap=hv1/vif1-rx.pcap \
3571 ofport-request=1
3572
3573ovs-vsctl -- add-port br-int vif2 -- \
3574 set interface vif2 external-ids:iface-id=ls1-lp2 \
3575 options:tx_pcap=hv1/vif2-tx.pcap \
3576 options:rxq_pcap=hv1/vif2-rx.pcap \
3577 ofport-request=1
3578
3579
3580# Allow some time for ovn-northd and ovn-controller to catch up.
3581# XXX This should be more systematic.
3582sleep 1
3583
3584# Send ip packets between the two ports.
3585ip_to_hex() {
3586 printf "%02x%02x%02x%02x" "$@"
3587}
4685e523
JP
3588
3589# Packet to send.
3590src_mac="f00000010203"
3591dst_mac="000000010203"
3592src_ip=`ip_to_hex 192 168 1 2`
3593dst_ip=`ip_to_hex 172 16 1 2`
3594packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3595as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3596
3597
3598echo "---------NB dump-----"
3599ovn-nbctl show
3600echo "---------------------"
3601ovn-nbctl list logical_router
3602echo "---------------------"
3603ovn-nbctl list logical_router_port
3604echo "---------------------"
3605
3606echo "---------SB dump-----"
3607ovn-sbctl list datapath_binding
3608echo "---------------------"
3609ovn-sbctl list logical_flow
3610echo "---------------------"
3611
3612echo "------ hv1 dump ----------"
3613as hv1 ovs-ofctl dump-flows br-int
3614
3615
3616#Disable router R1
3617ovn-nbctl set Logical_Router R1 enabled=false
3618
3b8cd0ea
BP
3619# Allow some time for ovn-northd and ovn-controller to catch up.
3620# XXX This should be more systematic.
3621sleep 1
3622
4685e523
JP
3623echo "---------SB dump-----"
3624ovn-sbctl list datapath_binding
3625echo "---------------------"
3626ovn-sbctl list logical_flow
3627echo "---------------------"
3628
3629echo "------ hv1 dump ----------"
3630as hv1 ovs-ofctl dump-flows br-int
3631
3632as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3633
3634# Packet to Expect
3635expect_src_mac="000000010203"
3636expect_dst_mac="f00000010204"
49d7c759 3637echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3638
49d7c759 3639OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
3640
3641
3642as hv1
3643OVS_APP_EXIT_AND_WAIT([ovn-controller])
3644OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3645OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3646
3647as ovn-sb
3648OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3649
3650as ovn-nb
3651OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3652
3653as northd
3654OVS_APP_EXIT_AND_WAIT([ovn-northd])
3655
3656as main
3657OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3658OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3659
3660AT_CLEANUP
3661
3662
3663AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3664AT_KEYWORDS([router-admin-state])
3665AT_SKIP_IF([test $HAVE_PYTHON = no])
3666ovn_start
3667
3668# Logical network:
3669# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3670# and has switch ls2 (172.16.1.0/24) connected to it.
3671
fa2a27b2 3672ovn-nbctl lr-add R1
5412db30 3673
ea46a4e9
JP
3674ovn-nbctl ls-add ls1
3675ovn-nbctl ls-add ls2
5412db30
J
3676
3677# Connect ls1 to R1
bf44c2cd 3678ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3679ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3680 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3681
3682# Connect ls2 to R1
bf44c2cd 3683ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3684ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3685 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3686
3687# Create logical port ls1-lp1 in ls1
31ed1192
JP
3688ovn-nbctl lsp-add ls1 ls1-lp1 \
3689-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3690
3691# Create logical port ls2-lp1 in ls2
31ed1192
JP
3692ovn-nbctl lsp-add ls2 ls2-lp1 \
3693-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3694
3695# Create one hypervisor and create OVS ports corresponding to logical ports.
3696net_add n1
3697
3698sim_add hv1
3699as hv1
3700ovs-vsctl add-br br-phys
3701ovn_attach n1 br-phys 192.168.0.1
3702ovs-vsctl -- add-port br-int vif1 -- \
3703 set interface vif1 external-ids:iface-id=ls1-lp1 \
3704 options:tx_pcap=hv1/vif1-tx.pcap \
3705 options:rxq_pcap=hv1/vif1-rx.pcap \
3706 ofport-request=1
3707
3708ovs-vsctl -- add-port br-int vif2 -- \
3709 set interface vif2 external-ids:iface-id=ls2-lp1 \
3710 options:tx_pcap=hv1/vif2-tx.pcap \
3711 options:rxq_pcap=hv1/vif2-rx.pcap \
3712 ofport-request=1
3713
3714
3715# Allow some time for ovn-northd and ovn-controller to catch up.
3716# XXX This should be more systematic.
3717sleep 1
3718
3719# Send ip packets between the two ports.
3720ip_to_hex() {
3721 printf "%02x%02x%02x%02x" "$@"
3722}
5412db30
J
3723
3724# Packet to send.
3725src_mac="f00000010203"
3726dst_mac="000000010203"
3727src_ip=`ip_to_hex 192 168 1 2`
3728dst_ip=`ip_to_hex 172 16 1 2`
3729packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3730as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3731
3732
3733echo "---------NB dump-----"
3734ovn-nbctl show
3735echo "---------------------"
3736ovn-nbctl list logical_router
3737echo "---------------------"
3738ovn-nbctl list logical_router_port
3739echo "---------------------"
3740
3741echo "---------SB dump-----"
3742ovn-sbctl list datapath_binding
3743echo "---------------------"
3744ovn-sbctl list logical_flow
3745echo "---------------------"
3746
3747echo "------ hv1 dump ----------"
3748as hv1 ovs-ofctl dump-flows br-int
3749
5412db30
J
3750#Disable router R1
3751ovn-nbctl set Logical_Router R1 enabled=false
3752
3753echo "---------SB dump-----"
3754ovn-sbctl list datapath_binding
3755echo "---------------------"
3756ovn-sbctl list logical_flow
3757echo "---------------------"
3758
3759echo "------ hv1 dump ----------"
3760as hv1 ovs-ofctl dump-flows br-int
3761
a1361a6e
LR
3762# Allow some time for the disabling of logical router R1 to propagate.
3763# XXX This should be more systematic.
3764sleep 1
3765
5412db30
J
3766as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3767
3768# Packet to Expect
3769expect_src_mac="000000010204"
3770expect_dst_mac="f00000010204"
49d7c759 3771echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3772
49d7c759 3773OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3774
7a8f15e0 3775OVN_CLEANUP([hv1])
5412db30
J
3776
3777AT_CLEANUP
3778
28dc3fe9 3779AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3780AT_SKIP_IF([test $HAVE_PYTHON = no])
3781ovn_start
3782
3783# Logical network:
3784# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3785# network. R1 has switchess foo (192.168.1.0/24)
3786# connected to it.
3787# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3788
fa2a27b2
JP
3789ovn-nbctl lr-add R1
3790ovn-nbctl lr-add R2
28dc3fe9 3791
ea46a4e9
JP
3792ovn-nbctl ls-add foo
3793ovn-nbctl ls-add alice
3794ovn-nbctl ls-add bob
28dc3fe9
SR
3795
3796# Connect foo to R1
bf44c2cd 3797ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3798ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3799 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3800
3801# Connect alice to R2
bf44c2cd 3802ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3803ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3804 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3805
3806# Connect bob to R2
bf44c2cd 3807ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3808ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3809 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3810
3811# Connect R1 to R2
4685e523
JP
3812ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3813ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3814
3815#install static routes
e48ccf3c
JP
3816ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3817ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3818ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3819
3820# Create logical port foo1 in foo
31ed1192
JP
3821ovn-nbctl lsp-add foo foo1 \
3822-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3823
3824# Create logical port alice1 in alice
31ed1192
JP
3825ovn-nbctl lsp-add alice alice1 \
3826-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3827
3828# Create logical port bob1 in bob
31ed1192
JP
3829ovn-nbctl lsp-add bob bob1 \
3830-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3831
3832# Create two hypervisor and create OVS ports corresponding to logical ports.
3833net_add n1
3834
3835sim_add hv1
3836as hv1
3837ovs-vsctl add-br br-phys
3838ovn_attach n1 br-phys 192.168.0.1
3839ovs-vsctl -- add-port br-int hv1-vif1 -- \
3840 set interface hv1-vif1 external-ids:iface-id=foo1 \
3841 options:tx_pcap=hv1/vif1-tx.pcap \
3842 options:rxq_pcap=hv1/vif1-rx.pcap \
3843 ofport-request=1
3844
3845ovs-vsctl -- add-port br-int hv1-vif2 -- \
3846 set interface hv1-vif2 external-ids:iface-id=alice1 \
3847 options:tx_pcap=hv1/vif2-tx.pcap \
3848 options:rxq_pcap=hv1/vif2-rx.pcap \
3849 ofport-request=2
3850
3851sim_add hv2
3852as hv2
3853ovs-vsctl add-br br-phys
3854ovn_attach n1 br-phys 192.168.0.2
3855ovs-vsctl -- add-port br-int hv2-vif1 -- \
3856 set interface hv2-vif1 external-ids:iface-id=bob1 \
3857 options:tx_pcap=hv2/vif1-tx.pcap \
3858 options:rxq_pcap=hv2/vif1-rx.pcap \
3859 ofport-request=1
3860
3861
3862# Pre-populate the hypervisors' ARP tables so that we don't lose any
3863# packets for ARP resolution (native tunneling doesn't queue packets
3864# for ARP resolution).
74868f2c 3865OVN_POPULATE_ARP
28dc3fe9
SR
3866
3867# Allow some time for ovn-northd and ovn-controller to catch up.
3868# XXX This should be more systematic.
3869sleep 1
3870
3871ip_to_hex() {
3872 printf "%02x%02x%02x%02x" "$@"
3873}
28dc3fe9
SR
3874
3875# Send ip packets between foo1 and alice1
3876src_mac="f00000010203"
3877dst_mac="000000010203"
3878src_ip=`ip_to_hex 192 168 1 2`
3879dst_ip=`ip_to_hex 172 16 1 2`
3880packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3881as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3882
3883# Send ip packets between foo1 and bob1
3884src_mac="f00000010203"
3885dst_mac="000000010203"
3886src_ip=`ip_to_hex 192 168 1 2`
3887dst_ip=`ip_to_hex 172 16 2 2`
3888packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3889as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3890
3891echo "---------NB dump-----"
3892ovn-nbctl show
3893echo "---------------------"
3894ovn-nbctl list logical_router
3895echo "---------------------"
3896ovn-nbctl list logical_router_port
3897echo "---------------------"
3898
3899echo "---------SB dump-----"
3900ovn-sbctl list datapath_binding
3901echo "---------------------"
3902ovn-sbctl list port_binding
3903echo "---------------------"
3904
3905echo "------ hv1 dump ----------"
3906as hv1 ovs-ofctl dump-flows br-int
3907echo "------ hv2 dump ----------"
3908as hv2 ovs-ofctl dump-flows br-int
3909
3910# Packet to Expect at bob1
3911src_mac="000000010205"
3912dst_mac="f00000010205"
3913src_ip=`ip_to_hex 192 168 1 2`
3914dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3915echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3916
49d7c759 3917OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3918
3919# Packet to Expect at alice1
3920src_mac="000000010204"
3921dst_mac="f00000010204"
3922src_ip=`ip_to_hex 192 168 1 2`
3923dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3924echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3925
49d7c759 3926OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3927
7a8f15e0 3928OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3929
3930AT_CLEANUP
5412db30 3931
0ee8aaf6 3932AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3933AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3934ovn_start
ea46a4e9 3935ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3936net_add n1
3937sim_add hv
3938as hv
3939ovs-vsctl \
3940 -- add-br br-phys \
3941 -- add-br br-eth0
3942
3943ovn_attach n1 br-phys 192.168.0.1
3944
3945AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3946AT_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])
3947
3948# Create a vif.
31ed1192
JP
3949AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3950AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3951AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3952
3953# Create a localnet port.
31ed1192
JP
3954AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3955AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3956AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3957AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3958
3959AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3960
3961# Wait for packet to be received.
49d7c759
BP
3962echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3963OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6 3964
5b57e12a
GL
3965# Check GARP packet when restart openflow connection.
3966as hv
3967OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3968
3969OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3970
3971as hv
3972start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3973
3974# Wait for packet to be received.
3975echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3976OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3977
0ee8aaf6
RR
3978# Delete the localnet ports.
3979AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3980AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3981
7a8f15e0 3982OVN_CLEANUP([hv])
0ee8aaf6
RR
3983
3984AT_CLEANUP
75cf9d2b
GS
3985
3986AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
3987AT_SKIP_IF([test $HAVE_PYTHON = no])
3988ovn_start
3989
3990# Logical network:
3991# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3992# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3993# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3994# connected to it.
3995
fa2a27b2
JP
3996ovn-nbctl lr-add R1
3997ovn-nbctl lr-add R2
3998ovn-nbctl lr-add R3
75cf9d2b 3999
ea46a4e9
JP
4000ovn-nbctl ls-add foo
4001ovn-nbctl ls-add alice
4002ovn-nbctl ls-add bob
4003ovn-nbctl ls-add join
75cf9d2b
GS
4004
4005# Connect foo to R1
31114af7 4006ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4007ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 4008 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
4009
4010# Connect alice to R2
31114af7 4011ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4012ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4013 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
4014
4015# Connect bob to R3
31114af7 4016ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 4017ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 4018 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
4019
4020# Connect R1 to join
31114af7 4021ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4022ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4023 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
4024
4025# Connect R2 to join
31114af7 4026ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4027ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4028 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
4029
4030# Connect R3 to join
31114af7 4031ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 4032ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 4033 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
4034
4035#install static routes
e48ccf3c
JP
4036ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4037ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 4038
e48ccf3c
JP
4039ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4040ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 4041
e48ccf3c
JP
4042ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
4043ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
4044
4045# Create logical port foo1 in foo
31ed1192
JP
4046ovn-nbctl lsp-add foo foo1 \
4047-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
4048
4049# Create logical port alice1 in alice
31ed1192
JP
4050ovn-nbctl lsp-add alice alice1 \
4051-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
4052
4053# Create logical port bob1 in bob
31ed1192
JP
4054ovn-nbctl lsp-add bob bob1 \
4055-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
4056
4057# Create two hypervisor and create OVS ports corresponding to logical ports.
4058net_add n1
4059
4060sim_add hv1
4061as hv1
4062ovs-vsctl add-br br-phys
4063ovn_attach n1 br-phys 192.168.0.1
4064ovs-vsctl -- add-port br-int hv1-vif1 -- \
4065 set interface hv1-vif1 external-ids:iface-id=foo1 \
4066 options:tx_pcap=hv1/vif1-tx.pcap \
4067 options:rxq_pcap=hv1/vif1-rx.pcap \
4068 ofport-request=1
4069
4070ovs-vsctl -- add-port br-int hv1-vif2 -- \
4071 set interface hv1-vif2 external-ids:iface-id=alice1 \
4072 options:tx_pcap=hv1/vif2-tx.pcap \
4073 options:rxq_pcap=hv1/vif2-rx.pcap \
4074 ofport-request=2
4075
4076sim_add hv2
4077as hv2
4078ovs-vsctl add-br br-phys
4079ovn_attach n1 br-phys 192.168.0.2
4080ovs-vsctl -- add-port br-int hv2-vif1 -- \
4081 set interface hv2-vif1 external-ids:iface-id=bob1 \
4082 options:tx_pcap=hv2/vif1-tx.pcap \
4083 options:rxq_pcap=hv2/vif1-rx.pcap \
4084 ofport-request=1
4085
4086
4087# Pre-populate the hypervisors' ARP tables so that we don't lose any
4088# packets for ARP resolution (native tunneling doesn't queue packets
4089# for ARP resolution).
74868f2c 4090OVN_POPULATE_ARP
75cf9d2b
GS
4091
4092# Allow some time for ovn-northd and ovn-controller to catch up.
4093# XXX This should be more systematic.
4094sleep 1
4095
4096ip_to_hex() {
4097 printf "%02x%02x%02x%02x" "$@"
4098}
75cf9d2b
GS
4099
4100# Send ip packets between foo1 and alice1
4101src_mac="f00000010203"
4102dst_mac="000001010203"
4103src_ip=`ip_to_hex 192 168 1 2`
4104dst_ip=`ip_to_hex 172 16 1 2`
4105packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4106as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4107as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4108
4109# Send ip packets between foo1 and bob1
4110src_mac="f00000010203"
4111dst_mac="000001010203"
4112src_ip=`ip_to_hex 192 168 1 2`
4113dst_ip=`ip_to_hex 10 32 1 2`
4114packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4115as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4116
4117echo "---------NB dump-----"
4118ovn-nbctl show
4119echo "---------------------"
4120ovn-nbctl list logical_router
4121echo "---------------------"
4122ovn-nbctl list logical_router_port
4123echo "---------------------"
4124
4125echo "---------SB dump-----"
4126ovn-sbctl list datapath_binding
4127echo "---------------------"
4128ovn-sbctl list port_binding
4129echo "---------------------"
4130ovn-sbctl dump-flows
4131echo "---------------------"
4132
4133echo "------ hv1 dump ----------"
4134as hv1 ovs-ofctl show br-int
4135as hv1 ovs-ofctl dump-flows br-int
4136echo "------ hv2 dump ----------"
4137as hv2 ovs-ofctl show br-int
4138as hv2 ovs-ofctl dump-flows br-int
4139echo "----------------------------"
4140
4141# Packet to Expect at bob1
4142src_mac="000003010203"
4143dst_mac="f00000010205"
4144src_ip=`ip_to_hex 192 168 1 2`
4145dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 4146echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 4147
49d7c759 4148OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
4149
4150# Packet to Expect at alice1
4151src_mac="000002010203"
4152dst_mac="f00000010204"
4153src_ip=`ip_to_hex 192 168 1 2`
4154dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 4155echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 4156
49d7c759 4157OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 4158
7a8f15e0 4159OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
4160
4161AT_CLEANUP
c1645003 4162
281977f7 4163AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
4164AT_SKIP_IF([test $HAVE_PYTHON = no])
4165ovn_start
4166
4167ovn-nbctl ls-add ls1
4168
4169ovn-nbctl lsp-add ls1 ls1-lp1 \
4170-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4171
4172ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4173
4174ovn-nbctl lsp-add ls1 ls1-lp2 \
4175-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4176
4177ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4178
4179ovn-nbctl ls-add ls2
4180ovn-nbctl lsp-add ls2 ls2-lp1 \
4181-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4182ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4183ovn-nbctl lsp-add ls2 ls2-lp2 \
4184-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4185ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4186
9060fc9a 4187d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
281977f7 4188options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
9060fc9a 4189\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
281977f7 4190
9060fc9a
MM
4191ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4192ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4193
4194d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
281977f7 4195options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
9060fc9a
MM
4196\"lease_time\"=\"3600\"")"
4197
4198ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
281977f7
NS
4199
4200net_add n1
4201sim_add hv1
4202
4203as hv1
4204ovs-vsctl add-br br-phys
4205ovn_attach n1 br-phys 192.168.0.1
4206ovs-vsctl -- add-port br-int hv1-vif1 -- \
4207 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4208 options:tx_pcap=hv1/vif1-tx.pcap \
4209 options:rxq_pcap=hv1/vif1-rx.pcap \
4210 ofport-request=1
4211
4212ovs-vsctl -- add-port br-int hv1-vif2 -- \
4213 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4214 options:tx_pcap=hv1/vif2-tx.pcap \
4215 options:rxq_pcap=hv1/vif2-rx.pcap \
4216 ofport-request=2
4217
4218ovs-vsctl -- add-port br-int hv1-vif3 -- \
4219 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4220 options:tx_pcap=hv1/vif3-tx.pcap \
4221 options:rxq_pcap=hv1/vif3-rx.pcap \
4222 ofport-request=3
4223
4224ovs-vsctl -- add-port br-int hv1-vif4 -- \
4225 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4226 options:tx_pcap=hv1/vif4-tx.pcap \
4227 options:rxq_pcap=hv1/vif4-rx.pcap \
4228 ofport-request=4
4229
74868f2c 4230OVN_POPULATE_ARP
281977f7
NS
4231
4232sleep 2
4233
4234as hv1 ovs-vsctl show
4235
281977f7 4236# This shell function sends a DHCP request packet
fcc3c93f 4237# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP REQUEST_IP ...
281977f7 4238test_dhcp() {
fcc3c93f
GS
4239 local inport=$1 src_mac=$2 dhcp_type=$3 ciaddr=$4 offer_ip=$5 request_ip=$6 use_ip=$7
4240 shift; shift; shift; shift; shift; shift; shift;
213615b3
NS
4241 if test $use_ip != 0; then
4242 src_ip=$1
4243 dst_ip=$2
4244 shift; shift;
4245 else
4246 src_ip=`ip_to_hex 0 0 0 0`
4247 dst_ip=`ip_to_hex 255 255 255 255`
4248 fi
fcc3c93f
GS
4249 if test $request_ip != 0; then
4250 ip_len=0120
4251 udp_len=010b
4252 else
4253 ip_len=011a
4254 udp_len=0106
4255 fi
4256 local request=ffffffffffff${src_mac}08004510${ip_len}0000000080110000${src_ip}${dst_ip}
281977f7 4257 # udp header and dhcp header
fcc3c93f
GS
4258 request=${request}00440043${udp_len}0000
4259 request=${request}010106006359aa7600000000${ciaddr}000000000000000000000000${src_mac}
281977f7 4260 # client hardware padding
ab187e7e 4261 request=${request}00000000000000000000
281977f7 4262 # server hostname
ab187e7e
BP
4263 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4264 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4265 # boot file name
ab187e7e
BP
4266 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4267 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4268 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4269 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4270 # dhcp magic cookie
ab187e7e 4271 request=${request}63825363
281977f7 4272 # dhcp message type
fcc3c93f
GS
4273 request=${request}3501${dhcp_type}
4274 # dhcp unknown option
4275 request=${request}d70701020304050607
4276 # dhcp pad option
4277 request=${request}00
4278 if test $request_ip != 0; then
4279 # dhcp requested ip
4280 request=${request}3204${request_ip}
4281 fi
4282 # dhcp end option
4283 request=${request}ff
281977f7 4284
697f5993
BP
4285 for port in $inport "$@"; do
4286 : >> $port.expected
4287 done
281977f7 4288 if test $offer_ip != 0; then
fcc3c93f 4289 local srv_mac=$1 srv_ip=$2 dhcp_reply_type=$3 expected_dhcp_opts=$4
281977f7
NS
4290 # total IP length will be the IP length of the request packet
4291 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4292 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4293 udp_len=`expr $ip_len - 20`
04d60f6e
YT
4294 ip_len=$(printf "%x" $ip_len)
4295 udp_len=$(printf "%x" $udp_len)
281977f7
NS
4296 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4297 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4298 # udp header and dhcp header.
4299 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
fcc3c93f
GS
4300 reply=${reply}004300440${udp_len}0000020106006359aa7600000000${ciaddr}
4301 # your ip address; 0 for NAK
4302 if test $dhcp_reply_type = 06; then
4303 reply=${reply}00000000
4304 else
4305 reply=${reply}${offer_ip}
4306 fi
281977f7 4307 # next server ip address, relay agent ip address, client mac address
ab187e7e 4308 reply=${reply}0000000000000000${src_mac}
281977f7 4309 # client hardware padding
ab187e7e 4310 reply=${reply}00000000000000000000
281977f7 4311 # server hostname
ab187e7e
BP
4312 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4313 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4314 # boot file name
ab187e7e
BP
4315 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4316 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4317 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4318 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4319 # dhcp magic cookie
ab187e7e 4320 reply=${reply}63825363
ab187e7e 4321 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
4322 echo $reply >> $inport.expected
4323 else
281977f7 4324 for outport; do
e4543cfe 4325 echo $request >> $outport.expected
281977f7
NS
4326 done
4327 fi
4328 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4329}
4330
4331reset_pcap_file() {
4332 local iface=$1
4333 local pcap_file=$2
4334 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4335options:rxq_pcap=dummy-rx.pcap
4336 rm -f ${pcap_file}*.pcap
4337 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4338options:rxq_pcap=${pcap_file}-rx.pcap
4339}
4340
4341ip_to_hex() {
4342 printf "%02x%02x%02x%02x" "$@"
4343}
4344
4345AT_CAPTURE_FILE([ofctl_monitor0.log])
4346as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4347--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4348
4349echo "---------NB dump-----"
4350ovn-nbctl show
4351echo "---------------------"
4352echo "---------SB dump-----"
4353ovn-sbctl list datapath_binding
4354echo "---------------------"
4355ovn-sbctl list logical_flow
4356echo "---------------------"
4357
4358echo "---------------------"
4359ovn-sbctl dump-flows
4360echo "---------------------"
4361
4362echo "------ hv1 dump ----------"
4363as hv1 ovs-ofctl dump-flows br-int
4364
4365# Send DHCPDISCOVER.
4366offer_ip=`ip_to_hex 10 0 0 4`
4367server_ip=`ip_to_hex 10 0 0 1`
fcc3c93f
GS
4368ciaddr=`ip_to_hex 0 0 0 0`
4369request_ip=0
7c76bf4e 4370expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
fcc3c93f 4371test_dhcp 1 f00000000001 01 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 02 $expected_dhcp_opts
281977f7
NS
4372
4373# NXT_RESUMEs should be 1.
4374OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4375
4376$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4377cat 1.expected | cut -c -48 > expout
4378AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4379# Skipping the IPv4 checksum.
4380cat 1.expected | cut -c 53- > expout
4381AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4382
4383# ovs-ofctl also resumes the packets and this causes other ports to receive
4384# the DHCP request packet. So reset the pcap files so that its easier to test.
4385reset_pcap_file hv1-vif1 hv1/vif1
4386reset_pcap_file hv1-vif2 hv1/vif2
4387rm -f 1.expected
4388rm -f 2.expected
4389
fcc3c93f
GS
4390# Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
4391# address in the Requested IP Address option.
281977f7
NS
4392offer_ip=`ip_to_hex 10 0 0 6`
4393server_ip=`ip_to_hex 10 0 0 1`
fcc3c93f
GS
4394ciaddr=`ip_to_hex 0 0 0 0`
4395request_ip=$offer_ip
7c76bf4e 4396expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
fcc3c93f 4397test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
281977f7
NS
4398
4399# NXT_RESUMEs should be 2.
4400OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4401
4402$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4403cat 2.expected | cut -c -48 > expout
4404AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4405# Skipping the IPv4 checksum.
4406cat 2.expected | cut -c 53- > expout
4407AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4408
4409reset_pcap_file hv1-vif1 hv1/vif1
4410reset_pcap_file hv1-vif2 hv1/vif2
4411rm -f 1.expected
4412rm -f 2.expected
4413
fcc3c93f
GS
4414# Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with a mismatched IP in
4415# the Requested IP Address option, expect a DHCPNAK.
4416offer_ip=`ip_to_hex 10 0 0 6`
4417server_ip=`ip_to_hex 10 0 0 1`
4418ciaddr=`ip_to_hex 0 0 0 0`
4419request_ip=`ip_to_hex 10 0 0 7`
4420expected_dhcp_opts=""
4421test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 06 $expected_dhcp_opts
4422
4423# NXT_RESUMEs should be 3.
4424OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4425
4426$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4427cat 2.expected | cut -c -48 > expout
4428AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4429# Skipping the IPv4 checksum.
4430cat 2.expected | cut -c 53- > expout
4431AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4432
4433reset_pcap_file hv1-vif1 hv1/vif1
4434reset_pcap_file hv1-vif2 hv1/vif2
4435rm -f 1.expected
4436rm -f 2.expected
4437
281977f7
NS
4438# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4439# but should be resumed without the reply.
4440# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4441# one from ovn-controller and the other from "ovs-ofctl resume."
fcc3c93f 4442ciaddr=`ip_to_hex 0 0 0 0`
281977f7 4443offer_ip=0
fcc3c93f
GS
4444request_ip=0
4445test_dhcp 2 f00000000002 08 $ciaddr $offer_ip $request_ip 0 1 1
281977f7 4446
fcc3c93f
GS
4447# NXT_RESUMEs should be 4.
4448OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
281977f7
NS
4449
4450# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 4451OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
4452
4453reset_pcap_file hv1-vif1 hv1/vif1
4454reset_pcap_file hv1-vif2 hv1/vif2
4455rm -f 1.expected
4456rm -f 2.expected
4457
4458# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4459# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4460
fcc3c93f
GS
4461ciaddr=`ip_to_hex 0 0 0 0`
4462test_dhcp 3 f00000000003 01 $ciaddr 0 0 4 0
281977f7
NS
4463
4464# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4465# this lport.
fcc3c93f
GS
4466ciaddr=`ip_to_hex 0 0 0 0`
4467test_dhcp 4 f00000000004 01 $ciaddr 0 0 3 0
281977f7 4468
fcc3c93f
GS
4469# NXT_RESUMEs should be 4.
4470OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
281977f7 4471
fcc3c93f
GS
4472#OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4473#OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 4474
fcc3c93f
GS
4475# Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4476# and ip4.dst set to 10.0.0.1.
213615b3
NS
4477offer_ip=`ip_to_hex 10 0 0 6`
4478server_ip=`ip_to_hex 10 0 0 1`
fcc3c93f
GS
4479ciaddr=$offer_ip
4480request_ip=0
213615b3
NS
4481src_ip=$offer_ip
4482dst_ip=$server_ip
fcc3c93f
GS
4483expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4484test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
213615b3 4485
fcc3c93f
GS
4486# NXT_RESUMEs should be 5.
4487OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
213615b3
NS
4488
4489$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4490cat 2.expected | cut -c -48 > expout
4491AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4492# Skipping the IPv4 checksum.
4493cat 2.expected | cut -c 53- > expout
4494AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4495
4496reset_pcap_file hv1-vif1 hv1/vif1
4497reset_pcap_file hv1-vif2 hv1/vif2
4498rm -f 1.expected
4499rm -f 2.expected
4500
fcc3c93f
GS
4501# Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4502# and ip4.dst set to 255.255.255.255.
213615b3
NS
4503offer_ip=`ip_to_hex 10 0 0 6`
4504server_ip=`ip_to_hex 10 0 0 1`
fcc3c93f
GS
4505ciaddr=$offer_ip
4506request_ip=0
4507src_ip=$offer_ip
4508dst_ip=`ip_to_hex 255 255 255 255`
213615b3 4509expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
fcc3c93f
GS
4510test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
4511
4512# NXT_RESUMEs should be 6.
4513OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4514
4515$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4516cat 2.expected | cut -c -48 > expout
4517AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4518# Skipping the IPv4 checksum.
4519cat 2.expected | cut -c 53- > expout
4520AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4521
4522reset_pcap_file hv1-vif1 hv1/vif1
4523reset_pcap_file hv1-vif2 hv1/vif2
4524rm -f 1.expected
4525rm -f 2.expected
4526
4527# Send DHCPREQUEST in the RENEWING/REBINDING state with a mismatched IP in the
4528# ciaddr, expect a DHCPNAK.
4529offer_ip=`ip_to_hex 10 0 0 6`
4530server_ip=`ip_to_hex 10 0 0 1`
4531ciaddr=`ip_to_hex 10 0 0 7`
4532request_ip=0
213615b3
NS
4533src_ip=$offer_ip
4534dst_ip=`ip_to_hex 255 255 255 255`
fcc3c93f
GS
4535expected_dhcp_opts=""
4536test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
213615b3 4537
fcc3c93f
GS
4538# NXT_RESUMEs should be 7.
4539OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4540
4541$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4542cat 2.expected | cut -c -48 > expout
4543AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4544# Skipping the IPv4 checksum.
4545cat 2.expected | cut -c 53- > expout
4546AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4547
4548reset_pcap_file hv1-vif1 hv1/vif1
4549reset_pcap_file hv1-vif2 hv1/vif2
4550rm -f 1.expected
4551rm -f 2.expected
4552
4553# Send DHCPREQUEST in the RENEWING/REBINDING state without a specifyied ciaddr,
4554# expect a DHCPNAK.
4555offer_ip=`ip_to_hex 10 0 0 6`
4556server_ip=`ip_to_hex 10 0 0 1`
4557ciaddr=`ip_to_hex 0 0 0 0`
4558request_ip=0
4559src_ip=$offer_ip
4560dst_ip=`ip_to_hex 255 255 255 255`
4561expected_dhcp_opts=""
4562test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
4563
4564# NXT_RESUMEs should be 8.
4565OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
213615b3
NS
4566
4567$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4568cat 2.expected | cut -c -48 > expout
4569AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4570# Skipping the IPv4 checksum.
4571cat 2.expected | cut -c 53- > expout
4572AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4573
4574reset_pcap_file hv1-vif1 hv1/vif1
4575reset_pcap_file hv1-vif2 hv1/vif2
4576rm -f 1.expected
4577rm -f 2.expected
4578
4579# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4580# The packet should not be received by ovn-controller.
fcc3c93f 4581ciaddr=`ip_to_hex 0 0 0 0`
213615b3
NS
4582src_ip=`ip_to_hex 10 0 0 6`
4583dst_ip=`ip_to_hex 10 0 0 4`
fcc3c93f 4584test_dhcp 2 f00000000002 03 $ciaddr 0 0 1 $src_ip $dst_ip 1
213615b3 4585
fcc3c93f
GS
4586# NXT_RESUMEs should be 8.
4587OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
213615b3
NS
4588
4589# vif1-tx.pcap should have received the DHCPv4 request packet
4590OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4591
281977f7 4592as hv1
33ac3c83
NS
4593OVS_APP_EXIT_AND_WAIT([ovn-controller])
4594OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4595OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4596
4597as ovn-sb
4598OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4599
4600as ovn-nb
4601OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4602
4603as northd
4604OVS_APP_EXIT_AND_WAIT([ovn-northd])
4605
4606as main
4607OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4608OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4609
4610AT_CLEANUP
4611
40df4566 4612AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
4613AT_SKIP_IF([test $HAVE_PYTHON = no])
4614ovn_start
4615
4616ovn-nbctl ls-add ls1
4617ovn-nbctl lsp-add ls1 ls1-lp1 \
4618-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4619
4620ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4621
4622ovn-nbctl lsp-add ls1 ls1-lp2 \
4623-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4624
4625ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4626
40df4566
ZKL
4627ovn-nbctl lsp-add ls1 ls1-lp3 \
4628-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4629
4630ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4631
9060fc9a
MM
4632d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4633options="\"server_id\"=\"00:00:00:10:00:01\"")"
4634
4635ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4636ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4637
4638d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4639options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
33ac3c83 4640
9060fc9a 4641ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
40df4566 4642
33ac3c83
NS
4643ovn-nbctl ls-add ls2
4644ovn-nbctl lsp-add ls2 ls2-lp1 \
4645-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4646ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4647ovn-nbctl lsp-add ls2 ls2-lp2 \
4648-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4649ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4650
4651net_add n1
4652sim_add hv1
4653
4654as hv1
4655ovs-vsctl add-br br-phys
4656ovn_attach n1 br-phys 192.168.0.1
4657ovs-vsctl -- add-port br-int hv1-vif1 -- \
4658 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4659 options:tx_pcap=hv1/vif1-tx.pcap \
4660 options:rxq_pcap=hv1/vif1-rx.pcap \
4661 ofport-request=1
4662
4663ovs-vsctl -- add-port br-int hv1-vif2 -- \
4664 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4665 options:tx_pcap=hv1/vif2-tx.pcap \
4666 options:rxq_pcap=hv1/vif2-rx.pcap \
4667 ofport-request=2
4668
4669ovs-vsctl -- add-port br-int hv1-vif3 -- \
4670 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4671 options:tx_pcap=hv1/vif3-tx.pcap \
4672 options:rxq_pcap=hv1/vif3-rx.pcap \
4673 ofport-request=3
4674
4675ovs-vsctl -- add-port br-int hv1-vif4 -- \
4676 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4677 options:tx_pcap=hv1/vif4-tx.pcap \
4678 options:rxq_pcap=hv1/vif4-rx.pcap \
4679 ofport-request=4
4680
40df4566
ZKL
4681ovs-vsctl -- add-port br-int hv1-vif5 -- \
4682 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4683 options:tx_pcap=hv1/vif5-tx.pcap \
4684 options:rxq_pcap=hv1/vif5-rx.pcap \
4685 ofport-request=5
4686
74868f2c 4687OVN_POPULATE_ARP
33ac3c83
NS
4688
4689sleep 2
4690
4691trim_zeros() {
4692 sed 's/\(00\)\{1,\}$//'
4693}
4694
4695# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4696# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4697# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4698# packet should be received twice (one from ovn-controller and the other
4699# from the "ovs-ofctl monitor br-int resume"
4700test_dhcpv6() {
4701 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
2e5fceb0
NS
4702 if test $msg_code != 0b; then
4703 req_len=2a
4704 else
4705 req_len=1a
4706 fi
4707 local request=ffffffffffff${src_mac}86dd0000000000${req_len}1101${src_lla}
33ac3c83 4708 # dst ip ff02::1:2
ab187e7e 4709 request=${request}ff020000000000000000000000010002
33ac3c83 4710 # udp header and dhcpv6 header
2e5fceb0 4711 request=${request}0222022300${req_len}ffff${msg_code}010203
33ac3c83 4712 # Client identifier
ab187e7e 4713 request=${request}0001000a00030001${src_mac}
2e5fceb0
NS
4714 # Add IA-NA (Identity Association for Non Temporary Address) if msg_code
4715 # is not 11 (information request packet)
4716 if test $msg_code != 0b; then
4717 request=${request}0003000c0102030400000e1000001518
4718 fi
33ac3c83
NS
4719 shift; shift; shift; shift; shift;
4720 if test $offer_ip != 0; then
4721 local server_mac=000000100001
4722 local server_lla=fe80000000000000020000fffe100001
4723 local reply_code=07
4724 if test $msg_code = 01; then
4725 reply_code=02
4726 fi
40df4566
ZKL
4727 local msg_len=54
4728 if test $offer_ip = 1; then
4729 msg_len=28
4730 fi
4731 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4732 # udp header and dhcpv6 header
ab187e7e 4733 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4734 # Client identifier
ab187e7e 4735 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4736 # IA-NA
40df4566 4737 if test $offer_ip != 1; then
ab187e7e 4738 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4739 fi
33ac3c83 4740 # Server identifier
ab187e7e 4741 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4742 echo $reply | trim_zeros >> $inport.expected
4743 else
4744 for outport; do
4745 echo $request | trim_zeros >> $outport.expected
4746 done
4747 fi
4748
4749 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4750}
4751
4752reset_pcap_file() {
4753 local iface=$1
4754 local pcap_file=$2
4755 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4756options:rxq_pcap=dummy-rx.pcap
4757 rm -f ${pcap_file}*.pcap
4758 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4759options:rxq_pcap=${pcap_file}-rx.pcap
4760}
4761
4762AT_CAPTURE_FILE([ofctl_monitor0.log])
4763as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4764--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4765
4766echo "---------NB dump-----"
4767ovn-nbctl show
4768echo "---------------------"
4769echo "---------SB dump-----"
4770ovn-sbctl list datapath_binding
4771echo "---------------------"
4772ovn-sbctl list logical_flow
4773echo "---------------------"
4774
4775echo "---------------------"
4776ovn-sbctl dump-flows
4777echo "---------------------"
4778
4779echo "------ hv1 dump ----------"
4780as hv1 ovs-ofctl dump-flows br-int
4781
4782src_mac=f00000000001
4783src_lla=fe80000000000000f20000fffe000001
4784offer_ip=ae700000000000000000000000000004
4785test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4786
4787# NXT_RESUMEs should be 1.
4788OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4789
4790$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4791# cat 1.expected | trim_zeros > expout
4792cat 1.expected | cut -c -120 > expout
4793AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4794# Skipping the UDP checksum
4795cat 1.expected | cut -c 125- > expout
4796AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4797
4798rm 1.expected
4799
4800# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4801# without any modifications and the packet should be received by ls1-lp1.
4802# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4803# resume and the other from ovs-ofctl monitor resume.
4804
4805reset_pcap_file hv1-vif1 hv1/vif1
4806reset_pcap_file hv1-vif2 hv1/vif2
4807
4808src_mac=f00000000002
4809src_lla=fe80000000000000f20000fffe000002
4810offer_ip=ae700000000000000000000000000005
4811# Set invalid msg_type
4812
4813test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4814
4815# NXT_RESUMEs should be 2.
4816OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4817
4818# vif2-tx.pcap should not have received the DHCPv6 reply packet
4819rm 2.packets
4820$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4821AT_CHECK([cat 2.packets], [0], [])
4822
4823# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4824$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4825cat 1.expected > expout
4826AT_CHECK([cat 1.packets], [0], [expout])
4827
4828# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4829# There should be no DHCPv6 reply from ovn-controller and the request packet
4830# should be received by ls2-lp2.
4831
4832src_mac=f00000000003
4833src_lla=fe80000000000000f20000fffe000003
4834test_dhcpv6 3 $src_mac $src_lla 01 0 4
4835
4836# NXT_RESUMEs should be 2 only.
4837OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4838
4839# vif3-tx.pcap should not have received the DHCPv6 reply packet
4840$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4841AT_CHECK([cat 3.packets], [0], [])
4842
4843# vif4-tx.pcap should have received the DHCPv6 request packet
4844$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4845cat 4.expected > expout
4846AT_CHECK([cat 4.packets], [0], [expout])
4847
40df4566 4848# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
2e5fceb0 4849# The DHCPv6 reply shouldn't contain offer_ip.
40df4566
ZKL
4850src_mac=f00000000022
4851src_lla=fe80000000000000f20000fffe000022
4852reset_pcap_file hv1-vif5 hv1/vif5
4853test_dhcpv6 5 $src_mac $src_lla 01 1 5
4854
4855# NXT_RESUMEs should be 3.
4856OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4857
4858$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4859# Skipping the UDP checksum
4860cat 5.expected | cut -c 1-120,125- > expout
2e5fceb0
NS
4861AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4862
4863# Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
4864# shouldn't contain offer_ip
4865src_mac=f00000000022
4866src_lla=fe80000000000000f20000fffe000022
4867reset_pcap_file hv1-vif5 hv1/vif5
4868rm -f 5.expected
4869test_dhcpv6 5 $src_mac $src_lla 0b 1 5
4870
4871# NXT_RESUMEs should be 4.
4872OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4873
4874$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap |
4875trim_zeros > 5.packets
4876# Skipping the UDP checksum
4877cat 5.expected | cut -c 1-120,125- > expout
40df4566
ZKL
4878AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4879
33ac3c83 4880as hv1
281977f7
NS
4881OVS_APP_EXIT_AND_WAIT([ovn-controller])
4882OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4883OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4884
4885as ovn-sb
4886OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4887
4888as ovn-nb
4889OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4890
4891as northd
4892OVS_APP_EXIT_AND_WAIT([ovn-northd])
4893
4894as main
4895OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4896OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4897
4898AT_CLEANUP
4899
c1645003 4900AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4901AT_SKIP_IF([test $HAVE_PYTHON = no])
4902ovn_start
4903
4904# Logical network:
4905# Two LRs - R1 and R2 that are connected to each other via LS "join"
4906# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4907# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4908# R2 is a gateway router.
4909
4910
4911
4912# Create two hypervisor and create OVS ports corresponding to logical ports.
4913net_add n1
4914
4915sim_add hv1
4916as hv1
4917ovs-vsctl add-br br-phys
4918ovn_attach n1 br-phys 192.168.0.1
4919ovs-vsctl -- add-port br-int hv1-vif1 -- \
4920 set interface hv1-vif1 external-ids:iface-id=foo1 \
4921 options:tx_pcap=hv1/vif1-tx.pcap \
4922 options:rxq_pcap=hv1/vif1-rx.pcap \
4923 ofport-request=1
4924
4925
4926sim_add hv2
4927as hv2
4928ovs-vsctl add-br br-phys
4929ovn_attach n1 br-phys 192.168.0.2
4930ovs-vsctl -- add-port br-int hv2-vif1 -- \
4931 set interface hv2-vif1 external-ids:iface-id=alice1 \
4932 options:tx_pcap=hv2/vif1-tx.pcap \
4933 options:rxq_pcap=hv2/vif1-rx.pcap \
4934 ofport-request=1
4935
4936# Pre-populate the hypervisors' ARP tables so that we don't lose any
4937# packets for ARP resolution (native tunneling doesn't queue packets
4938# for ARP resolution).
74868f2c 4939OVN_POPULATE_ARP
c1645003
GS
4940
4941ovn-nbctl create Logical_Router name=R1
4942ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4943
ea46a4e9
JP
4944ovn-nbctl ls-add foo
4945ovn-nbctl ls-add alice
4946ovn-nbctl ls-add join
c1645003
GS
4947
4948# Connect foo to R1
31114af7 4949ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4950ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4951 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4952
4953# Connect alice to R2
31114af7 4954ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4955ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4956 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4957
4958# Connect R1 to join
31114af7 4959ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4960ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4961 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4962
4963# Connect R2 to join
31114af7 4964ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4965ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4966 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4967
4968
4969#install static routes
4970ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4971ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4972R1 static_routes @lrt
4973
4974ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4975ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4976R2 static_routes @lrt
4977
4978# Create logical port foo1 in foo
31ed1192
JP
4979ovn-nbctl lsp-add foo foo1 \
4980-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4981
4982# Create logical port alice1 in alice
31ed1192
JP
4983ovn-nbctl lsp-add alice alice1 \
4984-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4985
4986
4987# Allow some time for ovn-northd and ovn-controller to catch up.
4988# XXX This should be more systematic.
4989sleep 2
4990
4991ip_to_hex() {
4992 printf "%02x%02x%02x%02x" "$@"
4993}
c1645003
GS
4994
4995# Send ip packets between foo1 and alice1
4996src_mac="f00000010203"
4997dst_mac="000001010203"
4998src_ip=`ip_to_hex 192 168 1 2`
4999dst_ip=`ip_to_hex 172 16 1 2`
5000packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5001
5002echo "---------NB dump-----"
5003ovn-nbctl show
5004echo "---------------------"
5005ovn-nbctl list logical_router
5006echo "---------------------"
5007ovn-nbctl list logical_router_port
5008echo "---------------------"
5009
5010echo "---------SB dump-----"
5011ovn-sbctl list datapath_binding
5012echo "---------------------"
5013ovn-sbctl list port_binding
5014echo "---------------------"
5015ovn-sbctl dump-flows
5016echo "---------------------"
5017ovn-sbctl list chassis
5018ovn-sbctl list encap
5019echo "---------------------"
5020
c1645003
GS
5021# Packet to Expect at alice1
5022src_mac="000002010203"
5023dst_mac="f00000010204"
5024src_ip=`ip_to_hex 192 168 1 2`
5025dst_ip=`ip_to_hex 172 16 1 2`
5026expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
5027
5028
5029as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5030as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
5031
ab39371d
RM
5032echo "------ hv1 dump after packet 1 ----------"
5033as hv1 ovs-ofctl show br-int
5034as hv1 ovs-ofctl dump-flows br-int
5035echo "------ hv2 dump after packet 1 ----------"
5036as hv2 ovs-ofctl show br-int
5037as hv2 ovs-ofctl dump-flows br-int
5038echo "----------------------------"
5039
49d7c759
BP
5040echo $expected > expected
5041OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 5042
34114cf8
GS
5043# Delete the router and re-create it. Things should work as before.
5044ovn-nbctl lr-del R2
5045ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5046# Connect alice to R2
5047ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5048# Connect R2 to join
5049ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
5050
5051ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5052ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5053R2 static_routes @lrt
5054
5055# Wait for ovn-controller to catch up.
5056sleep 1
5057
5058# Send the packet again.
5059as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
5060
5061echo "------ hv1 dump after packet 2 ----------"
5062as hv1 ovs-ofctl show br-int
5063as hv1 ovs-ofctl dump-flows br-int
5064echo "------ hv2 dump after packet 2 ----------"
5065as hv2 ovs-ofctl show br-int
5066as hv2 ovs-ofctl dump-flows br-int
5067echo "----------------------------"
5068
49d7c759
BP
5069echo $expected >> expected
5070OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 5071
7a8f15e0 5072OVN_CLEANUP([hv1],[hv2])
c1645003
GS
5073
5074AT_CLEANUP
bb3c4568
FF
5075
5076AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5077AT_KEYWORDS([router-icmp-reply])
5078AT_SKIP_IF([test $HAVE_PYTHON = no])
5079ovn_start
5080
5081# Logical network:
5082# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5083# and has switch ls2 (172.16.1.0/24) connected to it.
5084
fa2a27b2 5085ovn-nbctl lr-add R1
bb3c4568 5086
ea46a4e9
JP
5087ovn-nbctl ls-add ls1
5088ovn-nbctl ls-add ls2
bb3c4568
FF
5089
5090# Connect ls1 to R1
31114af7 5091ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 5092ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 5093 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
5094
5095# Connect ls2 to R1
31114af7 5096ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 5097ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 5098 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
5099
5100# Create logical port ls1-lp1 in ls1
31ed1192
JP
5101ovn-nbctl lsp-add ls1 ls1-lp1 \
5102-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
5103
5104# Create logical port ls2-lp1 in ls2
31ed1192
JP
5105ovn-nbctl lsp-add ls2 ls2-lp1 \
5106-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
5107
5108# Create one hypervisor and create OVS ports corresponding to logical ports.
5109net_add n1
5110
5111sim_add hv1
5112as hv1
5113ovs-vsctl add-br br-phys
5114ovn_attach n1 br-phys 192.168.0.1
5115ovs-vsctl -- add-port br-int vif1 -- \
5116 set interface vif1 external-ids:iface-id=ls1-lp1 \
5117 options:tx_pcap=hv1/vif1-tx.pcap \
5118 options:rxq_pcap=hv1/vif1-rx.pcap \
5119 ofport-request=1
5120
5121ovs-vsctl -- add-port br-int vif2 -- \
5122 set interface vif2 external-ids:iface-id=ls2-lp1 \
5123 options:tx_pcap=hv1/vif2-tx.pcap \
5124 options:rxq_pcap=hv1/vif2-rx.pcap \
5125 ofport-request=1
5126
5127
5128# Allow some time for ovn-northd and ovn-controller to catch up.
5129# XXX This should be more systematic.
5130sleep 1
5131
5132
5133ip_to_hex() {
5134 printf "%02x%02x%02x%02x" "$@"
5135}
bb3c4568
FF
5136for i in 1 2; do
5137 : > vif$i.expected
5138done
5139# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
5140#
5141# Causes a packet to be received on INPORT. The packet is an ICMPv4
5142# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
5143# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
5144# provided, then it should be the ip and icmp checksums of the packet
5145# responded; otherwise, no reply is expected.
5146# In the absence of an ip checksum calculation helpers, this relies
5147# on the caller to provide the checksums for the ip and icmp headers.
5148# XXX This should be more systematic.
5149#
5150# INPORT is an lport number, e.g. 11 for vif11.
5151# ETH_SRC and ETH_DST are each 12 hex digits.
5152# IPV4_SRC and IPV4_DST are each 8 hex digits.
5153# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
5154# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
5155test_ipv4_icmp_request() {
5156 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
5157 local exp_ip_chksum=$8 exp_icmp_chksum=$9
5158 shift; shift; shift; shift; shift; shift; shift
5159 shift; shift
5160
5161 # Use ttl to exercise section 4.2.2.9 of RFC1812
5162 local ip_ttl=01
5163 local icmp_id=5fbf
5164 local icmp_seq=0001
5165 local icmp_data=$(seq 1 56 | xargs printf "%02x")
5166 local icmp_type_code_request=0800
5167 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5168 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
5169
5170 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
5171 if test X$exp_icmp_chksum != X; then
5172 # Expect to receive the reply, if any. In same port where packet was sent.
5173 # Note: src and dst fields are expected to be reversed.
5174 local icmp_type_code_response=0000
5175 local reply_icmp_ttl=fe
5176 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5177 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
5178 echo $reply >> vif$inport.expected
5179 fi
5180}
5181
5182# Send ping packet to router's ip addresses, from each of the 2 logical ports.
5183rtr_l1_ip=$(ip_to_hex 192 168 1 1)
5184rtr_l2_ip=$(ip_to_hex 172 16 1 1)
5185l1_ip=$(ip_to_hex 192 168 1 2)
5186l2_ip=$(ip_to_hex 172 16 1 2)
5187
5188# Ping router ip address that is on same subnet as the logical port
5189test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
5190test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
5191
5192# Ping router ip address that is on the other side of the logical ports
5193test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
5194test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
5195
5196echo "---------NB dump-----"
5197ovn-nbctl show
5198echo "---------------------"
5199ovn-nbctl list logical_router
5200echo "---------------------"
5201ovn-nbctl list logical_router_port
5202echo "---------------------"
5203
5204echo "---------SB dump-----"
5205ovn-sbctl list datapath_binding
5206echo "---------------------"
5207ovn-sbctl list logical_flow
5208echo "---------------------"
5209
5210echo "------ hv1 dump ----------"
5211as hv1 ovs-ofctl dump-flows br-int
5212
5213# Now check the packets actually received against the ones expected.
5214for inport in 1 2; do
49d7c759 5215 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
5216done
5217
7a8f15e0 5218OVN_CLEANUP([hv1])
bb3c4568
FF
5219
5220AT_CLEANUP
94f79fcb
RB
5221
5222# 1 hypervisor, 1 port
5223# make sure that the port state is properly set to up and back down
5224# when created and deleted.
5225AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
5226ovn_start
5227
5228ovn-nbctl ls-add ls1
5229ovn-nbctl lsp-add ls1 lp1
5230ovn-nbctl lsp-set-addresses lp1 unknown
5231
5232net_add n1
5233sim_add hv1
5234as hv1 ovs-vsctl add-br br-phys
5235as hv1 ovn_attach n1 br-phys 192.168.0.1
5236
5237as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5238OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5239
5240as hv1 ovs-vsctl del-port br-int vif1
5241OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5242
7a8f15e0 5243OVN_CLEANUP([hv1])
94f79fcb 5244
94f79fcb 5245AT_CLEANUP
e75451fe 5246
ccc6e1db
FF
5247# 1 hypervisor, 1 port
5248# make sure that the OF rules created to support a datapath are added/cleared
5249# when logical switch is created and removed.
5250AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 5251AT_KEYWORDS([cleanup])
ccc6e1db
FF
5252ovn_start
5253
5254net_add n1
5255sim_add hv1
5256as hv1 ovs-vsctl add-br br-phys
5257as hv1 ovn_attach n1 br-phys 192.168.0.1
5258
5259# This shell function checks if OF rules in br-int have clauses
5260# related to OVN datapaths. The caller determines if it should find
5261# a match in the output, or not.
5262#
5263# EXPECT_DATAPATH param determines whether flows that refer to
5264# datapath to should be present or not. 0 means
5265# they should not be.
5266# STAGE_INFO param is a simple string to help identify the stage
5267# in the test when this function was invoked.
5268test_datapath_in_of_rules() {
5269 local expect_datapath=$1 stage_info=$2
5270 echo "------ ovn-nbctl show ${stage_info} ------"
5271 ovn-nbctl show
5272 echo "------ ovn-sbctl show ${stage_info} ------"
5273 ovn-sbctl show
5274 echo "------ OF rules ${stage_info} ------"
5275 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
5276 # if there is a datapath mentioned in the output, check for the
5277 # magic keyword that represents one, based on the exit status of
5278 # a quiet grep
5279 if test $expect_datapath != 0; then
4618b102 5280 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 5281 else
4618b102 5282 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
5283 fi
5284}
5285
5286test_datapath_in_of_rules 0 "before ls+port create"
5287
5288ovn-nbctl ls-add ls1
5289ovn-nbctl lsp-add ls1 lp1
5290ovn-nbctl lsp-set-addresses lp1 unknown
5291
5292as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5293OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5294
5295test_datapath_in_of_rules 1 "after port is bound"
5296
5297as hv1 ovs-vsctl del-port br-int vif1
5298OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5299
5300ovn-nbctl lsp-set-addresses lp1
5301ovn-nbctl lsp-del lp1
5302ovn-nbctl ls-del ls1
5303
5304# wait for earlier changes to take effect
5305AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
5306
5307# ensure OF rules are no longer present. There used to be a bug here.
5308test_datapath_in_of_rules 0 "after lport+ls removal"
5309
5310OVN_CLEANUP([hv1])
5311
5312AT_CLEANUP
5313
f8a8db39 5314AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
5315AT_SKIP_IF([test $HAVE_PYTHON = no])
5316ovn_start
5317
5318#TODO: since patch port for IPv6 logical router port is not ready not,
5319# so we are not going to test vifs on different lswitches cases. Try
5320# to update for that once relevant stuff implemented.
5321
5322# In this test cases we create 1 lswitch, it has 2 VIF ports attached
5323# with. NS packet we test, from one VIF for another VIF, will be replied
5324# by local ovn-controller, but not by target VIF.
5325
5326# Create hypervisors and logical switch lsw0.
5327ovn-nbctl ls-add lsw0
5328net_add n1
5329sim_add hv1
5330as hv1
5331ovs-vsctl add-br br-phys
5332ovn_attach n1 br-phys 192.168.0.2
5333
5334# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5335ovs-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
5336ovn-nbctl lsp-add lsw0 lp1
5337ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5338ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5339
5340# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5341ovs-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
5342ovn-nbctl lsp-add lsw0 lp2
5343ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5344ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5345
5346# Add ACL rule for ICMPv6 on lsw0
5347ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5348ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5349ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5350
5351# Allow some time for ovn-northd and ovn-controller to catch up.
5352# XXX This should be more systematic.
5353sleep 1
5354
5355# Given the name of a logical port, prints the name of the hypervisor
5356# on which it is located.
5357vif_to_hv() {
5358 echo hv1${1%?}
5359}
e75451fe
ZKL
5360for i in 1 2; do
5361 : > $i.expected
5362done
5363
5364# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5365# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5366# vif2 will not receive NS packet, since ovn-controller will reply for it.
5367ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5368na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5369
5370as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 5371echo $na_packet >> 1.expected
e75451fe 5372
e75451fe
ZKL
5373echo "------ hv1 dump ------"
5374as hv1 ovs-vsctl show
5375as hv1 ovs-ofctl -O OpenFlow13 show br-int
5376as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5377
5378for i in 1 2; do
49d7c759 5379 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
5380done
5381
7a8f15e0 5382OVN_CLEANUP([hv1])
e75451fe
ZKL
5383
5384AT_CLEANUP
7417d147
RM
5385
5386AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
5387ovn_start
5388
5389net_add n1
5390
5391sim_add hv1
5392as hv1
5393ovs-vsctl add-br br-phys
5394ovn_attach n1 br-phys 192.168.0.1
5395
5396row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5397ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5398ovn-nbctl destroy Address_Set $row
5399
5400sleep 1
5401
5402# A bug previously existed in the address set support code
5403# that caused ovn-controller to crash after an address set
5404# was updated and then removed. This test case ensures
5405# that ovn-controller is at least still running after
5406# creating, updating, and deleting an address set.
5407AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5408
5409OVN_CLEANUP([hv1])
5410
5411AT_CLEANUP
8639f9be
ND
5412
5413AT_SETUP([ovn -- ipam])
8639f9be
ND
5414AT_SKIP_IF([test $HAVE_PYTHON = no])
5415ovn_start
5416
5417# Add a port to a switch that does not have a subnet set, then set the
5418# subnet which should result in an address being allocated for the port.
5419ovn-nbctl ls-add sw0
5420ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 5421ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be 5422AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
c814545b 5423 ["0a:00:00:a8:01:03 192.168.1.2"
8639f9be
ND
5424])
5425
5426# Add 9 more ports to sw0, addresses should all be unique.
5427for n in `seq 1 9`; do
11547f85 5428 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5429done
5430AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
c814545b 5431 ["0a:00:00:a8:01:04 192.168.1.3"
8639f9be
ND
5432])
5433AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
c814545b 5434 ["0a:00:00:a8:01:05 192.168.1.4"
8639f9be
ND
5435])
5436AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
c814545b 5437 ["0a:00:00:a8:01:06 192.168.1.5"
8639f9be
ND
5438])
5439AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
c814545b 5440 ["0a:00:00:a8:01:07 192.168.1.6"
8639f9be
ND
5441])
5442AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
c814545b 5443 ["0a:00:00:a8:01:08 192.168.1.7"
8639f9be
ND
5444])
5445AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
c814545b 5446 ["0a:00:00:a8:01:09 192.168.1.8"
8639f9be
ND
5447])
5448AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
c814545b 5449 ["0a:00:00:a8:01:0a 192.168.1.9"
8639f9be
ND
5450])
5451AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
c814545b 5452 ["0a:00:00:a8:01:0b 192.168.1.10"
8639f9be
ND
5453])
5454AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
c814545b 5455 ["0a:00:00:a8:01:0c 192.168.1.11"
8639f9be
ND
5456])
5457
5458# Trying similar tests with a second switch. MAC addresses should be unique
5459# across both switches but IP's only need to be unique within the same switch.
5460ovn-nbctl ls-add sw1
5461ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 5462ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be 5463AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
c814545b 5464 ["0a:00:00:a8:01:0d 192.168.1.2"
8639f9be
ND
5465])
5466
5467for n in `seq 11 19`; do
11547f85 5468 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5469done
5470AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
c814545b 5471 ["0a:00:00:a8:01:0e 192.168.1.3"
8639f9be
ND
5472])
5473AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
c814545b 5474 ["0a:00:00:a8:01:0f 192.168.1.4"
8639f9be
ND
5475])
5476AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
c814545b 5477 ["0a:00:00:a8:01:10 192.168.1.5"
8639f9be
ND
5478])
5479AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
c814545b 5480 ["0a:00:00:a8:01:11 192.168.1.6"
8639f9be
ND
5481])
5482AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
c814545b 5483 ["0a:00:00:a8:01:12 192.168.1.7"
8639f9be
ND
5484])
5485AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
c814545b 5486 ["0a:00:00:a8:01:13 192.168.1.8"
8639f9be
ND
5487])
5488AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
c814545b 5489 ["0a:00:00:a8:01:14 192.168.1.9"
8639f9be
ND
5490])
5491AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
c814545b 5492 ["0a:00:00:a8:01:15 192.168.1.10"
8639f9be
ND
5493])
5494AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
c814545b 5495 ["0a:00:00:a8:01:16 192.168.1.11"
8639f9be
ND
5496])
5497
5498# Change a port's address to test for multiple ip's for a single address entry
5499# and addresses set by the user.
c814545b 5500ovn-nbctl lsp-set-addresses p0 "0a:00:00:a8:01:17 192.168.1.2 192.168.1.12 192.168.1.14"
11547f85 5501ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be 5502AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
c814545b 5503 ["0a:00:00:a8:01:18 192.168.1.13"
8639f9be
ND
5504])
5505
5506# Test for logical router port address management.
5507ovn-nbctl create Logical_Router name=R1
5508ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
c814545b 5509network="192.168.1.1/24" mac=\"0a:00:00:a8:01:19\" \
8639f9be
ND
5510-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5511-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 5512ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be 5513AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
c814545b 5514 ["0a:00:00:a8:01:1a 192.168.1.15"
8639f9be
ND
5515])
5516
5517# Test for address reuse after logical port is deleted.
5518ovn-nbctl lsp-del p0
11547f85 5519ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be 5520AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
c814545b 5521 ["0a:00:00:a8:01:03 192.168.1.2"
8639f9be
ND
5522])
5523
5524# Test for multiple addresses to one logical port.
5525ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
c814545b 5526"0a:00:00:a8:01:1b 192.168.1.12" "0a:00:00:a8:01:1c 192.168.1.14"
11547f85 5527ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be 5528AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
c814545b 5529 ["0a:00:00:a8:01:17 192.168.1.16"
8639f9be
ND
5530])
5531
5532# Test for exhausting subnet address space.
5533ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 5534ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be 5535AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
c814545b 5536 ["0a:00:00:10:01:03 172.16.1.2"
8639f9be
ND
5537])
5538
11547f85 5539ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 5540AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
c814545b 5541 ["0a:00:00:00:00:01"
8639f9be
ND
5542])
5543
5544# Test that address management does not add duplicate MAC for lsp/lrp peers.
5545ovn-nbctl create Logical_Router name=R2
5546ovn-nbctl ls-add sw3
5547ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
c814545b 5548"0a:00:00:a8:01:18"
8639f9be 5549ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
c814545b 5550network="192.168.2.1/24" mac=\"0a:00:00:a8:01:18\" \
8639f9be
ND
5551-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5552-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 5553ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be 5554AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
c814545b 5555 ["0a:00:00:a8:01:1d 192.168.1.17"
8639f9be
ND
5556])
5557
6374d518
LR
5558# Test static MAC address with dynamically allocated IP
5559ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5560"fe:dc:ba:98:76:54 dynamic"
5561AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5562 ["fe:dc:ba:98:76:54 192.168.1.18"
5563])
5564
6c4f7a8a
NS
5565# Update the static MAC address with dynamically allocated IP and check
5566# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5567ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
6c4f7a8a
NS
5568
5569AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5570 ["fe:dc:ba:98:76:55 192.168.1.18"
5571])
5572
5573ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5574AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
c814545b 5575 ["0a:00:00:a8:01:1e 192.168.1.18"
6c4f7a8a
NS
5576])
5577
5578ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5579AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5580 ["fe:dc:ba:98:76:56 192.168.1.18"
5581])
5582
161ea2c8
NS
5583
5584# Test the exclude_ips from the IPAM list
5585ovn-nbctl --wait=sb set logical_switch sw0 \
5586other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5587
5588ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5589"dynamic"
5590# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5591AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
c814545b 5592 ["0a:00:00:a8:01:1e 192.168.1.20"
161ea2c8
NS
5593])
5594
5595ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5596"dynamic"
5597# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5598AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
c814545b 5599 ["0a:00:00:a8:01:1f 192.168.1.22"
161ea2c8
NS
5600])
5601
5602ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5603"dynamic"
5604# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5605AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
c814545b 5606 ["0a:00:00:a8:01:34 192.168.1.51"
161ea2c8
NS
5607])
5608
5609# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5610ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5611ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5612"dynamic"
5613AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
c814545b 5614 ["0a:00:00:a8:01:20 192.168.1.19"
161ea2c8
NS
5615])
5616
5617# Set invalid data in exclude_ips list. It should be ignored.
5618ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5619ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5620"dynamic"
5621# 192.168.1.21 should be assigned as that's the next free one.
5622AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
c814545b 5623 ["0a:00:00:a8:01:21 192.168.1.21"
161ea2c8
NS
5624])
5625
5626# Clear the dynamic addresses assignment request.
5627ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5628AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5629 [[[]]
5630])
5631
7cc0741e
NS
5632# Set IPv6 prefix
5633ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5634ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5635"dynamic"
5636
5637# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5638# - aef0::800:ff:fe00:26 (EUI64)
5639AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
c814545b 5640 ["0a:00:00:a8:01:21 192.168.1.21 aef0::800:ff:fea8:121"
7cc0741e
NS
5641])
5642
5643ovn-nbctl --wait=sb ls-add sw4
451624fe
MM
5644ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
5645-- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
7cc0741e
NS
5646ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5647"dynamic"
5648
5649AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
c814545b 5650 ["0a:00:00:a8:02:03 192.168.2.2 bef0::800:ff:fea8:203"
7cc0741e
NS
5651])
5652
5653ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5654"f0:00:00:00:10:12 dynamic"
5655
5656AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5657 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5658])
5659
451624fe
MM
5660# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5661# p40 should not have an IPv4 address since the pool is exhausted
7cc0741e
NS
5662ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5663"dynamic"
7cc0741e 5664AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
c814545b 5665 ["0a:00:00:00:00:02 bef0::800:ff:fe00:2"
451624fe
MM
5666])
5667
5668# Test dynamic changes on switch ports.
5669#
5670ovn-nbctl --wait=sb ls-add sw5
5671ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
5672"dynamic"
5673# p41 will start with nothing
5674AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
7cc0741e
NS
5675 [[[]]
5676])
5677
451624fe
MM
5678# Set a subnet. Now p41 should have an ipv4 address, too
5679ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5680AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
c814545b 5681 ["0a:00:00:a8:01:22 192.168.1.2"
451624fe 5682])
7cc0741e 5683
451624fe
MM
5684# Clear the other_config. The IPv4 address should be gone
5685ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5686AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5687 [[[]]
7cc0741e
NS
5688])
5689
451624fe
MM
5690# Set an IPv6 prefix. Now p41 should have an IPv6 address.
5691ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
7cc0741e 5692AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
c814545b 5693 ["0a:00:00:00:00:03 aef0::800:ff:fe00:3"
451624fe
MM
5694])
5695
5696# Change the MAC address to a static one. The IPv6 address should update.
5697ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
5698AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5699 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
5700])
5701
5702# Change the IPv6 prefix. The IPv6 address should update.
5703ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
5704AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5705 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
5706])
5707
5708# Clear the other_config. The IPv6 address should be gone
5709ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5710AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5711 [[[]]
5712])
5713
5714# Set the subnet again. Now p41 should get the IPv4 address again.
5715ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5716AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5717 ["f0:00:00:00:10:2b 192.168.1.2"
5718])
5719
451624fe
MM
5720# Add an excluded IP address that conflicts with p41. p41 should update.
5721ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
863fb61f 5722exclude_ips="192.168.1.2"
451624fe 5723AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
863fb61f 5724 ["f0:00:00:00:10:2b 192.168.1.3"
7cc0741e
NS
5725])
5726
282e5357
LB
5727# define a mac address prefix
5728ovn-nbctl ls-add sw6
5729ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22:33:44:55"
5730ovn-nbctl --wait=sb set Logical-Switch sw6 other_config:subnet=192.168.100.0/24
5731for n in $(seq 1 3); do
5732 ovn-nbctl --wait=sb lsp-add sw6 "p5$n" -- lsp-set-addresses "p5$n" dynamic
5733done
5734AT_CHECK([ovn-nbctl get Logical-Switch-Port p51 dynamic_addresses], [0],
c814545b 5735 ["00:11:22:a8:64:03 192.168.100.2"
282e5357
LB
5736])
5737AT_CHECK([ovn-nbctl get Logical-Switch-Port p52 dynamic_addresses], [0],
c814545b 5738 ["00:11:22:a8:64:04 192.168.100.3"
282e5357
LB
5739])
5740AT_CHECK([ovn-nbctl get Logical-Switch-Port p53 dynamic_addresses], [0],
c814545b 5741 ["00:11:22:a8:64:05 192.168.100.4"
282e5357
LB
5742])
5743
04438dbf
LB
5744# verify configuration order does not break IPAM/MACAM
5745ovn-nbctl ls-add sw7
5746for n in $(seq 1 3); do
5747 ovn-nbctl --wait=sb lsp-add sw7 "p7$n" -- lsp-set-addresses "p7$n" dynamic
5748done
5749ovn-nbctl --wait=sb set Logical-Switch sw7 other_config:ipv6_prefix="bef0::"
5750p71_addr=$(ovn-nbctl get Logical-Switch-Port p71 dynamic_addresses)
5751p72_addr=$(ovn-nbctl get Logical-Switch-Port p72 dynamic_addresses)
5752p73_addr=$(ovn-nbctl get Logical-Switch-Port p73 dynamic_addresses)
5753AT_CHECK([test "$p71_addr" != "$p72_addr"], [0], [])
5754AT_CHECK([test "$p71_addr" != "$p73_addr"], [0], [])
5755AT_CHECK([test "$p72_addr" != "$p73_addr"], [0], [])
5756
8639f9be
ND
5757as ovn-sb
5758OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5759
5760as ovn-nb
5761OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5762
5763as northd
5764OVS_APP_EXIT_AND_WAIT([ovn-northd])
5765
5766AT_CLEANUP
5767
5768AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5769AT_SKIP_IF([test $HAVE_PYTHON = no])
5770ovn_start
5771
5772ovn-nbctl lr-add R1
5773
5774# Test for a ping using dynamically allocated addresses.
5775ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5776ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5777
5778# Connect foo to R1
5779ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5780ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5781 options:router-port=foo \
5782 -- lsp-set-addresses rp-foo router
8639f9be
ND
5783
5784# Connect alice to R1
5785ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5786ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5787 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5788
5789# Create logical port foo1 in foo
fd3b31e9 5790ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5791-- lsp-set-addresses foo1 "dynamic"
c814545b 5792AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:a8:01:03 192.168.1.2"'], [0])
8639f9be
ND
5793
5794# Create logical port alice1 in alice
fd3b31e9 5795ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5796-- lsp-set-addresses alice1 "dynamic"
c814545b 5797AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:a8:02:03 192.168.2.2"'])
8639f9be
ND
5798
5799# Create logical port foo2 in foo
fd3b31e9 5800ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5801-- lsp-set-addresses foo2 "dynamic"
c814545b 5802AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:a8:01:04 192.168.1.3"'])
8639f9be
ND
5803
5804# Create a hypervisor and create OVS ports corresponding to logical ports.
5805net_add n1
5806
5807sim_add hv1
5808as hv1
5809ovs-vsctl add-br br-phys
5810ovn_attach n1 br-phys 192.168.0.1
5811ovs-vsctl -- add-port br-int hv1-vif1 -- \
5812 set interface hv1-vif1 external-ids:iface-id=foo1 \
5813 options:tx_pcap=hv1/vif1-tx.pcap \
5814 options:rxq_pcap=hv1/vif1-rx.pcap \
5815 ofport-request=1
5816
5817ovs-vsctl -- add-port br-int hv1-vif2 -- \
5818 set interface hv1-vif2 external-ids:iface-id=foo2 \
5819 options:tx_pcap=hv1/vif2-tx.pcap \
5820 options:rxq_pcap=hv1/vif2-rx.pcap \
5821 ofport-request=2
5822
5823ovs-vsctl -- add-port br-int hv1-vif3 -- \
5824 set interface hv1-vif3 external-ids:iface-id=alice1 \
5825 options:tx_pcap=hv1/vif3-tx.pcap \
5826 options:rxq_pcap=hv1/vif3-rx.pcap \
5827 ofport-request=3
5828
5829# Allow some time for ovn-northd and ovn-controller to catch up.
5830# XXX This should be more systematic.
5831sleep 1
5832
5833ip_to_hex() {
5834 printf "%02x%02x%02x%02x" "$@"
5835}
8639f9be
ND
5836
5837# Send ip packets between foo1 and foo2
c814545b
LB
5838src_mac="0a0000a80103"
5839dst_mac="0a0000a80104"
8639f9be
ND
5840src_ip=`ip_to_hex 192 168 1 2`
5841dst_ip=`ip_to_hex 192 168 1 3`
5842packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5843as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5844
5845# Send ip packets between foo1 and alice1
c814545b 5846src_mac="0a0000a80103"
8639f9be
ND
5847dst_mac="000000010203"
5848src_ip=`ip_to_hex 192 168 1 2`
5849dst_ip=`ip_to_hex 192 168 2 2`
5850packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5851as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5852
5853echo "---------NB dump-----"
5854ovn-nbctl show
5855echo "---------------------"
5856ovn-nbctl list logical_router
5857echo "---------------------"
5858ovn-nbctl list logical_router_port
5859echo "---------------------"
5860
5861echo "---------SB dump-----"
5862ovn-sbctl list datapath_binding
5863echo "---------------------"
5864ovn-sbctl list port_binding
5865echo "---------------------"
5866
5867echo "------ hv1 dump ----------"
5868as hv1 ovs-ofctl dump-flows br-int
5869
5870# Packet to Expect at foo2
c814545b
LB
5871src_mac="0a0000a80103"
5872dst_mac="0a0000a80104"
8639f9be
ND
5873src_ip=`ip_to_hex 192 168 1 2`
5874dst_ip=`ip_to_hex 192 168 1 3`
5875expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5876
e4543cfe
DDP
5877$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5878echo $expected > expout
8639f9be
ND
5879AT_CHECK([cat received1.packets], [0], [expout])
5880
5881# Packet to Expect at alice1
5882src_mac="000000010204"
c814545b 5883dst_mac="0a0000a80203"
8639f9be
ND
5884src_ip=`ip_to_hex 192 168 1 2`
5885dst_ip=`ip_to_hex 192 168 2 2`
5886expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5887
e4543cfe
DDP
5888$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5889echo $expected > expout
8639f9be
ND
5890AT_CHECK([cat received2.packets], [0], [expout])
5891
5892OVN_CLEANUP([hv1])
5893
5894AT_CLEANUP
f5792c3f
NS
5895
5896AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5897AT_KEYWORDS([vswitchd])
f5792c3f
NS
5898AT_SKIP_IF([test $HAVE_PYTHON = no])
5899ovn_start
5900
5901ovn-nbctl ls-add ls1
5902
5903ovn-nbctl lsp-add ls1 ls1-lp1 \
5904-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5905
5906ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5907
5908net_add n1
5909sim_add hv1
5910
5911as hv1
5912ovs-vsctl add-br br-phys
5913ovn_attach n1 br-phys 192.168.0.1
5914ovs-vsctl -- add-port br-int hv1-vif1 -- \
5915 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5916 options:tx_pcap=hv1/vif1-tx.pcap \
5917 options:rxq_pcap=hv1/vif1-rx.pcap \
5918 ofport-request=1
5919
74868f2c 5920OVN_POPULATE_ARP
f5792c3f
NS
5921sleep 2
5922
5923as hv1 ovs-vsctl show
5924
5925echo "---------------------"
5926ovn-sbctl dump-flows
5927echo "---------------------"
5928
5929echo "------ hv1 dump ----------"
5930as hv1 ovs-ofctl dump-flows br-int
5931total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5932
5933echo "Total flows before vswitchd restart = " $total_flows
5934
5935# Code taken from ovs-save utility
5936save_flows () {
5937 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5938 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5939 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5940 echo "EOF" >> restore_flows.sh
5941}
5942
5943restart_vswitchd () {
5944 restore_flows=$1
5945
5946 if test $restore_flows = true; then
5947 save_flows
5948 fi
5949
5950 as hv1
5951 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5952
5953 if test $restore_flows = true; then
5954 as hv1
5955 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5956 fi
5957
5958 as hv1
5959 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5960 ovs-ofctl dump-flows br-int
5961
5962 if test $restore_flows = true; then
5963 sh ./restore_flows.sh
5964 echo "Flows after restore"
5965 as hv1
5966 ovs-ofctl dump-flows br-int
5967 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5968 flow-restore-wait="true"
5969 fi
5970}
5971
5972# Save the flows, restart vswitchd and restore the flows
5973restart_vswitchd true
5974OVS_WAIT_UNTIL([
5975 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5976 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5977 test "${total_flows}" = "${total_flows_after_restart}"
5978])
5979
5980# Restart vswitchd without restoring
5981restart_vswitchd false
5982OVS_WAIT_UNTIL([
5983 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5984 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5985 test "${total_flows}" = "${total_flows_after_restart}"
5986])
5987
5988OVN_CLEANUP([hv1])
5989AT_CLEANUP
47021598
CSV
5990
5991AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5992AT_SKIP_IF([test $HAVE_PYTHON = no])
5993ovn_start
5994
5995# Topology: Two LSs - ls1 and ls2 are connected via router r0
5996
5997# Create logical switches
5998ovn-nbctl ls-add ls1
5999ovn-nbctl ls-add ls2
6000
6001# Create router
6002ovn-nbctl create Logical_Router name=lr0
6003
6004# Add router ls1p1 port to gateway router
6005ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
6006ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
6007 type=router options:router-port=lrp-ls1lp1 \
6008 addresses='"f0:00:00:00:00:01 192.168.0.1"'
6009
6010# Add router ls2p2 port to gateway router
6011ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
6012ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
6013 type=router options:router-port=lrp-ls2lp1 \
6014 addresses='"f0:00:00:00:00:02 192.168.1.1"'
6015
6016# Set default gateway (nexthop) to 192.168.1.254
6017ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
6018
6019# Create logical port ls1lp2 in ls1
6020ovn-nbctl lsp-add ls1 ls1lp2 \
6021-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
6022
6023# Create logical port ls2lp2 in ls2
6024ovn-nbctl lsp-add ls2 ls2lp2 \
6025-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
6026
6027net_add n1
6028sim_add hv1
6029as hv1
6030ovs-vsctl add-br br-phys
6031ovn_attach n1 br-phys 192.168.0.1
6032ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
6033 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
6034 options:tx_pcap=hv1/ls1lp2-tx.pcap \
6035 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
6036 ofport-request=1
6037ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
6038 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
6039 options:tx_pcap=hv1/ls2lp2-tx.pcap \
6040 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
6041 ofport-request=2
6042
6043# Allow some time for ovn-northd and ovn-controller to catch up.
6044# XXX This should be more systematic.
6045sleep 1
6046
6047echo "---------NB dump-----"
6048ovn-nbctl show
6049echo "---------------------"
6050ovn-nbctl list logical_router
6051echo "---------------------"
6052ovn-nbctl list logical_router_port
6053echo "---------------------"
6054
6055echo "---------SB dump-----"
6056ovn-sbctl list datapath_binding
6057echo "---------------------"
6058ovn-sbctl list port_binding
6059echo "---------------------"
6060ovn-sbctl dump-flows
6061echo "---------------------"
6062ovn-sbctl list chassis
6063ovn-sbctl list encap
6064echo "---------------------"
6065
6066echo "------Flows dump-----"
6067as hv1
6068ovs-ofctl dump-flows
6069echo "---------------------"
6070
6071ip_to_hex() {
6072 printf "%02x%02x%02x%02x" "$@"
6073}
6074
6075src_mac="f00000000003"
6076dst_mac="f00000000001"
6077src_ip=`ip_to_hex 192 168 0 2`
6078dst_ip=`ip_to_hex 8 8 8 8`
6079packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6080
6081# Send IP packet destined to 8.8.8.8 from lsp1lp2
6082as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
6083
6084trim_zeros() {
6085 sed 's/\(00\)\{1,\}$//'
6086}
6087
6088# ARP packet should be received with Target IP Address set to 192.168.1.254 and
6089# not 8.8.8.8
6090
6091$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
6092expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
6093echo $expected > expout
6094AT_CHECK([cat packets], [0], [expout])
6095cat packets
6096
6097OVN_CLEANUP([hv1])
6098
6099AT_CLEANUP
8439c2eb
CSV
6100
6101AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
6102AT_SKIP_IF([test $HAVE_PYTHON = no])
6103ovn_start
6104# Create logical switch
6105ovn-nbctl ls-add ls0
6106# Create gateway router
6107ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6108# Add router port to gateway router
6109ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6110ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 6111 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
6112# Add nat-address option
6113ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
6114
6115net_add n1
6116sim_add hv1
6117as hv1
6118ovs-vsctl \
6119 -- add-br br-phys \
6120 -- add-br br-eth0
6121
6122ovn_attach n1 br-phys 192.168.0.1
6123
6124AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6125AT_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])
6126
6127# Create a localnet port.
6128AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6129AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6130AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6131AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6132
6133
6134# Wait for packet to be received.
6135OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6136trim_zeros() {
6137 sed 's/\(00\)\{1,\}$//'
6138}
6139$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6140expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6141echo $expected > expout
6142AT_CHECK([sort packets], [0], [expout])
6143cat packets
6144
6145OVN_CLEANUP([hv1])
6146
6147AT_CLEANUP
6e31816f 6148
e914fb54
MS
6149AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6150AT_SKIP_IF([test $HAVE_PYTHON = no])
6151ovn_start
6152# Create logical switch
6153ovn-nbctl ls-add ls0
6154# Create gateway router
6155ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6156# Add router port to gateway router
6157ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6158ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 6159 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
6160# Add nat-address option
6161ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6162# Add NAT rules
6163AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6164AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6165# Add load balancers
6166AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6167AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6168AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6169AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6170
6171net_add n1
6172sim_add hv1
6173as hv1
6174ovs-vsctl \
6175 -- add-br br-phys \
6176 -- add-br br-eth0
6177
6178ovn_attach n1 br-phys 192.168.0.1
6179
6180AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6181AT_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])
6182
6183# Create a localnet port.
6184AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6185AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6186AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6187AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6188
6189
6190# Wait for packet to be received.
6191OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6192trim_zeros() {
6193 sed 's/\(00\)\{1,\}$//'
6194}
6195$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6196expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6197echo $expected > expout
6198expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6199echo $expected >> expout
6200expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6201echo $expected >> expout
6202AT_CHECK([sort packets], [0], [expout])
6203cat packets
6204
6205OVN_CLEANUP([hv1])
6206
6207AT_CLEANUP
6208
6e31816f 6209AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
6210ovn_start
6211net_add n1
6212sim_add hv1
6213as hv1
6214ovs-vsctl -- add-br br-phys
6215ovn_attach n1 br-phys 192.168.0.1
6216# Create logical switch ls0
6217ovn-nbctl ls-add ls0
6218# Create ports lp0, lp1 in ls0
6219ovn-nbctl lsp-add ls0 lp0
6220ovn-nbctl lsp-add ls0 lp1
6221ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6222ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6223dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6224ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6225ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6226ovn-sbctl find MAC_Binding
093aa761 6227# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
6228ovn-nbctl lsp-del lp0
6229ovn-sbctl find MAC_Binding
093aa761
BP
6230OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6231# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
6232ovn-nbctl ls-del ls0
6233ovn-sbctl find MAC_Binding
093aa761 6234OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
6235
6236OVN_CLEANUP([hv1])
6237
6238AT_CLEANUP
926c34fd
RM
6239
6240AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
6241AT_SKIP_IF([test $HAVE_PYTHON = no])
6242ovn_start
6243
6244# Logical network:
6245# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6246# connected to a router R1.
6247# foo has foo1 to act as a client.
6248# bar has bar1, bar2, bar3 to act as servers.
6249
6250net_add n1
6251
6252sim_add hv1
6253as hv1
6254ovs-vsctl add-br br-phys
6255ovn_attach n1 br-phys 192.168.0.1
6256for i in foo1 bar1 bar2 bar3; do
6257 ovs-vsctl -- add-port br-int $i -- \
6258 set interface $i external-ids:iface-id=$i \
6259 options:tx_pcap=hv1/$i-tx.pcap \
6260 options:rxq_pcap=hv1/$i-rx.pcap
6261done
6262
6263ovn-nbctl create Logical_Router name=R1
6264ovn-nbctl ls-add foo
6265ovn-nbctl ls-add bar
6266
6267# Connect foo to R1
6268ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6269ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6270 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6271
6272# Connect bar to R1
6273ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6274ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6275 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6276
6277# Create logical port foo1 in foo
6278ovn-nbctl lsp-add foo foo1 \
6279-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6280
6281# Create logical port bar1, bar2 and bar3 in bar
6282for i in `seq 1 3`; do
6283 ip=`expr $i + 1`
6284 ovn-nbctl lsp-add bar bar$i \
6285 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6286done
6287
6288OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6289
6290OVN_CLEANUP([hv1])
6291
6292AT_CLEANUP
b511690b
GS
6293
6294AT_SETUP([ovn -- tag allocation])
b511690b
GS
6295ovn_start
6296
6297AT_CHECK([ovn-nbctl ls-add ls0])
6298AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6299AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6300AT_CHECK([ovn-nbctl ls-add ls1])
6301
6302dnl When a tag is provided, no allocation is done
6303AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6304AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6305])
6306dnl The same 'tag' gets created in southbound database.
6307AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6308logical_port="c0"], [0], [3
6309])
6310
6311dnl Allocate tags and see it getting created in both NB and SB
6312AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6313AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6314])
6315AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6316logical_port="c1"], [0], [1
6317])
6318
6319AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6320AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6321])
6322AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6323logical_port="c2"], [0], [2
6324])
6325AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6326AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6327])
6328AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6329logical_port="c3"], [0], [4
6330])
6331
6332dnl A different parent.
6333AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6334AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6335])
6336AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6337logical_port="c4"], [0], [1
6338])
6339
6340AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6341AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6342])
6343AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6344logical_port="c5"], [0], [2
6345])
6346
6347dnl Delete a logical port and create a new one.
6348AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6349AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6350AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6351])
6352AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6353logical_port="c6"], [0], [1
6354])
6355
6356dnl Restart northd to see that the same allocation remains.
6357as northd
6358OVS_APP_EXIT_AND_WAIT([ovn-northd])
6359start_daemon ovn-northd \
6360 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6361 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6362
6363dnl Create a switch to make sure that ovn-northd has run through the main loop.
6364AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6365AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6366])
6367AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6368])
6369AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6370])
6371AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6372])
6373AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6374])
6375AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6376])
6377
6378dnl Create a switch port with a tag that has already been allocated.
6379dnl It should go through fine with a duplicate tag.
6380AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6381AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6382])
6383AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6384logical_port="c7"], [0], [2
6385])
6386AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6387])
6388
6389AT_CHECK([ovn-nbctl ls-add ls2])
6390dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
6391dnl gets copied to 'tag'
6392AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
6393AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
6394])
6395dnl The same 'tag' gets created in southbound database.
6396AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6397logical_port="local0"], [0], [25
6398])
6399dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
6400AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
6401AT_CHECK([ovn-nbctl lsp-get-tag local1])
6402dnl change the tag_request.
6403AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
6404AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
6405])
6406
6407AT_CLEANUP
57afd0c0
RR
6408
6409AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
6410ovn_start
6411ovn-nbctl ls-add lsw0
6412net_add n1
6413for i in 1 2; do
6414 sim_add hv$i
6415 as hv$i
6416 ovs-vsctl add-br br-phys
6417 ovn_attach n1 br-phys 192.168.0.$i
6418 ovs-vsctl add-br br-eth0
6419 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6420done
6421
6422# Create a localnet port.
6423AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
6424AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6425AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6426AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6427
6428
6429# Create 3 vifs.
6430AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6431AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6432AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6433AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
863fb61f 6434AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
57afd0c0
RR
6435AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6436AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6437AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6438AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6439
6440# Bind the localvif1 to hv1.
6441as hv1
6442AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6443
6444# On hv1, check that there are no flows outputting bcast to tunnel
6445OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6446
1ea9b847 6447# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 6448as hv2
1ea9b847 6449OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
6450
6451# Now bind vif2 on hv2.
6452AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6453
6454# At this point, the broadcast flow on vif2 should be deleted.
6455# because, there is now a localnet vif bound (table=32 programming logic)
6456OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6457
6458# Verify that the local net patch port exists on hv2.
6459OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6460
6461# Now bind vif3 on hv2.
6462AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6463
6464# Verify that the local net patch port still exists on hv2
6465OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6466
6467# Delete localvif2
6468AT_CHECK([ovn-nbctl lsp-del localvif2])
6469
6470# Verify that the local net patch port still exists on hv2,
6471# because, localvif3 is still bound.
6472OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6473
57afd0c0 6474OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
6475
6476AT_CLEANUP
6477
d383eed5
JP
6478
6479AT_SETUP([ovn -- ACL logging])
6480AT_KEYWORDS([ovn])
6481ovn_start
6482
6483net_add n1
6484
6485sim_add hv
6486as hv
6487ovs-vsctl add-br br-phys
6488ovn_attach n1 br-phys 192.168.0.1
6489for i in lp1 lp2; do
6490 ovs-vsctl -- add-port br-int $i -- \
6491 set interface $i external-ids:iface-id=$i \
6492 options:tx_pcap=hv/$i-tx.pcap \
6493 options:rxq_pcap=hv/$i-rx.pcap
6494done
6495
6496lp1_mac="f0:00:00:00:00:01"
6497lp1_ip="192.168.1.2"
6498
6499lp2_mac="f0:00:00:00:00:02"
6500lp2_ip="192.168.1.3"
6501
6502ovn-nbctl ls-add lsw0
6503ovn-nbctl --wait=sb lsp-add lsw0 lp1
6504ovn-nbctl --wait=sb lsp-add lsw0 lp2
6505ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6506ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6507ovn-nbctl --wait=sb sync
6508
6509ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6510ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6511
6512ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6513ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6514
6515ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6516ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6517
6518ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6519ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6520
6521ovn-sbctl dump-flows
6522
6523
6524# Send packet that should be dropped without logging.
6525packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6526 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6527 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6528as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6529
6530# Send packet that should be dropped with logging.
6531packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6532 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6533 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6534as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6535
6536# Send packet that should be allowed without logging.
6537packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6538 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6539 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6540as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6541
6542# Send packet that should be allowed with logging.
6543packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6544 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6545 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6546as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6547
6548# Send packet that should allow related flows without logging.
6549packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6550 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6551 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6552as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6553
6554# Send packet that should allow related flows with logging.
6555packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6556 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6557 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6558as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6559
df48cfc7 6560# Send packet that should be rejected without logging.
d383eed5
JP
6561packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6562 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6563 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6564as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6565
df48cfc7 6566# Send packet that should be rejected with logging.
d383eed5
JP
6567packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6568 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6569 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6570as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6571
c1f272f9
NS
6572OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6573
d383eed5
JP
6574AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6575name="drop-flow", verdict=drop, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4361,tp_dst=81,tcp_flags=syn
6576name="allow-flow", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4363,tp_dst=83,tcp_flags=syn
6577name="<unnamed>", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4365,tp_dst=85,tcp_flags=syn
6578name="reject-flow", verdict=reject, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4367,tp_dst=87,tcp_flags=syn
6579])
6580
6581OVN_CLEANUP([hv])
6582AT_CLEANUP
6583
6584
23749245
JP
6585AT_SETUP([ovn -- ACL rate-limited logging])
6586AT_KEYWORDS([ovn])
6587ovn_start
6588
6589net_add n1
6590
6591sim_add hv
6592as hv
6593ovs-vsctl add-br br-phys
6594ovn_attach n1 br-phys 192.168.0.1
6595for i in lp1 lp2; do
6596 ovs-vsctl -- add-port br-int $i -- \
6597 set interface $i external-ids:iface-id=$i \
6598 options:tx_pcap=hv/$i-tx.pcap \
6599 options:rxq_pcap=hv/$i-rx.pcap
6600done
6601
6602lp1_mac="f0:00:00:00:00:01"
6603lp1_ip="192.168.1.2"
6604
6605lp2_mac="f0:00:00:00:00:02"
6606lp2_ip="192.168.1.3"
6607
6608ovn-nbctl ls-add lsw0
6609ovn-nbctl --wait=sb lsp-add lsw0 lp1
6610ovn-nbctl --wait=sb lsp-add lsw0 lp2
6611ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6612ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6613ovn-nbctl --wait=sb sync
6614
6615
6616# Add an ACL that rate-limits logs at 10 per second.
6617ovn-nbctl meter-add http-rl1 drop 10 pktps
6618ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6619
6620# Add an ACL that rate-limits logs at 5 per second.
6621ovn-nbctl meter-add http-rl2 drop 5 pktps
6622ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
6623
6624# Add an ACL that doesn't rate-limit logs.
6625ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
6626
6627
6628# For each ACL, send 100 packets.
6629for i in `seq 1 100`; do
6630 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=80)'
6631
6632 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=81)'
6633
6634 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=82)'
6635done
6636
2600ef02
JP
6637# The rate at which packets are sent is highly system-dependent, so we
6638# can't count on precise drop counts. To work around that, we just
6639# check that exactly 100 "http-acl3" actions were logged and that there
6640# were more "http-acl1" actions than "http-acl2" ones.
6641OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
6642
6643# On particularly slow or overloaded systems, the transmission rate may
6644# be lower than the configured meter rate. To prevent false test
6645# failures, we check the duration count of the meter, and if it's
6646# greater than nine seconds, just skip the test.
6647d_secs=$(as hv ovs-ofctl -O OpenFlow13 meter-stats br-int | grep "meter:1" | sed 's/.* duration:\([[0-9]]\{1,\}\)\.[[0-9]]\+s .*/\1/')
6648
6649echo "Meter duration: $d_secs"
6650AT_SKIP_IF([test $d_secs -gt 9])
6651
23749245
JP
6652# Print some information that may help debugging.
6653as hv ovs-appctl -t ovn-controller meter-table-list
6654as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
6655
23749245
JP
6656n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
6657n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
6658n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
6659
6660AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
6661AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
6662
23749245
JP
6663OVN_CLEANUP([hv])
6664AT_CLEANUP
6665
6666
66d89287 6667AT_SETUP([ovn -- DSCP marking and meter check])
1a03fc7d
BS
6668AT_KEYWORDS([ovn])
6669ovn_start
6670
6671ovn-nbctl ls-add lsw0
6672ovn-nbctl --wait=sb lsp-add lsw0 lp1
6673ovn-nbctl --wait=sb lsp-add lsw0 lp2
e50ed58a 6674ovn-nbctl --wait=sb lsp-add lsw0 lp3
1a03fc7d
BS
6675ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6676ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
e50ed58a 6677ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
1a03fc7d
BS
6678ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6679ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6680ovn-nbctl --wait=sb sync
6681net_add n1
6682sim_add hv
6683as hv
6684ovs-vsctl add-br br-phys
6685ovn_attach n1 br-phys 192.168.0.1
6686ovs-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
6687ovs-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
6688
6689AT_CAPTURE_FILE([trace])
6690ovn_trace () {
6691 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6692}
6693
6694# Extracts nw_tos from the final flow from ofproto/trace output and prints
6695# it on stdout. Prints "none" if no nw_tos was included.
6696get_final_nw_tos() {
6697 if flow=$(grep '^Final flow:' stdout); then :; else
6698 # The output didn't have a final flow.
6699 return 99
6700 fi
6701
6702 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6703 case $tos in
6704 '') echo none ;;
5a0e4aec 6705 *) echo $tos ;;
1a03fc7d
BS
6706 esac
6707}
6708
6709# check_tos TOS
6710#
6711# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6712check_tos() {
6713 # First check with ovn-trace for logical flows.
6714 echo "checking for tos $1"
6715 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6716 echo 'output("lp2");') > expout
6717 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])
6718
6719 # Then re-check with ofproto/trace for a physical packet.
6720 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])
6721 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6722])
6723}
6724
6725# check at L2
6726AT_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");
6727])
6728AT_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])
6729AT_CHECK([get_final_nw_tos], [0], [none
6730])
6731
6732# check at L3 without dscp marking
6733check_tos 0
6734
6735# Mark DSCP with a valid value
e50ed58a 6736qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"\ &&\ is_chassis_resident(\"lp1\")" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
5ee33cbd
GL
6737AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6738])
1a03fc7d
BS
6739check_tos 48
6740
66d89287
GL
6741# check at hv without qos meter
6742AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6743])
6744
6745# Update the meter rate
6746ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6747
6748# check at hv with a qos meter table
6749AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6750])
6751AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6752])
6753
1a03fc7d
BS
6754# Update the DSCP marking
6755ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6756check_tos 63
6757
66d89287
GL
6758# Update the meter rate
6759ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6760
6761# check at hv with a qos meter table
6762AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6763])
6764AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6765])
6766
1a03fc7d
BS
6767ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6768check_tos 63
6769
6770# Disable DSCP marking
5ee33cbd
GL
6771ovn-nbctl --wait=hv qos-del lsw0
6772AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6773])
1a03fc7d
BS
6774check_tos 0
6775
66d89287
GL
6776# check at hv without qos meter
6777AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6778])
6779
e50ed58a
GL
6780# check meter with chassis not resident
6781ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6782AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6783])
6784
6785# check no meter table
6786AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6787])
6788AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6789])
6790
1a03fc7d 6791OVN_CLEANUP([hv])
57afd0c0 6792AT_CLEANUP
7fff4eb7
LR
6793
6794AT_SETUP([ovn -- read-only sb db:ptcp access])
6795AT_SKIP_IF([test $HAVE_PYTHON = no])
6796
6797: > .$1.db.~lock~
6798ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6799
6800# Add read-only remote to sb ovsdb-server
6801AT_CHECK(
6802 [ovsdb-tool transact ovn-sb.db \
6803 ['["OVN_Southbound",
6804 {"op": "insert",
6805 "table": "SB_Global",
6806 "row": {
6807 "connections": ["set", [["named-uuid", "xyz"]]]}},
6808 {"op": "insert",
6809 "table": "Connection",
6810 "uuid-name": "xyz",
6811 "row": {"target": "ptcp:0:127.0.0.1",
6812 "read_only": true}}]']], [0], [ignore], [ignore])
6813
6814start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6815
6816PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6817
6818# read-only accesses should succeed
6819AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6820AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6821
6822# write access should fail
6823AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6824[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6825])
6826
6827OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6828AT_CLEANUP
6829
6830AT_SETUP([ovn -- read-only sb db:pssl access])
6831AT_SKIP_IF([test $HAVE_PYTHON = no])
6832AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6833PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6834AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6835\\]"])
6836
6837: > .$1.db.~lock~
6838ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6839
6840# Add read-only remote to sb ovsdb-server
6841AT_CHECK(
6842 [ovsdb-tool transact ovn-sb.db \
6843 ['["OVN_Southbound",
6844 {"op": "insert",
6845 "table": "SB_Global",
6846 "row": {
6847 "connections": ["set", [["named-uuid", "xyz"]]]}},
6848 {"op": "insert",
6849 "table": "Connection",
6850 "uuid-name": "xyz",
6851 "row": {"target": "pssl:0:127.0.0.1",
6852 "read_only": true}}]']], [0], [ignore], [ignore])
6853
6854start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6855 --remote=db:OVN_Southbound,SB_Global,connections \
6856 --private-key="$PKIDIR/testpki-privkey2.pem" \
6857 --certificate="$PKIDIR/testpki-cert2.pem" \
6858 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6859 ovn-sb.db
6860
6861PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6862
6863# read-only accesses should succeed
6864AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6865 --private-key=$PKIDIR/testpki-privkey.pem \
6866 --certificate=$PKIDIR/testpki-cert.pem \
6867 --ca-cert=$PKIDIR/testpki-cacert.pem \
6868 list SB_Global], [0], [stdout], [ignore])
6869AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6870 --private-key=$PKIDIR/testpki-privkey.pem \
6871 --certificate=$PKIDIR/testpki-cert.pem \
6872 --ca-cert=$PKIDIR/testpki-cacert.pem \
6873 list Connection], [0], [stdout], [ignore])
6874
6875# write access should fail
6876AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6877 --private-key=$PKIDIR/testpki-privkey.pem \
6878 --certificate=$PKIDIR/testpki-cert.pem \
6879 --ca-cert=$PKIDIR/testpki-cacert.pem \
6880 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6881[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6882])
6883
6884OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6885AT_CLEANUP
6886
821302cf
LR
6887AT_SETUP([ovn -- nb connection/ssl commands])
6888AT_SKIP_IF([test $HAVE_PYTHON = no])
6889AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6890PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6891AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6892\\]"])
6893
6894: > .$1.db.~lock~
6895ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6896
6897# Start nb db server using db connection/ssl entries (unpopulated initially)
6898start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6899 --remote=db:OVN_Northbound,NB_Global,connections \
6900 --private-key=db:OVN_Northbound,SSL,private_key \
6901 --certificate=db:OVN_Northbound,SSL,certificate \
6902 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6903 ovn-nb.db
6904
6905# Populate SSL configuration entries in nb db
6906AT_CHECK(
6907 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6908 $PKIDIR/testpki-cert.pem \
6909 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6910
6911# Populate a passive SSL connection in nb db
6912AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6913
6914PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6915
6916# Verify SSL connetivity to nb db server
6917AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6918 --private-key=$PKIDIR/testpki-privkey.pem \
6919 --certificate=$PKIDIR/testpki-cert.pem \
6920 --ca-cert=$PKIDIR/testpki-cacert.pem \
6921 list NB_Global],
6922 [0], [stdout], [ignore])
6923AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6924 --private-key=$PKIDIR/testpki-privkey.pem \
6925 --certificate=$PKIDIR/testpki-cert.pem \
6926 --ca-cert=$PKIDIR/testpki-cacert.pem \
6927 list Connection],
6928 [0], [stdout], [ignore])
6929AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6930 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6931 --certificate=$PKIDIR/testpki-cert.pem \
6932 --ca-cert=$PKIDIR/testpki-cacert.pem \
6933 get-connection],
6934 [0], [stdout], [ignore])
6935
6936OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6937AT_CLEANUP
6938
6939AT_SETUP([ovn -- sb connection/ssl commands])
6940AT_SKIP_IF([test $HAVE_PYTHON = no])
6941AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6942PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6943AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6944\\]"])
6945
6946: > .$1.db.~lock~
6947ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6948
6949# Start sb db server using db connection/ssl entries (unpopulated initially)
6950start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6951 --remote=db:OVN_Southbound,SB_Global,connections \
6952 --private-key=db:OVN_Southbound,SSL,private_key \
6953 --certificate=db:OVN_Southbound,SSL,certificate \
6954 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6955 ovn-sb.db
6956
6957# Populate SSL configuration entries in sb db
6958AT_CHECK(
6959 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6960 $PKIDIR/testpki-cert.pem \
6961 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6962
6963# Populate a passive SSL connection in sb db
6964AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6965
6966PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6967
6968# Verify SSL connetivity to sb db server
6969AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6970 --private-key=$PKIDIR/testpki-privkey.pem \
6971 --certificate=$PKIDIR/testpki-cert.pem \
6972 --ca-cert=$PKIDIR/testpki-cacert.pem \
6973 list SB_Global],
6974 [0], [stdout], [ignore])
6975AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6976 --private-key=$PKIDIR/testpki-privkey.pem \
6977 --certificate=$PKIDIR/testpki-cert.pem \
6978 --ca-cert=$PKIDIR/testpki-cacert.pem \
6979 list Connection],
6980 [0], [stdout], [ignore])
6981AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6982 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
6983 --certificate=$PKIDIR/testpki-cert.pem \
6984 --ca-cert=$PKIDIR/testpki-cacert.pem \
6985 get-connection],
6986 [0], [stdout], [ignore])
6987
6988OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6989AT_CLEANUP
6990
75fd74f8
GS
6991AT_SETUP([ovn -- nested containers])
6992ovn_start
6993
6994# Physical network:
6995# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6996
6997# Logical network:
6998# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6999# and "bar" (192.168.2.0/24). They are all connected to router R1.
7000
7001ovn-nbctl lr-add R1
7002ovn-nbctl ls-add mgmt
7003ovn-nbctl ls-add foo
7004ovn-nbctl ls-add bar
7005
7006# Connect mgmt to R1
7007ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
7008ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
7009 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
7010
7011# Connect foo to R1
7012ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
7013ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7014 options:router-port=foo addresses=\"00:00:00:01:02:03\"
7015
7016# Connect bar to R1
7017ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
7018ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7019 options:router-port=bar addresses=\"00:00:00:01:02:04\"
7020
7021# "mgmt" has VM1 and VM2 connected
7022ovn-nbctl lsp-add mgmt vm1 \
7023-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
7024
7025ovn-nbctl lsp-add mgmt vm2 \
7026-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
7027
7028# "foo1" and "foo2" are containers belonging to switch "foo"
7029# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
7030ovn-nbctl lsp-add foo foo1 vm1 1 \
7031-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
7032
7033ovn-nbctl lsp-add foo foo2 vm2 2 \
7034-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7035
7036# "bar1" and "bar2" are containers belonging to switch "bar"
7037# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
7038ovn-nbctl lsp-add bar bar1 vm1 2 \
7039-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
7040
7041ovn-nbctl lsp-add bar bar2 vm2 1 \
7042-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
7043
7044# bar3 is a standalone VM belonging to switch "bar"
7045ovn-nbctl lsp-add bar bar3 \
7046-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
7047
7048# Create two hypervisor and create OVS ports corresponding to logical ports.
7049net_add n1
7050
7051sim_add hv1
7052as hv1
7053ovs-vsctl add-br br-phys
7054ovn_attach n1 br-phys 192.168.0.1
7055ovs-vsctl -- add-port br-int vm1 -- \
7056 set interface vm1 external-ids:iface-id=vm1 \
7057 options:tx_pcap=hv1/vm1-tx.pcap \
7058 options:rxq_pcap=hv1/vm1-rx.pcap \
7059 ofport-request=1
7060
7061ovs-vsctl -- add-port br-int bar3 -- \
7062 set interface bar3 external-ids:iface-id=bar3 \
7063 options:tx_pcap=hv1/bar3-tx.pcap \
7064 options:rxq_pcap=hv1/bar3-rx.pcap \
7065 ofport-request=2
7066
7067sim_add hv2
7068as hv2
7069ovs-vsctl add-br br-phys
7070ovn_attach n1 br-phys 192.168.0.2
7071ovs-vsctl -- add-port br-int vm2 -- \
7072 set interface vm2 external-ids:iface-id=vm2 \
7073 options:tx_pcap=hv2/vm2-tx.pcap \
7074 options:rxq_pcap=hv2/vm2-rx.pcap \
7075 ofport-request=1
7076
7077# Pre-populate the hypervisors' ARP tables so that we don't lose any
7078# packets for ARP resolution (native tunneling doesn't queue packets
7079# for ARP resolution).
74868f2c 7080OVN_POPULATE_ARP
75fd74f8
GS
7081
7082# Allow some time for ovn-northd and ovn-controller to catch up.
7083# XXX This should be more systematic.
7084sleep 1
7085
7086ip_to_hex() {
7087 printf "%02x%02x%02x%02x" "$@"
7088}
7089
7090# Send ip packets between foo1 and foo2 (same switch, different HVs and
7091# different VLAN tags).
7092src_mac="f00000010205"
7093dst_mac="f00000010206"
7094src_ip=`ip_to_hex 192 168 1 2`
7095dst_ip=`ip_to_hex 192 168 1 3`
7096packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7097as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7098
7099# expected packet at foo2
7100packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7101echo $packet > expected
7102OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7103
7104# Send ip packets between foo1 and bar2 (different switch, different HV)
7105src_mac="f00000010205"
7106dst_mac="000000010203"
7107src_ip=`ip_to_hex 192 168 1 2`
7108dst_ip=`ip_to_hex 192 168 2 3`
7109packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7110as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7111
7112# expected packet at bar2
7113src_mac="000000010204"
7114dst_mac="f00000010208"
7115packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7116echo $packet >> expected
7117OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7118
7119# Send ip packets between foo1 and bar1
7120# (different switch, loopback to same vm but different tag)
7121src_mac="f00000010205"
7122dst_mac="000000010203"
7123src_ip=`ip_to_hex 192 168 1 2`
7124dst_ip=`ip_to_hex 192 168 2 2`
7125packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7126as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7127
7128# expected packet at bar1
7129src_mac="000000010204"
7130dst_mac="f00000010207"
7131packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7132echo $packet > expected1
7133OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7134
7135# Send ip packets between bar1 and bar3
7136# (same switch. But one is container and another is a standalone VM)
7137src_mac="f00000010207"
7138dst_mac="f00000010209"
7139src_ip=`ip_to_hex 192 168 2 2`
7140dst_ip=`ip_to_hex 192 168 2 3`
7141packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7142as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7143
7144# expected packet at bar3
7145packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7146echo $packet > expected
7147OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7148
7149# Send ip packets between foo1 and vm1.
7150(different switch, container to the VM hosting it.)
7151src_mac="f00000010205"
7152dst_mac="000000010203"
7153src_ip=`ip_to_hex 192 168 1 2`
7154dst_ip=`ip_to_hex 172 16 1 2`
7155packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7156as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7157
7158# expected packet at vm1
7159src_mac="000000010202"
7160dst_mac="f00000010203"
7161packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7162echo $packet >> expected1
7163OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7164
7165# Send packets from vm1 to bar1.
7166(different switch, A hosting VM to a container inside it)
7167src_mac="f00000010203"
7168dst_mac="000000010202"
7169src_ip=`ip_to_hex 172 16 1 2`
7170dst_ip=`ip_to_hex 192 168 2 2`
7171packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7172as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7173
7174# expected packet at vm1
7175src_mac="000000010204"
7176dst_mac="f00000010207"
7177packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7178echo $packet >> expected1
7179OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7180
22e506d3
NS
7181# Send broadcast packet from foo1. foo1 should not receive the same packet.
7182src_mac="f00000010205"
7183dst_mac="ffffffffffff"
7184src_ip=`ip_to_hex 192 168 1 2`
7185dst_ip=`ip_to_hex 255 255 255 255`
7186packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7187as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7188
7189# expected packet at VM1
7190OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7191
75fd74f8
GS
7192OVN_CLEANUP([hv1],[hv2])
7193
7194AT_CLEANUP
440a9f4b
GS
7195
7196AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7197AT_SKIP_IF([test $HAVE_PYTHON = no])
7198ovn_start
7199
7200# Logical network:
7201# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7202# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7203# (192.168.2.0/24) connected to it.
7204#
7205# R2 and R3 are gateway routers.
7206# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7207# connected to it. Note how both alice and bob have the same subnet behind it.
7208# We are trying to simulate external network via those 2 switches. In real
7209# world the switch ports of these switches will have addresses set as "unknown"
7210# to make them learning switches. Or those switches will be "localnet" ones.
7211
7212# Create three hypervisors and create OVS ports corresponding to logical ports.
7213net_add n1
7214
7215sim_add hv1
7216as hv1
7217ovs-vsctl add-br br-phys
7218ovn_attach n1 br-phys 192.168.0.1
7219ovs-vsctl -- add-port br-int hv1-vif1 -- \
7220 set interface hv1-vif1 external-ids:iface-id=foo1 \
7221 options:tx_pcap=hv1/vif1-tx.pcap \
7222 options:rxq_pcap=hv1/vif1-rx.pcap \
7223 ofport-request=1
7224
7225ovs-vsctl -- add-port br-int hv1-vif2 -- \
7226 set interface hv1-vif2 external-ids:iface-id=bar1 \
7227 options:tx_pcap=hv1/vif2-tx.pcap \
7228 options:rxq_pcap=hv1/vif2-rx.pcap \
7229 ofport-request=2
7230
7231sim_add hv2
7232as hv2
7233ovs-vsctl add-br br-phys
7234ovn_attach n1 br-phys 192.168.0.2
7235ovs-vsctl -- add-port br-int hv2-vif1 -- \
7236 set interface hv2-vif1 external-ids:iface-id=alice1 \
7237 options:tx_pcap=hv2/vif1-tx.pcap \
7238 options:rxq_pcap=hv2/vif1-rx.pcap \
7239 ofport-request=1
7240
7241sim_add hv3
7242as hv3
7243ovs-vsctl add-br br-phys
7244ovn_attach n1 br-phys 192.168.0.3
7245ovs-vsctl -- add-port br-int hv3-vif1 -- \
7246 set interface hv3-vif1 external-ids:iface-id=bob1 \
7247 options:tx_pcap=hv3/vif1-tx.pcap \
7248 options:rxq_pcap=hv3/vif1-rx.pcap \
7249 ofport-request=1
7250
7251
7252ovn-nbctl create Logical_Router name=R1
7253ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7254ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7255
7256ovn-nbctl ls-add foo
7257ovn-nbctl ls-add bar
7258ovn-nbctl ls-add alice
7259ovn-nbctl ls-add bob
7260ovn-nbctl ls-add join
7261
7262# Connect foo to R1
7263ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7264ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7265 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7266
7267# Connect bar to R1
7268ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7269ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7270 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7271
7272# Connect alice to R2
7273ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7274ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7275 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7276
7277# Connect bob to R3
7278ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7279ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7280 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7281
7282# Connect R1 to join
7283ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7284ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7285 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7286
7287# Connect R2 to join
7288ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7289ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7290 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7291
7292# Connect R3 to join
7293ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7294ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7295 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7296
7297# Install static routes with source ip address as the policy for routing.
7298# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7299ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7300ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7301
7302# Install static routes with destination ip address as the policy for routing.
7303ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7304
7305ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7306
7307# Create logical port foo1 in foo
7308ovn-nbctl lsp-add foo foo1 \
7309-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7310
7311# Create logical port bar1 in bar
7312ovn-nbctl lsp-add bar bar1 \
7313-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7314
7315# Create logical port alice1 in alice
7316ovn-nbctl lsp-add alice alice1 \
7317-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7318
7319# Create logical port bob1 in bob
7320ovn-nbctl lsp-add bob bob1 \
7321-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7322
7323# Pre-populate the hypervisors' ARP tables so that we don't lose any
7324# packets for ARP resolution (native tunneling doesn't queue packets
7325# for ARP resolution).
74868f2c 7326OVN_POPULATE_ARP
440a9f4b
GS
7327
7328# Allow some time for ovn-northd and ovn-controller to catch up.
7329# XXX This should be more systematic.
7330sleep 1
7331
7332ip_to_hex() {
7333 printf "%02x%02x%02x%02x" "$@"
7334}
7335trim_zeros() {
7336 sed 's/\(00\)\{1,\}$//'
7337}
7338
7339# Send ip packets between foo1 and bar1
7340# (East-west traffic should flow normally)
7341src_mac="f00000010203"
7342dst_mac="000001010203"
7343src_ip=`ip_to_hex 192 168 1 2`
7344dst_ip=`ip_to_hex 192 168 2 2`
7345packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7346as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7347
7348# Send ip packets between foo1 and alice1
7349src_mac="f00000010203"
7350dst_mac="000001010203"
7351src_ip=`ip_to_hex 192 168 1 2`
7352dst_ip=`ip_to_hex 172 16 1 3`
7353packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7354as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 7355as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
7356
7357# Send ip packets between bar1 and bob1
7358src_mac="f00000010204"
7359dst_mac="000001010204"
7360src_ip=`ip_to_hex 192 168 2 2`
7361dst_ip=`ip_to_hex 172 16 1 4`
7362packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7363as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7364#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7365
7366# Packet to expect at bar1
7367src_mac="000001010204"
7368dst_mac="f00000010204"
7369src_ip=`ip_to_hex 192 168 1 2`
7370dst_ip=`ip_to_hex 192 168 2 2`
7371expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7372echo $expected > expected
7373OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7374
7375# Packet to Expect at alice1
7376src_mac="000002010203"
7377dst_mac="f00000010205"
7378src_ip=`ip_to_hex 192 168 1 2`
7379dst_ip=`ip_to_hex 172 16 1 3`
7380expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7381echo $expected > expected
7382OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7383
7384# Packet to Expect at bob1
7385src_mac="000003010203"
7386dst_mac="f00000010206"
7387src_ip=`ip_to_hex 192 168 2 2`
7388dst_ip=`ip_to_hex 172 16 1 4`
7389expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7390echo $expected > expected
7391OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
7392
7393for sim in hv1 hv2 hv3; do
7394 as $sim
7395 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7396 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7397 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7398done
7399
7400as ovn-sb
7401OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7402
7403as ovn-nb
7404OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7405
7406as northd
7407OVS_APP_EXIT_AND_WAIT([ovn-northd])
7408
7409as main
7410OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7411OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7412
7413AT_CLEANUP
41a15b71 7414
302eda27
NS
7415AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
7416AT_SKIP_IF([test $HAVE_PYTHON = no])
7417ovn_start
7418
7419ovn-nbctl ls-add ls1
7420
7421ovn-nbctl lsp-add ls1 ls1-lp1 \
7422-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7423
7424ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7425
7426ovn-nbctl lsp-add ls1 ls1-lp2 \
7427-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7428
7429ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7430
7431DNS1=`ovn-nbctl create DNS records={}`
7432DNS2=`ovn-nbctl create DNS records={}`
7433
7434ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7435ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
7436ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
7437
7438ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
7439
7440net_add n1
7441sim_add hv1
7442
7443as hv1
7444ovs-vsctl add-br br-phys
7445ovn_attach n1 br-phys 192.168.0.1
7446ovs-vsctl -- add-port br-int hv1-vif1 -- \
7447 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
7448 options:tx_pcap=hv1/vif1-tx.pcap \
7449 options:rxq_pcap=hv1/vif1-rx.pcap \
7450 ofport-request=1
7451
7452ovs-vsctl -- add-port br-int hv1-vif2 -- \
7453 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
7454 options:tx_pcap=hv1/vif2-tx.pcap \
7455 options:rxq_pcap=hv1/vif2-rx.pcap \
7456 ofport-request=2
7457
74868f2c 7458OVN_POPULATE_ARP
302eda27
NS
7459sleep 2
7460as hv1 ovs-vsctl show
7461
7462echo "*************************"
7463ovn-sbctl list DNS
7464echo "*************************"
7465
7466ip_to_hex() {
7467 printf "%02x%02x%02x%02x" "$@"
7468}
7469
7470reset_pcap_file() {
7471 local iface=$1
7472 local pcap_file=$2
7473 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7474options:rxq_pcap=dummy-rx.pcap
7475 rm -f ${pcap_file}*.pcap
7476 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7477options:rxq_pcap=${pcap_file}-rx.pcap
7478}
7479
7480# set_dns_params host_name
7481# Sets the dns_req_data and dns_resp_data
7482set_dns_params() {
7483 local hname=$1
7484 local ttl=00000e10
7485 an_count=0001
7486 type=0001
7487 case $hname in
7488 vm1)
7489 # vm1.ovn.org
7490 query_name=03766d31036f766e036f726700
7491 # IPv4 address - 10.0.0.4
7492 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7493 ;;
7494 vm2)
7495 # vm2.ovn.org
7496 query_name=03766d32036f766e036f726700
7497 # IPv4 address - 10.0.0.6
7498 expected_dns_answer=${query_name}00010001${ttl}00040a000006
7499 # IPv4 address - 20.0.0.4
7500 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
7501 an_count=0002
7502 ;;
7503 vm3)
7504 # vm3.ovn.org
7505 query_name=03766d33036f766e036f726700
7506 # IPv4 address - 40.0.0.4
7507 expected_dns_answer=${query_name}00010001${ttl}000428000004
7508 ;;
7509 vm1_ipv6_only)
7510 # vm1.ovn.org
7511 query_name=03766d31036f766e036f726700
7512 # IPv6 address - aef0::4
7513 type=001c
7514 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
7515 ;;
7516 vm1_ipv4_v6)
7517 # vm1.ovn.org
7518 query_name=03766d31036f766e036f726700
7519 type=00ff
7520 an_count=0002
7521 # IPv4 address - 10.0.0.4
7522 # IPv6 address - aef0::4
7523 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7524 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7525 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7526 ;;
7527 vm1_invalid_type)
7528 # vm1.ovn.org
7529 query_name=03766d31036f766e036f726700
7530 # IPv6 address - aef0::4
7531 type=0002
7532 ;;
7533 vm1_incomplete)
7534 # set type to none
7535 type=''
7536 esac
7537 # TTL - 3600
7538 local dns_req_header=010201200001000000000000
7539 local dns_resp_header=010281200001${an_count}00000000
7540 dns_req_data=${dns_req_header}${query_name}${type}0001
7541 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7542}
7543
7544# This shell function sends a DNS request packet
7545# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7546test_dns() {
7547 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7548 local dns_query_data=$7
7549 shift; shift; shift; shift; shift; shift; shift;
7550 # Packet size => IPv4 header (20) + UDP header (8) +
7551 # DNS data (header + query)
7552 ip_len=`expr 28 + ${#dns_query_data} / 2`
7553 udp_len=`expr $ip_len - 20`
7554 ip_len=$(printf "%x" $ip_len)
7555 udp_len=$(printf "%x" $udp_len)
7556 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7557 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7558 # dns data
7559 request=${request}${dns_query_data}
7560
7561 if test $dns_reply != 0; then
7562 local dns_reply=$1
7563 ip_len=`expr 28 + ${#dns_reply} / 2`
7564 udp_len=`expr $ip_len - 20`
7565 ip_len=$(printf "%x" $ip_len)
7566 udp_len=$(printf "%x" $udp_len)
7567 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7568 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7569 echo $reply >> $inport.expected
7570 else
7571 for outport; do
7572 echo $request >> $outport.expected
7573 done
7574 fi
7575 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7576}
7577
f8e79d82
MM
7578test_dns6() {
7579 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7580 local dns_query_data=$7
7581 shift; shift; shift; shift; shift; shift; shift;
7582 # Packet size => UDP header (8) +
7583 # DNS data (header + query)
7584 ip_len=`expr 8 + ${#dns_query_data} / 2`
7585 udp_len=$ip_len
7586 ip_len=$(printf "%x" $ip_len)
7587 udp_len=$(printf "%x" $udp_len)
7588 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7589 request=${request}9234003500${udp_len}0000
7590 #dns data
7591 request=${request}${dns_query_data}
7592
7593 if test $dns_reply != 0; then
7594 local dns_reply=$1
7595 ip_len=`expr 8 + ${#dns_reply} / 2`
7596 udp_len=$ip_len
7597 ip_len=$(printf "%x" $ip_len)
7598 udp_len=$(printf "%x" $udp_len)
7599 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7600 reply=${reply}0035923400${udp_len}0000${dns_reply}
7601 echo $reply >> $inport.expected
7602 else
7603 for outport; do
7604 echo $request >> $outport.expected
7605 done
7606 fi
7607 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7608}
7609
302eda27
NS
7610AT_CAPTURE_FILE([ofctl_monitor0.log])
7611as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7612--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7613
7614set_dns_params vm2
7615src_ip=`ip_to_hex 10 0 0 4`
7616dst_ip=`ip_to_hex 10 0 0 1`
7617dns_reply=1
7618test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7619
7620# NXT_RESUMEs should be 1.
7621OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7622
7623$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7624cat 1.expected | cut -c -48 > expout
7625AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7626# Skipping the IPv4 checksum.
7627cat 1.expected | cut -c 53- > expout
7628AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7629
7630reset_pcap_file hv1-vif1 hv1/vif1
7631reset_pcap_file hv1-vif2 hv1/vif2
7632rm -f 1.expected
7633rm -f 2.expected
7634
7635set_dns_params vm1
7636src_ip=`ip_to_hex 10 0 0 6`
7637dst_ip=`ip_to_hex 10 0 0 1`
7638dns_reply=1
7639test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7640
7641# NXT_RESUMEs should be 2.
7642OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7643
7644$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7645cat 2.expected | cut -c -48 > expout
7646AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7647# Skipping the IPv4 checksum.
7648cat 2.expected | cut -c 53- > expout
7649AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7650
7651reset_pcap_file hv1-vif1 hv1/vif1
7652reset_pcap_file hv1-vif2 hv1/vif2
7653rm -f 1.expected
7654rm -f 2.expected
7655
7656# Clear the query name options for ls1-lp2
7657ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7658
7659set_dns_params vm2
7660src_ip=`ip_to_hex 10 0 0 4`
7661dst_ip=`ip_to_hex 10 0 0 1`
7662dns_reply=0
7663test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7664
7665# NXT_RESUMEs should be 3.
7666OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7667
7668$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7669AT_CHECK([cat 1.packets], [0], [])
7670
7671reset_pcap_file hv1-vif1 hv1/vif1
7672reset_pcap_file hv1-vif2 hv1/vif2
7673rm -f 1.expected
7674rm -f 2.expected
7675
7676# Clear the query name for ls1-lp1
7677# Since ls1 has no query names configued,
7678# ovn-northd should not add the DNS flows.
7679ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7680
7681set_dns_params vm1
7682src_ip=`ip_to_hex 10 0 0 6`
7683dst_ip=`ip_to_hex 10 0 0 1`
7684dns_reply=0
7685test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7686
7687# NXT_RESUMEs should be 3 only.
7688OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7689
7690$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7691AT_CHECK([cat 2.packets], [0], [])
7692
7693reset_pcap_file hv1-vif1 hv1/vif1
7694reset_pcap_file hv1-vif2 hv1/vif2
7695rm -f 1.expected
7696rm -f 2.expected
7697
7698# Test IPv6 (AAAA records) using IPv4 packet.
7699# Add back the DNS options for ls1-lp1.
4f4ac4bb 7700ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
302eda27
NS
7701
7702set_dns_params vm1_ipv6_only
7703src_ip=`ip_to_hex 10 0 0 6`
7704dst_ip=`ip_to_hex 10 0 0 1`
7705dns_reply=1
7706test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7707
7708# NXT_RESUMEs should be 4.
7709OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7710
7711$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7712cat 2.expected | cut -c -48 > expout
7713AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7714# Skipping the IPv4 checksum.
7715cat 2.expected | cut -c 53- > expout
7716AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7717
7718reset_pcap_file hv1-vif1 hv1/vif1
7719reset_pcap_file hv1-vif2 hv1/vif2
7720rm -f 1.expected
7721rm -f 2.expected
7722
7723# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7724set_dns_params vm1_ipv4_v6
7725src_ip=`ip_to_hex 10 0 0 6`
7726dst_ip=`ip_to_hex 10 0 0 1`
7727dns_reply=1
7728test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7729
7730# NXT_RESUMEs should be 5.
7731OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7732
7733$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7734cat 2.expected | cut -c -48 > expout
7735AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7736# Skipping the IPv4 checksum.
7737cat 2.expected | cut -c 53- > expout
7738AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7739
7740reset_pcap_file hv1-vif1 hv1/vif1
7741reset_pcap_file hv1-vif2 hv1/vif2
7742rm -f 1.expected
7743rm -f 2.expected
7744
7745# Invalid type.
7746set_dns_params vm1_invalid_type
7747src_ip=`ip_to_hex 10 0 0 6`
7748dst_ip=`ip_to_hex 10 0 0 1`
7749dns_reply=0
7750test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7751
7752# NXT_RESUMEs should be 6.
7753OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7754
7755$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7756AT_CHECK([cat 2.packets], [0], [])
7757
7758reset_pcap_file hv1-vif1 hv1/vif1
7759reset_pcap_file hv1-vif2 hv1/vif2
7760rm -f 1.expected
7761rm -f 2.expected
7762
7763# Incomplete DNS packet.
7764set_dns_params vm1_incomplete
7765src_ip=`ip_to_hex 10 0 0 6`
7766dst_ip=`ip_to_hex 10 0 0 1`
7767dns_reply=0
7768test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7769
7770# NXT_RESUMEs should be 7.
7771OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7772
7773$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7774AT_CHECK([cat 2.packets], [0], [])
7775
7776reset_pcap_file hv1-vif1 hv1/vif1
7777reset_pcap_file hv1-vif2 hv1/vif2
7778rm -f 1.expected
7779rm -f 2.expected
7780
7781# Add one more DNS record to the ls1.
7782ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7783
7784set_dns_params vm3
7785src_ip=`ip_to_hex 10 0 0 4`
7786dst_ip=`ip_to_hex 10 0 0 1`
7787dns_reply=1
7788test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7789
7790# NXT_RESUMEs should be 8.
7791OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7792
7793$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7794cat 1.expected | cut -c -48 > expout
7795AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7796# Skipping the IPv4 checksum.
7797cat 1.expected | cut -c 53- > expout
7798AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7799
7800reset_pcap_file hv1-vif1 hv1/vif1
7801reset_pcap_file hv1-vif2 hv1/vif2
7802rm -f 1.expected
7803rm -f 2.expected
7804
f8e79d82
MM
7805# Try DNS query over IPv6
7806set_dns_params vm1
7807src_ip=aef00000000000000000000000000004
7808dst_ip=aef00000000000000000000000000001
7809dns_reply=1
7810test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7811
7812# NXT_RESUMEs should be 9.
7813OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7814
7815$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
b75f2651
MM
7816# Skipping the UDP checksum.
7817cat 1.expected | cut -c 1-120,125- > expout
7818AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
f8e79d82
MM
7819
7820reset_pcap_file hv1-vif1 hv1/vif1
7821reset_pcap_file hv1-vif2 hv1/vif2
7822rm -f 1.expected
7823rm -f 2.expected
7824
302eda27
NS
7825as hv1
7826 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7827OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7828OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7829
7830as ovn-sb
7831OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7832
7833as ovn-nb
7834OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7835
7836as northd
7837OVS_APP_EXIT_AND_WAIT([ovn-northd])
7838
7839as main
7840OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7841OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7842AT_CLEANUP
7843
75f9e007 7844AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 7845AT_SKIP_IF([test $HAVE_PYTHON = no])
7846ovn_start
7847
7848net_add n1
7849
7850sim_add hv1
7851as hv1
7852ovs-vsctl add-br br-phys
7853ovn_attach n1 br-phys 192.168.0.1
7854ovs-vsctl -- add-port br-int hv1-vif1 -- \
7855 set interface hv1-vif1 external-ids:iface-id=foo1 \
7856 options:tx_pcap=hv1/vif1-tx.pcap \
7857 options:rxq_pcap=hv1/vif1-rx.pcap \
7858 ofport-request=1
7859
7860sim_add gw1
7861as gw1
7862ovs-vsctl add-br br-phys
7863ovn_attach n1 br-phys 192.168.0.2
7864
7865sim_add gw2
7866as gw2
7867ovs-vsctl add-br br-phys
7868ovn_attach n1 br-phys 192.168.0.4
7869
7870sim_add ext1
7871as ext1
7872ovs-vsctl add-br br-phys
7873ovn_attach n1 br-phys 192.168.0.3
7874ovs-vsctl -- add-port br-int ext1-vif1 -- \
7875 set interface ext1-vif1 external-ids:iface-id=outside1 \
7876 options:tx_pcap=ext1/vif1-tx.pcap \
7877 options:rxq_pcap=ext1/vif1-rx.pcap \
7878 ofport-request=1
7879
7880# Pre-populate the hypervisors' ARP tables so that we don't lose any
7881# packets for ARP resolution (native tunneling doesn't queue packets
7882# for ARP resolution).
74868f2c 7883OVN_POPULATE_ARP
1da17a0b 7884
7885ovn-nbctl create Logical_Router name=R1
7886
7887ovn-nbctl ls-add foo
7888ovn-nbctl ls-add alice
7889ovn-nbctl ls-add outside
7890
7891# Connect foo to R1
7892ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7893ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7894 type=router options:router-port=foo \
7895 -- lsp-set-addresses rp-foo router
7896
7897# Connect alice to R1 as distributed router gateway port on gw1
7898ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7899
7900ovn-nbctl \
7901 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7902 chassis_name=gw1 \
7903 priority=20 -- \
7904 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7905 chassis_name=gw2 \
7906 priority=10 -- \
7907 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7908
7909ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7910 type=router options:router-port=alice \
7911 -- lsp-set-addresses rp-alice router
7912
7913# Create logical port foo1 in foo
7914ovn-nbctl lsp-add foo foo1 \
7915-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7916
7917# Create logical port outside1 in outside
7918ovn-nbctl lsp-add outside outside1 \
7919-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7920
7921# Create localnet port in alice
7922ovn-nbctl lsp-add alice ln-alice
7923ovn-nbctl lsp-set-addresses ln-alice unknown
7924ovn-nbctl lsp-set-type ln-alice localnet
7925ovn-nbctl lsp-set-options ln-alice network_name=phys
7926
7927# Create localnet port in outside
7928ovn-nbctl lsp-add outside ln-outside
7929ovn-nbctl lsp-set-addresses ln-outside unknown
7930ovn-nbctl lsp-set-type ln-outside localnet
7931ovn-nbctl lsp-set-options ln-outside network_name=phys
7932
7933# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7934# mapping to the external network, is the one generating packets
7935as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7936as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7937as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7938
7939AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7940
7941# Allow some time for ovn-northd and ovn-controller to catch up.
7942# XXX This should be more systematic.
7943sleep 2
7944
7945ip_to_hex() {
7946 printf "%02x%02x%02x%02x" "$@"
7947}
7948
7949reset_pcap_file() {
7950 local iface=$1
7951 local pcap_file=$2
7952 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7953options:rxq_pcap=dummy-rx.pcap
7954 rm -f ${pcap_file}*.pcap
7955 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7956options:rxq_pcap=${pcap_file}-rx.pcap
7957}
7958
7959test_ip_packet()
7960{
7961 local active_gw=$1
7962 local backup_gw=$2
7963
7964 # Send ip packet between foo1 and outside1
7965 src_mac="f00000010203" # foo1 mac
7966 dst_mac="000001010203" # rp-foo mac (internal router leg)
7967 src_ip=`ip_to_hex 192 168 1 2`
7968 dst_ip=`ip_to_hex 172 16 1 3`
7969 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7970
7971 # ARP request packet to expect at outside1
7972 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7973
7974 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7975
7976 # Send ARP reply from outside1 back to the router
7977 # XXX: note, we could avoid this if we plug this port into a netns
7978 # and setup the IP address into the port, so the kernel would simply reply
7979 src_mac="000002010203"
7980 reply_mac="f00000010204"
7981 dst_ip=`ip_to_hex 172 16 1 3`
7982 src_ip=`ip_to_hex 172 16 1 1`
7983 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7984
7985 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7986
86c9d79a
NS
7987 OVS_WAIT_UNTIL([
7988 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7989grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7990 ])
7991
1da17a0b 7992 # Packet to Expect at ext1 chassis, outside1 port
7993 src_mac="000002010203"
7994 dst_mac="f00000010204"
7995 src_ip=`ip_to_hex 192 168 1 2`
7996 dst_ip=`ip_to_hex 172 16 1 3`
7997 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7998 echo $expected > ext1-vif1.expected
7999
8000 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8001 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8002 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8003
8004 # Resend packet from foo1 to outside1
8005 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8006
8007 sleep 1
8008
8009 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8010 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8011 AT_CHECK([grep $expected packets | sort], [0], [expout])
8012 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8013 AT_CHECK([grep $expected packets | sort], [0], [])
8014}
8015
8016test_ip_packet gw1 gw2
8017
75f9e007
GZ
8018ovn-nbctl --timeout=3 --wait=hv \
8019 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8020 chassis_name=gw1 \
8021 priority=10 -- \
8022 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8023 chassis_name=gw2 \
8024 priority=20 -- \
8025 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8026
8027test_ip_packet gw2 gw1
8028
8029OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8030AT_CLEANUP
8031
8032AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
8033AT_SKIP_IF([test $HAVE_PYTHON = no])
8034ovn_start
8035
8036net_add n1
8037
8038sim_add hv1
8039as hv1
8040ovs-vsctl add-br br-phys
8041ovn_attach n1 br-phys 192.168.0.1
8042ovs-vsctl -- add-port br-int hv1-vif1 -- \
8043 set interface hv1-vif1 external-ids:iface-id=foo1 \
8044 options:tx_pcap=hv1/vif1-tx.pcap \
8045 options:rxq_pcap=hv1/vif1-rx.pcap \
8046 ofport-request=1
8047
8048sim_add gw1
8049as gw1
8050ovs-vsctl add-br br-phys
8051ovn_attach n1 br-phys 192.168.0.2
8052
8053sim_add gw2
8054as gw2
8055ovs-vsctl add-br br-phys
8056ovn_attach n1 br-phys 192.168.0.4
8057
8058sim_add ext1
8059as ext1
8060ovs-vsctl add-br br-phys
8061ovn_attach n1 br-phys 192.168.0.3
8062ovs-vsctl -- add-port br-int ext1-vif1 -- \
8063 set interface ext1-vif1 external-ids:iface-id=outside1 \
8064 options:tx_pcap=ext1/vif1-tx.pcap \
8065 options:rxq_pcap=ext1/vif1-rx.pcap \
8066 ofport-request=1
8067
8068# Pre-populate the hypervisors' ARP tables so that we don't lose any
8069# packets for ARP resolution (native tunneling doesn't queue packets
8070# for ARP resolution).
74868f2c 8071OVN_POPULATE_ARP
75f9e007
GZ
8072
8073ovn-nbctl create Logical_Router name=R0
8074ovn-nbctl create Logical_Router name=R1
8075
8076ovn-nbctl ls-add foo
8077ovn-nbctl ls-add join
8078ovn-nbctl ls-add alice
8079ovn-nbctl ls-add outside
8080
8081#Connect foo to R0
8082ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
8083ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
8084 type=router options:router-port=R0-foo \
8085 -- lsp-set-addresses foo-R0 router
8086
8087#Connect R0 to join
8088ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
8089ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
8090 type=router options:router-port=R0-join \
8091 -- lsp-set-addresses join-R0 router
8092
8093#Connect join to R1
8094ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
8095ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
8096 type=router options:router-port=R1-join \
8097 -- lsp-set-addresses join-R1 router
8098
8099#add route rules
8100ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
8101ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
8102
8103# Connect alice to R1 as distributed router gateway port on gw1
8104ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8105
8106ovn-nbctl \
8107 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8108 chassis_name=gw1 \
8109 priority=20 -- \
8110 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8111 chassis_name=gw2 \
8112 priority=10 -- \
8113 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8114
8115ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8116 type=router options:router-port=alice \
8117 -- lsp-set-addresses rp-alice router
8118
8119# Create logical port foo1 in foo
8120ovn-nbctl lsp-add foo foo1 \
8121-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8122
8123# Create logical port outside1 in outside
8124ovn-nbctl lsp-add outside outside1 \
8125-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8126
8127# Create localnet port in alice
8128ovn-nbctl lsp-add alice ln-alice
8129ovn-nbctl lsp-set-addresses ln-alice unknown
8130ovn-nbctl lsp-set-type ln-alice localnet
8131ovn-nbctl lsp-set-options ln-alice network_name=phys
8132
8133# Create localnet port in outside
8134ovn-nbctl lsp-add outside ln-outside
8135ovn-nbctl lsp-set-addresses ln-outside unknown
8136ovn-nbctl lsp-set-type ln-outside localnet
8137ovn-nbctl lsp-set-options ln-outside network_name=phys
8138
8139# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8140# mapping to the external network, is the one generating packets
8141as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8142as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8143as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8144
8145AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8146
8147# Allow some time for ovn-northd and ovn-controller to catch up.
8148# XXX This should be more systematic.
8149sleep 2
8150
8151ip_to_hex() {
8152 printf "%02x%02x%02x%02x" "$@"
8153}
8154
8155reset_pcap_file() {
8156 local iface=$1
8157 local pcap_file=$2
8158 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8159options:rxq_pcap=dummy-rx.pcap
8160 rm -f ${pcap_file}*.pcap
8161 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8162options:rxq_pcap=${pcap_file}-rx.pcap
8163}
8164
8165test_ip_packet()
8166{
8167 local active_gw=$1
8168 local backup_gw=$2
8169
8170 # Send ip packet between foo1 and outside1
8171 src_mac="f00000010203" # foo1 mac
8172 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8173 src_ip=`ip_to_hex 192 168 1 2`
8174 dst_ip=`ip_to_hex 172 16 1 3`
8175 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8176
8177 # ARP request packet to expect at outside1
8178 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8179
8180 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8181
8182 # Send ARP reply from outside1 back to the router
8183 # XXX: note, we could avoid this if we plug this port into a netns
8184 # and setup the IP address into the port, so the kernel would simply reply
8185 src_mac="000002010203"
8186 reply_mac="f00000010204"
8187 dst_ip=`ip_to_hex 172 16 1 3`
8188 src_ip=`ip_to_hex 172 16 1 1`
8189 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8190
8191 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8192
86c9d79a
NS
8193 OVS_WAIT_UNTIL([
8194 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8195grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8196 ])
8197
75f9e007
GZ
8198 # Packet to Expect at ext1 chassis, outside1 port
8199 src_mac="000002010203"
8200 dst_mac="f00000010204"
8201 src_ip=`ip_to_hex 192 168 1 2`
8202 dst_ip=`ip_to_hex 172 16 1 3`
8203 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8204 echo $expected > ext1-vif1.expected
8205
8206 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8207 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8208 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8209
8210 # Resend packet from foo1 to outside1
8211 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8212
8213 sleep 1
8214
8215 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8216 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8217 AT_CHECK([grep $expected packets | sort], [0], [expout])
8218 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8219 AT_CHECK([grep $expected packets | sort], [0], [])
8220}
8221
8222test_ip_packet gw1 gw2
8223
8e1d9349 8224ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 8225 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8226 chassis_name=gw1 \
8227 priority=10 -- \
8228 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8229 chassis_name=gw2 \
8230 priority=20 -- \
8231 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8232
8233test_ip_packet gw2 gw1
8234
8235OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8236AT_CLEANUP
8237
41a15b71
MS
8238AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8239AT_SKIP_IF([test $HAVE_PYTHON = no])
8240ovn_start
8241
8242# Logical network:
8243# One LR R1 that has switches foo (192.168.1.0/24) and
8244# alice (172.16.1.0/24) connected to it. The logical port
8245# between R1 and alice has a "redirect-chassis" specified,
8246# i.e. it is the distributed router gateway port.
8247# Switch alice also has a localnet port defined.
8248# An additional switch outside has a localnet port and the
8249# same subnet as alice (172.16.1.0/24).
8250
8251# Physical network:
8252# Three hypervisors hv[123].
8253# hv1 hosts vif foo1.
8254# hv2 is the "redirect-chassis" that hosts the distributed
8255# router gateway port.
8256# hv3 hosts vif outside1.
8257# In order to show that connectivity works only through hv2,
8258# an initial round of tests is run without any bridge-mapping
8259# defined for the localnet on hv2. These tests are expected
8260# to fail.
8261# Subsequent tests are run after defining the bridge-mapping
8262# for the localnet on hv2. These tests are expected to succeed.
8263
8264# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 8265# to logical ports.
41a15b71
MS
8266net_add n1
8267
8268sim_add hv1
8269as hv1
8270ovs-vsctl add-br br-phys
8271ovn_attach n1 br-phys 192.168.0.1
8272ovs-vsctl -- add-port br-int hv1-vif1 -- \
8273 set interface hv1-vif1 external-ids:iface-id=foo1 \
8274 options:tx_pcap=hv1/vif1-tx.pcap \
8275 options:rxq_pcap=hv1/vif1-rx.pcap \
8276 ofport-request=1
8277
8278sim_add hv2
8279as hv2
8280ovs-vsctl add-br br-phys
8281ovn_attach n1 br-phys 192.168.0.2
8282
8283sim_add hv3
8284as hv3
8285ovs-vsctl add-br br-phys
8286ovn_attach n1 br-phys 192.168.0.3
8287ovs-vsctl -- add-port br-int hv3-vif1 -- \
8288 set interface hv3-vif1 external-ids:iface-id=outside1 \
8289 options:tx_pcap=hv3/vif1-tx.pcap \
8290 options:rxq_pcap=hv3/vif1-rx.pcap \
8291 ofport-request=1
8292
8293# Pre-populate the hypervisors' ARP tables so that we don't lose any
8294# packets for ARP resolution (native tunneling doesn't queue packets
8295# for ARP resolution).
74868f2c 8296OVN_POPULATE_ARP
41a15b71
MS
8297
8298ovn-nbctl create Logical_Router name=R1
8299
8300ovn-nbctl ls-add foo
8301ovn-nbctl ls-add alice
8302ovn-nbctl ls-add outside
8303
8304# Connect foo to R1
8305ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8306ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8307 type=router options:router-port=foo \
8308 -- lsp-set-addresses rp-foo router
8309
8310# Connect alice to R1 as distributed router gateway port on hv2
8311ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8312 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8313ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8314 type=router options:router-port=alice \
8315 -- lsp-set-addresses rp-alice router
8316
8317# Create logical port foo1 in foo
8318ovn-nbctl lsp-add foo foo1 \
8319-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8320
8321# Create logical port outside1 in outside
8322ovn-nbctl lsp-add outside outside1 \
8323-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8324
8325# Create localnet port in alice
8326ovn-nbctl lsp-add alice ln-alice
8327ovn-nbctl lsp-set-addresses ln-alice unknown
8328ovn-nbctl lsp-set-type ln-alice localnet
8329ovn-nbctl lsp-set-options ln-alice network_name=phys
8330
8331# Create localnet port in outside
8332ovn-nbctl lsp-add outside ln-outside
8333ovn-nbctl lsp-set-addresses ln-outside unknown
8334ovn-nbctl lsp-set-type ln-outside localnet
8335ovn-nbctl lsp-set-options ln-outside network_name=phys
8336
8337# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8338as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8339as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8340
8341
8342# Allow some time for ovn-northd and ovn-controller to catch up.
8343# XXX This should be more systematic.
8344sleep 2
8345
8346echo "---------NB dump-----"
8347ovn-nbctl show
8348echo "---------------------"
8349ovn-nbctl list logical_router
8350echo "---------------------"
8351ovn-nbctl list logical_router_port
8352echo "---------------------"
8353
8354echo "---------SB dump-----"
8355ovn-sbctl list datapath_binding
8356echo "---------------------"
8357ovn-sbctl list port_binding
8358echo "---------------------"
8359ovn-sbctl dump-flows
8360echo "---------------------"
8361ovn-sbctl list chassis
8362ovn-sbctl list encap
1da17a0b 8363echo "------ Gateway_Chassis dump (SBDB) -------"
8364ovn-sbctl list Gateway_Chassis
8365echo "------ Port_Binding chassisredirect -------"
8366ovn-sbctl find Port_Binding type=chassisredirect
8367echo "-------------------------------------------"
41a15b71
MS
8368
8369echo "------ hv1 dump ----------"
8370as hv1 ovs-ofctl show br-int
8371as hv1 ovs-ofctl dump-flows br-int
8372echo "------ hv2 dump ----------"
8373as hv2 ovs-ofctl show br-int
8374as hv2 ovs-ofctl dump-flows br-int
8375echo "------ hv3 dump ----------"
8376as hv3 ovs-ofctl show br-int
8377as hv3 ovs-ofctl dump-flows br-int
8378echo "--------------------------"
8379
1da17a0b 8380
41a15b71
MS
8381# Check that redirect mapping is programmed only on hv2
8382AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8383])
8384AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
8385])
8386# Check that hv1 sends chassisredirect port traffic to hv2
8387AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
8388])
8389AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8390])
8391# Check that arp reply on distributed gateway port is only programmed on hv2
b0684540 8392AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
41a15b71 8393])
b0684540 8394AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
41a15b71
MS
8395])
8396
8397
8398ip_to_hex() {
8399 printf "%02x%02x%02x%02x" "$@"
8400}
8401
8402
8403: > hv2-vif1.expected
8404: > hv3-vif1.expected
8405
8406# test_arp INPORT SHA SPA TPA [REPLY_HA]
8407#
8408# Causes a packet to be received on INPORT. The packet is an ARP
8409# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
8410# it should be the hardware address of the target to expect to receive in an
8411# ARP reply; otherwise no reply is expected.
8412#
8413# INPORT is an logical switch port number, e.g. 11 for vif11.
8414# SHA and REPLY_HA are each 12 hex digits.
8415# SPA and TPA are each 8 hex digits.
8416test_arp() {
8417 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
8418 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
8419 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
8420
8421 if test X$reply_ha != X; then
8422 # Expect to receive the reply, if any.
8423 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
8424 echo $reply >> hv${hv}-vif$inport.expected
8425 fi
8426}
8427
8428rtr_ip=$(ip_to_hex 172 16 1 1)
8429foo_ip=$(ip_to_hex 192 168 1 2)
8430outside_ip=$(ip_to_hex 172 16 1 3)
8431
8432echo $rtr_ip
8433echo $foo_ip
8434echo $outside_ip
8435
8436# ARP for router IP address from outside1, no response expected
8437test_arp 3 1 f00000010204 $outside_ip $rtr_ip
8438
8439# Now check the packets actually received against the ones expected.
8440OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8441
8442# Send ip packet between foo1 and outside1
8443src_mac="f00000010203"
8444dst_mac="000001010203"
8445src_ip=`ip_to_hex 192 168 1 2`
8446dst_ip=`ip_to_hex 172 16 1 3`
8447packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8448
8449# Now check the packets actually received against the ones expected.
8450OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8451
8452# Now add bridge-mappings on hv2, which should make everything work
8453as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8454
8455# Allow some time for ovn-northd and ovn-controller to catch up.
8456# XXX This should be more systematic.
8457sleep 2
8458
8459# ARP for router IP address from outside1
8460test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
8461
8462# Now check the packets actually received against the ones expected.
8463OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8464
8465# Send ip packet between foo1 and outside1
8466src_mac="f00000010203"
8467dst_mac="000001010203"
8468src_ip=`ip_to_hex 192 168 1 2`
8469dst_ip=`ip_to_hex 172 16 1 3`
8470packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8471
41a15b71
MS
8472# Packet to Expect at outside1
8473src_mac="000002010203"
8474dst_mac="f00000010204"
41a15b71
MS
8475expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8476
41a15b71
MS
8477as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8478
8479echo "------ hv1 dump ----------"
8480as hv1 ovs-ofctl show br-int
8481as hv1 ovs-ofctl dump-flows br-int
8482echo "------ hv2 dump ----------"
8483as hv2 ovs-ofctl show br-int
8484as hv2 ovs-ofctl dump-flows br-int
8485echo "------ hv3 dump ----------"
8486as hv3 ovs-ofctl show br-int
8487as hv3 ovs-ofctl dump-flows br-int
8488echo "----------------------------"
8489
8490echo $expected >> hv3-vif1.expected
8491OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8492
8493#Check ovn-trace over "chassisredirect" port
8494AT_CAPTURE_FILE([trace])
8495ovn_trace () {
8496 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
8497}
8498
8499echo 'ip.ttl--;' > expout
8500echo 'eth.src = 00:00:02:01:02:03;' >> expout
8501echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8502echo 'output("ln-alice");' >> expout
8503AT_CHECK_UNQUOTED([ovn_trace foo 'inport == "foo1" && eth.src == f0:00:00:01:02:03 && eth.dst == 00:00:01:01:02:03 && ip4.src == 192.168.1.2 && ip4.dst == 172.16.1.3 && ip.ttl == 0xff'], [0], [expout])
8504
8505# Create logical port alice1 in alice on hv1
8506as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8507 set interface hv1-vif2 external-ids:iface-id=alice1 \
8508 options:tx_pcap=hv1/vif2-tx.pcap \
8509 options:rxq_pcap=hv1/vif2-rx.pcap \
8510 ofport-request=1
8511
8512ovn-nbctl lsp-add alice alice1 \
8513-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8514
8515# Create logical port foo2 in foo on hv2
8516as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8517 set interface hv2-vif1 external-ids:iface-id=foo2 \
8518 options:tx_pcap=hv2/vif1-tx.pcap \
8519 options:rxq_pcap=hv2/vif1-rx.pcap \
8520 ofport-request=1
8521
8522ovn-nbctl lsp-add foo foo2 \
8523-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8524
8525# Allow some time for ovn-northd and ovn-controller to catch up.
8526# XXX This should be more systematic.
8527sleep 1
8528
8529: > hv1-vif2.expected
8530
8531# Send ip packet between alice1 and foo2
8532src_mac="f00000010205"
8533dst_mac="000002010203"
8534src_ip=`ip_to_hex 172 16 1 4`
8535dst_ip=`ip_to_hex 192 168 1 3`
8536packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8537
8538as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8539
8540# Packet to Expect at foo2
8541src_mac="000001010203"
8542dst_mac="f00000010206"
8543src_ip=`ip_to_hex 172 16 1 4`
8544dst_ip=`ip_to_hex 192 168 1 3`
8545expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8546
8547echo $expected >> hv2-vif1.expected
f5f64552 8548OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 8549
0d31e5be 8550AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 8551])
8552
8e1d9349 8553ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 8554
0d31e5be 8555AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 8556])
8557
41a15b71
MS
8558OVN_CLEANUP([hv1],[hv2],[hv3])
8559
8560AT_CLEANUP
26b9e08d
MS
8561
8562AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8563AT_SKIP_IF([test $HAVE_PYTHON = no])
8564ovn_start
8565# Create logical switches
8566ovn-nbctl ls-add ls0
8567ovn-nbctl ls-add ls1
8568# Create distributed router
8569ovn-nbctl create Logical_Router name=lr0
8570# Add distributed gateway port to distributed router
8571ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8572 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8573ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8574 type=router options:router-port=lrp0 addresses="router"
8575# Add router port to ls1
8576ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8577ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8578 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
8579# Add logical ports for NAT rules
8580ovn-nbctl lsp-add ls1 foo1 \
8581-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8582ovn-nbctl lsp-add ls1 foo2 \
8583-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
8584# Add nat-addresses option
8585ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8586# Add NAT rules
8587AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8588AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8589AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.3 10.0.0.3 foo1 f0:00:00:00:00:03])
f40c5588 8590AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.4 10.0.0.4 foo2 f0:00:00:00:00:04])
26b9e08d
MS
8591
8592net_add n1
8593sim_add hv1
8594as hv1
8595ovs-vsctl add-br br-phys
8596ovn_attach n1 br-phys 192.168.0.1
8597
8598AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8599AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
8600
8601sim_add hv2
8602as hv2
8603ovs-vsctl add-br br-phys
8604ovn_attach n1 br-phys 192.168.0.2
8605# Initially test with no bridge-mapping on hv2, expect to receive no packets
8606
f40c5588
MS
8607sim_add hv3
8608as hv3
8609ovs-vsctl add-br br-phys
8610ovn_attach n1 br-phys 192.168.0.3
8611# Initially test with no bridge-mapping on hv3
8612
26b9e08d
MS
8613# Create a localnet port.
8614AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8615AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8616AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8617AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8618
8619# Allow some time for ovn-northd and ovn-controller to catch up.
8620# XXX This should be more systematic.
8621sleep 2
8622
8623# Expect no packets when hv2 bridge-mapping is not present
8624: > packets
8625OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8626
8627# Add bridge-mapping on hv2
f40c5588 8628AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
8629
8630# Wait for packets to be received.
8631OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8632trim_zeros() {
8633 sed 's/\(00\)\{1,\}$//'
8634}
8635$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8636expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8637echo $expected > expout
8638expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8639echo $expected >> expout
8640AT_CHECK([sort packets], [0], [expout])
f40c5588 8641sort packets | cat
26b9e08d 8642
f40c5588
MS
8643# Temporarily remove nat-addresses option to avoid race conditions
8644# due to GARP backoff
8645ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8646
8647reset_pcap_file() {
8648 local iface=$1
8649 local pcap_file=$2
8650 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8651options:rxq_pcap=dummy-rx.pcap
8652 rm -f ${pcap_file}*.pcap
8653 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8654options:rxq_pcap=${pcap_file}-rx.pcap
8655}
8656
8657as hv1 reset_pcap_file snoopvif hv1/snoopvif
8658
8659# Add OVS ports for foo1 and foo2 on hv3
8660ovs-vsctl -- add-port br-int hv3-vif1 -- \
8661 set interface hv3-vif1 external-ids:iface-id=foo1 \
8662 ofport-request=1
8663ovs-vsctl -- add-port br-int hv3-vif2 -- \
8664 set interface hv3-vif2 external-ids:iface-id=foo2 \
8665 ofport-request=2
8666
8667# Add bridge-mapping on hv3
8668AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8669
8670# Re-add nat-addresses option
8671ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8672
8673# Wait for packets to be received.
8674OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8675trim_zeros() {
8676 sed 's/\(00\)\{1,\}$//'
8677}
8678
8679$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8680expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8681echo $expected >> expout
8682expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8683echo $expected >> expout
8684AT_CHECK([sort packets], [0], [expout])
8685sort packets | cat
8686
8687OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
8688
8689AT_CLEANUP
6b785fd8 8690
85706c34
NS
8691# VLAN traffic for external network redirected through distributed router
8692# gateway port should use vlans(i.e input network vlan tag) across hypervisors
8693# instead of tunneling.
8694AT_SETUP([ovn -- vlan traffic for external network with distributed router gateway port])
8695AT_SKIP_IF([test $HAVE_PYTHON = no])
8696ovn_start
8697
8698# Logical network:
8699# # One LR R1 that has switches foo (192.168.1.0/24) and
8700# # alice (172.16.1.0/24) connected to it. The logical port
8701# # between R1 and alice has a "redirect-chassis" specified,
8702# # i.e. it is the distributed router gateway port(172.16.1.6).
8703# # Switch alice also has a localnet port defined.
8704# # An additional switch outside has the same subnet as alice
8705# # (172.16.1.0/24), a localnet port and nexthop port(172.16.1.1)
8706# # which will receive the packet destined for external network
8707# # (i.e 8.8.8.8 as destination ip).
8708
8709# Physical network:
8710# # Three hypervisors hv[123].
8711# # hv1 hosts vif foo1.
8712# # hv2 is the "redirect-chassis" that hosts the distributed router gateway port.
8713# # hv3 hosts nexthop port vif outside1.
8714# # All other tests connect hypervisors to network n1 through br-phys for tunneling.
8715# # But in this test, hv1 won't connect to n1(and no br-phys in hv1), and
8716# # in order to show vlans(instead of tunneling) used between hv1 and hv2,
8717# # a new network n2 created and hv1 and hv2 connected to this network through br-ex.
8718# # hv2 and hv3 are still connected to n1 network through br-phys.
8719net_add n1
8720
8721# We are not calling ovn_attach for hv1, to avoid adding br-phys.
8722# Tunneling won't work in hv1 as ovn-encap-ip is not added to any bridge in hv1
8723sim_add hv1
8724as hv1
8725ovs-vsctl \
8726 -- set Open_vSwitch . external-ids:system-id=hv1 \
8727 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
8728 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
8729 -- set Open_vSwitch . external-ids:ovn-encap-ip=192.168.0.1 \
8730 -- add-br br-int \
8731 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
8732 -- set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-ex
8733
8734start_daemon ovn-controller
8735ovs-vsctl -- add-port br-int hv1-vif1 -- \
8736 set interface hv1-vif1 external-ids:iface-id=foo1 \
8737 ofport-request=1
8738
8739sim_add hv2
8740as hv2
8741ovs-vsctl add-br br-phys
8742ovn_attach n1 br-phys 192.168.0.2
8743ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
8744
8745sim_add hv3
8746as hv3
8747ovs-vsctl add-br br-phys
8748ovn_attach n1 br-phys 192.168.0.3
8749ovs-vsctl -- add-port br-int hv3-vif1 -- \
8750 set interface hv3-vif1 external-ids:iface-id=outside1 \
8751 options:tx_pcap=hv3/vif1-tx.pcap \
8752 options:rxq_pcap=hv3/vif1-rx.pcap \
8753 ofport-request=1
8754ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="phys:br-phys"
8755
8756# Create network n2 for vlan connectivity between hv1 and hv2
8757net_add n2
8758
8759as hv1
8760ovs-vsctl add-br br-ex
8761net_attach n2 br-ex
8762
8763as hv2
8764ovs-vsctl add-br br-ex
8765net_attach n2 br-ex
8766
8767OVN_POPULATE_ARP
8768
8769ovn-nbctl create Logical_Router name=R1
8770
8771ovn-nbctl ls-add foo
8772ovn-nbctl ls-add alice
8773ovn-nbctl ls-add outside
8774
8775# Connect foo to R1
8776ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8777ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8778 type=router options:router-port=foo \
8779 -- lsp-set-addresses rp-foo router
8780
8781# Connect alice to R1 as distributed router gateway port (172.16.1.6) on hv2
8782ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.6/24 \
8783 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8784ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8785 type=router options:router-port=alice \
8786 -- lsp-set-addresses rp-alice router \
8787
8788# Create logical port foo1 in foo
8789ovn-nbctl lsp-add foo foo1 \
8790-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8791
8792# Create logical port outside1 in outside, which is a nexthop address
8793# for 172.16.1.0/24
8794ovn-nbctl lsp-add outside outside1 \
8795-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.1"
8796
8797# Set default gateway (nexthop) to 172.16.1.1
8798ovn-nbctl lr-route-add R1 "0.0.0.0/0" 172.16.1.1 alice
8799AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.6 192.168.1.1/24])
8800ovn-nbctl set Logical_Switch_Port rp-alice options:nat-addresses=router
8801
8802ovn-nbctl lsp-add foo ln-foo
8803ovn-nbctl lsp-set-addresses ln-foo unknown
8804ovn-nbctl lsp-set-options ln-foo network_name=public
8805ovn-nbctl lsp-set-type ln-foo localnet
8806AT_CHECK([ovn-nbctl set Logical_Switch_Port ln-foo tag=2])
8807
8808# Create localnet port in alice
8809ovn-nbctl lsp-add alice ln-alice
8810ovn-nbctl lsp-set-addresses ln-alice unknown
8811ovn-nbctl lsp-set-type ln-alice localnet
8812ovn-nbctl lsp-set-options ln-alice network_name=phys
8813
8814# Create localnet port in outside
8815ovn-nbctl lsp-add outside ln-outside
8816ovn-nbctl lsp-set-addresses ln-outside unknown
8817ovn-nbctl lsp-set-type ln-outside localnet
8818ovn-nbctl lsp-set-options ln-outside network_name=phys
8819
8820# Allow some time for ovn-northd and ovn-controller to catch up.
8821# XXX This should be more systematic.
8822ovn-nbctl --wait=hv --timeout=3 sync
8823
8824# Check that there is a logical flow in logical switch foo's pipeline
8825# to set the outport to rp-foo (which is expected).
8826OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
8827grep rp-foo | grep -v is_chassis_resident | wc -l`])
8828
8829# Set the option 'reside-on-redirect-chassis' for foo
8830ovn-nbctl set logical_router_port foo options:reside-on-redirect-chassis=true
8831# Check that there is a logical flow in logical switch foo's pipeline
8832# to set the outport to rp-foo with the condition is_chassis_redirect.
8833ovn-sbctl dump-flows foo
8834OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
8835grep rp-foo | grep is_chassis_resident | wc -l`])
8836
8837echo "---------NB dump-----"
8838ovn-nbctl show
8839echo "---------------------"
8840ovn-nbctl list logical_router
8841echo "---------------------"
8842ovn-nbctl list nat
8843echo "---------------------"
8844ovn-nbctl list logical_router_port
8845echo "---------------------"
8846
8847echo "---------SB dump-----"
8848ovn-sbctl list datapath_binding
8849echo "---------------------"
8850ovn-sbctl list port_binding
8851echo "---------------------"
8852ovn-sbctl dump-flows
8853echo "---------------------"
8854ovn-sbctl list chassis
8855echo "---------------------"
8856
8857for chassis in hv1 hv2 hv3; do
8858 as $chassis
8859 echo "------ $chassis dump ----------"
8860 ovs-vsctl show br-int
8861 ovs-ofctl show br-int
8862 ovs-ofctl dump-flows br-int
8863 echo "--------------------------"
8864done
8865
8866ip_to_hex() {
8867 printf "%02x%02x%02x%02x" "$@"
8868}
8869
8870foo1_ip=$(ip_to_hex 192 168 1 2)
8871gw_ip=$(ip_to_hex 172 16 1 6)
8872dst_ip=$(ip_to_hex 8 8 8 8)
8873nexthop_ip=$(ip_to_hex 172 16 1 1)
8874
8875foo1_mac="f00000010203"
8876foo_mac="000001010203"
8877gw_mac="000002010203"
8878nexthop_mac="f00000010204"
8879
8880# Send ip packet from foo1 to 8.8.8.8
8881src_mac="f00000010203"
8882dst_mac="000001010203"
8883packet=${foo_mac}${foo1_mac}08004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
8884
81e92852 8885# Wait for GARPs announcing gw IP to arrive
85706c34
NS
8886OVS_WAIT_UNTIL([
8887 test `as hv2 ovs-ofctl dump-flows br-int | grep table=66 | \
8888grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8889 ])
8890
8891# VLAN tagged packet with router port(192.168.1.1) MAC as destination MAC
8892# is expected on bridge connecting hv1 and hv2
8893expected=${foo_mac}${foo1_mac}8100000208004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
8894echo $expected > hv1-br-ex_n2.expected
8895
8896# Packet to Expect at outside1 i.e nexthop(172.16.1.1) port.
8897# As connection tracking not enabled for this test, snat can't be done on the packet.
8898# We still see foo1 as the source ip address. But source mac(gateway MAC) and
8899# dest mac(nexthop mac) are properly configured.
8900expected=${nexthop_mac}${gw_mac}08004500001c000000003f110100${foo1_ip}${dst_ip}0035111100080000
8901echo $expected > hv3-vif1.expected
8902
8903reset_pcap_file() {
8904 local iface=$1
8905 local pcap_file=$2
8906 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8907options:rxq_pcap=dummy-rx.pcap
8908 rm -f ${pcap_file}*.pcap
8909 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8910options:rxq_pcap=${pcap_file}-rx.pcap
8911}
8912
8913as hv1 reset_pcap_file br-ex_n2 hv1/br-ex_n2
8914as hv3 reset_pcap_file hv3-vif1 hv3/vif1
8915sleep 2
81e92852
DA
8916# Take note of how many packets arrived on the VLAN switch before generating
8917# further traffic
8918n_packets=`as hv1 ovs-ofctl dump-flows br-int table=65 | grep "priority=100,reg15=0x1,metadata=0x2" | grep actions=clone | sed 's/.*n_packets=\([[0-9]]\+\),.*/\1/'`
85706c34
NS
8919as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8920sleep 2
8921
8922# On hv1, the packet should not go from vlan switch pipleline to router
81e92852 8923# pipeline
85706c34 8924as hv1 ovs-ofctl dump-flows br-int
85706c34 8925AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep "priority=100,reg15=0x1,metadata=0x2" \
81e92852 8926| grep actions=clone | grep -v n_packets=$n_packets | wc -l], [0], [[0
85706c34
NS
8927]])
8928
8929# On hv1, table 32 check that no packet goes via the tunnel port
8930AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 \
8931| grep "NXM_NX_TUN_ID" | grep -v n_packets=0 | wc -l], [0], [[0
8932]])
8933
8934ip_packet() {
8935 grep "1010203f00000010203"
8936}
8937
8938# Check vlan tagged packet on the bridge connecting hv1 and hv2 with the
8939# foo1's mac.
8940$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-ex_n2-tx.pcap | ip_packet | uniq > hv1-br-ex_n2
8941cat hv1-br-ex_n2.expected > expout
8942AT_CHECK([sort hv1-br-ex_n2], [0], [expout])
8943
8944# Check expected packet on nexthop interface
8945$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/vif1-tx.pcap | grep ${foo1_ip}${dst_ip} | uniq > hv3-vif1
8946cat hv3-vif1.expected > expout
8947AT_CHECK([sort hv3-vif1], [0], [expout])
8948
8949OVN_CLEANUP([hv1],[hv2],[hv3])
8950AT_CLEANUP
8951
4364646c
ZKL
8952AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8953AT_KEYWORDS([ovn-nd_ra])
8954AT_SKIP_IF([test $HAVE_PYTHON = no])
8955ovn_start
8956
8957# In this test case we create 1 lswitch with 3 VIF ports attached,
8958# and a lrouter connected to the lswitch.
8959# We generate the Router solicitation packet and verify the Router Advertisement
8960# reply packet from the ovn-controller.
8961
8962# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8963# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8964# 'slaac' to allow lrp0 send RA for SLAAC mode.
8965ovn-nbctl ls-add lsw0
8966ovn-nbctl lr-add lr0
8967ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8968ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8969ovn-nbctl \
8970 -- lsp-add lsw0 lsp0 \
8971 -- set Logical_Switch_Port lsp0 type=router \
8972 options:router-port=lrp0 \
8973 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8974net_add n1
8975sim_add hv1
8976as hv1
8977ovs-vsctl add-br br-phys
8978ovn_attach n1 br-phys 192.168.0.2
8979
8980ovn-nbctl lsp-add lsw0 lp1
8981ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8982ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8983
8984ovn-nbctl lsp-add lsw0 lp2
8985ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8986ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8987
8988ovn-nbctl lsp-add lsw0 lp3
8989ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8990ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8991
8992# Add ACL rule for ICMPv6 on lsw0
8993ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8994ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8995ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8996ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8997
8998ovs-vsctl -- add-port br-int hv1-vif1 -- \
8999 set interface hv1-vif1 external-ids:iface-id=lp1 \
9000 options:tx_pcap=hv1/vif1-tx.pcap \
9001 options:rxq_pcap=hv1/vif1-rx.pcap \
9002 ofport-request=1
9003
9004ovs-vsctl -- add-port br-int hv1-vif2 -- \
9005 set interface hv1-vif2 external-ids:iface-id=lp2 \
9006 options:tx_pcap=hv1/vif2-tx.pcap \
9007 options:rxq_pcap=hv1/vif2-rx.pcap \
9008 ofport-request=2
9009
9010ovs-vsctl -- add-port br-int hv1-vif3 -- \
9011 set interface hv1-vif3 external-ids:iface-id=lp3 \
9012 options:tx_pcap=hv1/vif3-tx.pcap \
9013 options:rxq_pcap=hv1/vif3-rx.pcap \
9014 ofport-request=3
9015
9016# Allow some time for ovn-northd and ovn-controller to catch up.
9017# XXX This should be more systematic.
9018sleep 1
9019
9020reset_pcap_file() {
9021 local iface=$1
9022 local pcap_file=$2
9023 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9024options:rxq_pcap=dummy-rx.pcap
9025 rm -f ${pcap_file}*.pcap
9026 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9027options:rxq_pcap=${pcap_file}-rx.pcap
9028}
9029
9030# Make sure that ovn-controller has installed the corresponding OF Flow.
9031OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9032
9033# This shell function sends a Router Solicitation packet.
9034# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
9035test_ipv6_ra() {
9036 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
9037 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
9038
9039 local len=24
9040 local mtu_opt=""
9041 if test $mtu != 0; then
9042 len=`expr $len + 8`
9043 mtu_opt=05010000${mtu}
9044 fi
9045
9046 if test ${#prefix_opt} != 0; then
9047 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
9048 len=`expr $len + ${#prefix_opt} / 2`
9049 fi
9050
9051 len=$(printf "%x" $len)
9052 local lrp_mac=fa163e000001
9053 local lrp_lla=fe80000000000000f8163efffe000001
9054 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
9055 echo $reply >> $inport.expected
9056
9057 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
9058}
9059
9060AT_CAPTURE_FILE([ofctl_monitor0.log])
9061as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
9062--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
9063
9064# MTU is not set and the address mode is set to slaac
9065addr_mode=00
9066default_prefix_option_config=030440c0ffffffffffffffff00000000
9067src_mac=fa163e000002
9068src_lla=fe80000000000000f8163efffe000002
9069test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
9070
9071# NXT_RESUME should be 1.
9072OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9073
9074$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9075
9076cat 1.expected | cut -c -112 > expout
9077AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9078
9079# Skipping the ICMPv6 checksum.
9080cat 1.expected | cut -c 117- > expout
9081AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9082
9083rm -f *.expected
9084reset_pcap_file hv1-vif1 hv1/vif1
9085reset_pcap_file hv1-vif2 hv1/vif2
9086reset_pcap_file hv1-vif3 hv1/vif3
9087
9088# Set the MTU to 1500
9089ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
9090
9091# Make sure that ovn-controller has installed the corresponding OF Flow.
9092OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9093
9094addr_mode=00
9095default_prefix_option_config=030440c0ffffffffffffffff00000000
9096src_mac=fa163e000003
9097src_lla=fe80000000000000f8163efffe000003
9098mtu=000005dc
9099
9100test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9101
9102# NXT_RESUME should be 2.
9103OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9104
9105$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
9106
9107cat 2.expected | cut -c -112 > expout
9108AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9109
9110# Skipping the ICMPv6 checksum.
9111cat 2.expected | cut -c 117- > expout
9112AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9113
9114rm -f *.expected
9115reset_pcap_file hv1-vif1 hv1/vif1
9116reset_pcap_file hv1-vif2 hv1/vif2
9117reset_pcap_file hv1-vif3 hv1/vif3
9118
9119# Set the address mode to dhcpv6_stateful
9120ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
9121# Make sure that ovn-controller has installed the corresponding OF Flow.
9122OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9123
9124addr_mode=80
9125default_prefix_option_config=""
9126src_mac=fa163e000004
9127src_lla=fe80000000000000f8163efffe000004
9128mtu=000005dc
9129
9130test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9131
9132# NXT_RESUME should be 3.
9133OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9134
9135$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
9136
9137cat 3.expected | cut -c -112 > expout
9138AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
9139
9140# Skipping the ICMPv6 checksum.
9141cat 3.expected | cut -c 117- > expout
9142AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
9143
9144rm -f *.expected
9145reset_pcap_file hv1-vif1 hv1/vif1
9146reset_pcap_file hv1-vif2 hv1/vif2
9147reset_pcap_file hv1-vif3 hv1/vif3
9148
9149# Set the address mode to dhcpv6_stateless
9150ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
9151# Make sure that ovn-controller has installed the corresponding OF Flow.
9152OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9153
9154addr_mode=40
9155default_prefix_option_config=030440c0ffffffffffffffff00000000
9156src_mac=fa163e000002
9157src_lla=fe80000000000000f8163efffe000002
9158mtu=000005dc
9159
9160test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9161
9162# NXT_RESUME should be 4.
9163OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9164
9165$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9166
9167cat 1.expected | cut -c -112 > expout
9168AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9169
9170# Skipping the ICMPv6 checksum.
9171cat 1.expected | cut -c 117- > expout
9172AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9173
9174rm -f *.expected
9175reset_pcap_file hv1-vif1 hv1/vif1
9176reset_pcap_file hv1-vif2 hv1/vif2
9177reset_pcap_file hv1-vif3 hv1/vif3
9178
9179# Set the address mode to invalid.
9180ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
9181# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
9182OVS_WAIT_UNTIL([test 0 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9183
9184addr_mode=40
9185default_prefix_option_config=""
9186src_mac=fa163e000002
9187src_lla=fe80000000000000f8163efffe000002
9188mtu=000005dc
9189
9190test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9191
9192# NXT_RESUME should be 4 only.
9193OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9194
9195$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9196AT_CHECK([cat 1.packets], [0], [])
9197
9198OVN_CLEANUP([hv1])
9199AT_CLEANUP
9200
6b785fd8
GS
9201AT_SETUP([ovn -- /32 router IP address])
9202AT_SKIP_IF([test $HAVE_PYTHON = no])
9203ovn_start
9204
9205# Logical network:
9206# 2 LS 'foo' and 'alice' connected via router R1.
9207# R1 connects to 'alice' with a /32 IP address. We use static routes and
9208# nexthop to push traffic to a logical port in switch 'alice'
9209
9210ovn-nbctl lr-add R1
9211
9212ovn-nbctl ls-add foo
9213ovn-nbctl ls-add alice
9214
9215# Connect foo to R1
9216ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
9217ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
9218 options:router-port=foo addresses=\"00:00:00:01:02:03\"
9219
9220# Connect alice to R1.
9221ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
9222ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9223 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
9224
9225# Create logical port foo1 in foo
9226ovn-nbctl lsp-add foo foo1 \
9227-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9228
9229# Create logical port alice1 in alice
9230ovn-nbctl lsp-add alice alice1 \
9231-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
9232
9233#install default route in R1 to use alice1's IP address as nexthop
9234ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
9235
9236# Create two hypervisor and create OVS ports corresponding to logical ports.
9237net_add n1
9238
9239sim_add hv1
9240as hv1
9241ovs-vsctl add-br br-phys
9242ovn_attach n1 br-phys 192.168.0.1
9243ovs-vsctl -- add-port br-int hv1-vif1 -- \
9244 set interface hv1-vif1 external-ids:iface-id=foo1 \
9245 options:tx_pcap=hv1/vif1-tx.pcap \
9246 options:rxq_pcap=hv1/vif1-rx.pcap \
9247 ofport-request=1
9248
9249sim_add hv2
9250as hv2
9251ovs-vsctl add-br br-phys
9252ovn_attach n1 br-phys 192.168.0.2
9253ovs-vsctl -- add-port br-int hv2-vif1 -- \
9254 set interface hv2-vif1 external-ids:iface-id=alice1 \
9255 options:tx_pcap=hv2/vif1-tx.pcap \
9256 options:rxq_pcap=hv2/vif1-rx.pcap \
9257 ofport-request=1
9258
9259
9260# Pre-populate the hypervisors' ARP tables so that we don't lose any
9261# packets for ARP resolution (native tunneling doesn't queue packets
9262# for ARP resolution).
74868f2c 9263OVN_POPULATE_ARP
6b785fd8
GS
9264
9265# Allow some time for ovn-northd and ovn-controller to catch up.
9266# XXX This should be more systematic.
9267sleep 1
9268
9269ip_to_hex() {
9270 printf "%02x%02x%02x%02x" "$@"
9271}
9272
9273# Send ip packets between foo1 and alice1
9274src_mac="f00000010203"
9275dst_mac="000000010203"
9276src_ip=`ip_to_hex 192 168 1 2`
9277dst_ip=`ip_to_hex 10 0 0 2`
9278packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9279
9280# Send the first packet to trigger a ARP response and population of
9281# mac_bindings table.
9282as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9283OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
b0b27a83 9284ovn-nbctl --wait=hv sync
6b785fd8
GS
9285
9286# Packet to Expect at 'alice1'
9287src_mac="000000010204"
9288dst_mac="f00000010204"
9289src_ip=`ip_to_hex 192 168 1 2`
9290dst_ip=`ip_to_hex 10 0 0 2`
9291echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
9292
9293OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
9294
9295OVN_CLEANUP([hv1],[hv2])
9296
9297AT_CLEANUP
2a38ef45
DA
9298
9299AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
9300AT_SKIP_IF([test $HAVE_PYTHON = no])
9301ovn_start
9302
9303ovn-nbctl ls-add ls1
9304
9305# Add localport to the switch
9306ovn-nbctl lsp-add ls1 lp01
9307ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
9308ovn-nbctl lsp-set-type lp01 localport
9309
9310net_add n1
9311
9312for i in 1 2; do
9313 sim_add hv$i
9314 as hv$i
9315 ovs-vsctl add-br br-phys
9316 ovn_attach n1 br-phys 192.168.0.$i
9317 ovs-vsctl add-port br-int vif01 -- \
9318 set Interface vif01 external-ids:iface-id=lp01 \
9319 options:tx_pcap=hv${i}/vif01-tx.pcap \
9320 options:rxq_pcap=hv${i}/vif01-rx.pcap \
9321 ofport-request=${i}0
9322
9323 ovs-vsctl add-port br-int vif${i}1 -- \
9324 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
9325 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
9326 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
9327 ofport-request=${i}1
9328
9329 ovn-nbctl lsp-add ls1 lp${i}1
9330 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
9331 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
9332
9333 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
9334done
9335
9336ovn-nbctl --wait=sb sync
9337ovn-sbctl dump-flows
9338
74868f2c 9339OVN_POPULATE_ARP
2a38ef45
DA
9340
9341# Given the name of a logical port, prints the name of the hypervisor
9342# on which it is located.
9343vif_to_hv() {
9344 echo hv${1%?}
9345}
9346#
9347# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
9348#
9349# This shell function causes a packet to be received on INPORT. The packet's
9350# content has Ethernet destination DST and source SRC (each exactly 12 hex
9351# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
9352# logical switch port numbers, e.g. 11 for vif11.
9353#
9354# EOUT is the end-to-end output port, that is, where the packet will end up
9355# after possibly bouncing through one or more localnet ports. LOUT is the
9356# logical output port, which might be a localnet port, as seen by ovn-trace
9357# (which doesn't know what localnet ports are connected to and therefore can't
9358# figure out the end-to-end answer).
9359#
9360# DEFHV is the default hypervisor from where the packet is going to be sent
9361# if the source port is a localport.
9362for i in 1 2; do
9363 for j in 0 1; do
9364 : > $i$j.expected
9365 done
9366done
9367test_packet() {
9368 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
9369 echo "$@"
9370
9371 # First try tracing the packet.
9372 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
9373 if test $lout != drop; then
9374 echo "output(\"$lout\");"
9375 fi > expout
9376 AT_CAPTURE_FILE([trace])
9377 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
9378
9379 # Then actually send a packet, for an end-to-end test.
9380 local packet=$(echo $dst$src | sed 's/://g')${eth}
9381 hv=`vif_to_hv $inport`
9382 # If hypervisor 0 (localport) use the defhv parameter
da88b550 9383 if test $hv = hv0; then
2a38ef45
DA
9384 hv=$defhv
9385 fi
9386 vif=vif$inport
9387 as $hv ovs-appctl netdev-dummy/receive $vif $packet
9388 if test $eout != drop; then
9389 echo $packet >> ${eout#lp}.expected
9390 fi
9391}
9392
9393
9394# lp11 and lp21 are on different hypervisors
9395test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
9396test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
9397
9398# Both VIFs should be able to reach the localport on their own HV
9399test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
9400test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
9401
9402# Packet sent from localport on same hv should reach the vif
9403test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
9404test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
9405
9406# Packet sent from localport on different hv should be dropped
9407test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
9408test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
9409
9410# Now check the packets actually received against the ones expected.
9411for i in 1 2; do
9412 for j in 0 1; do
9413 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
9414 done
9415done
9416
9417OVN_CLEANUP([hv1],[hv2])
9418
9419AT_CLEANUP
1da17a0b 9420
9421AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
9422AT_SKIP_IF([test $HAVE_PYTHON = no])
9423ovn_start
9424
9425net_add n1
9426
9427# create gateways with external network connectivity
9428
9429for i in 1 2; do
9430 sim_add gw$i
9431 as gw$i
9432 ovs-vsctl add-br br-phys
9433 ovn_attach n1 br-phys 192.168.0.$i
9434 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9435done
9436
9437ovn-nbctl ls-add inside
9438ovn-nbctl ls-add outside
9439
9440# create hypervisors with a vif port each to an internal network
9441
9442for i in 1 2; do
9443 sim_add hv$i
9444 as hv$i
9445 ovs-vsctl add-br br-phys
9446 ovn_attach n1 br-phys 192.168.0.1$i
9447 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9448 set interface hv$i-vif1 external-ids:iface-id=inside$i \
9449 options:tx_pcap=hv$i/vif1-tx.pcap \
9450 options:rxq_pcap=hv$i/vif1-rx.pcap \
9451 ofport-request=1
9452
9453 ovn-nbctl lsp-add inside inside$i \
9454 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
9455
9456done
9457
74868f2c 9458OVN_POPULATE_ARP
1da17a0b 9459
9460ovn-nbctl create Logical_Router name=R1
9461
9462# Connect inside to R1
9463ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9464ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9465 type=router options:router-port=inside \
9466 -- lsp-set-addresses rp-inside router
9467
9468# Connect outside to R1 as distributed router gateway port on gw1+gw2
9469ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9470
9471ovn-nbctl --id=@gc0 create Gateway_Chassis \
9472 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9473 --id=@gc1 create Gateway_Chassis \
9474 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9475 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9476
9477ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9478 type=router options:router-port=outside \
9479 -- lsp-set-addresses rp-outside router
9480
9481# Create localnet port in outside
9482ovn-nbctl lsp-add outside ln-outside
9483ovn-nbctl lsp-set-addresses ln-outside unknown
9484ovn-nbctl lsp-set-type ln-outside localnet
9485ovn-nbctl lsp-set-options ln-outside network_name=phys
9486
9487# Allow some time for ovn-northd and ovn-controller to catch up.
9488# XXX This should be more systematic.
8e1d9349 9489ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 9490
9491echo "---------NB dump-----"
9492ovn-nbctl show
9493echo "---------------------"
9494ovn-nbctl list logical_router
9495echo "---------------------"
9496ovn-nbctl list logical_router_port
9497echo "---------------------"
9498
9499echo "---------SB dump-----"
9500ovn-sbctl list datapath_binding
9501echo "---------------------"
9502ovn-sbctl list port_binding
9503echo "---------------------"
9504ovn-sbctl dump-flows
9505echo "---------------------"
9506ovn-sbctl list chassis
9507ovn-sbctl list encap
9508echo "---------------------"
9509echo "------ Gateway_Chassis dump (SBDB) -------"
9510ovn-sbctl list Gateway_Chassis
9511echo "------ Port_Binding chassisredirect -------"
9512ovn-sbctl find Port_Binding type=chassisredirect
9513echo "-------------------------------------------"
9514
3475695e
VA
9515for chassis in gw1 gw2 hv1 hv2; do
9516 as $chassis
9517 echo "------ $chassis dump ----------"
9518 ovs-ofctl show br-int
9519 ovs-ofctl dump-flows br-int
3475695e
VA
9520 echo "--------------------------"
9521done
508b7f96 9522function bfd_dump() {
9523 for chassis in gw1 gw2 hv1 hv2; do
9524 as $chassis
9525 echo "------ $chassis dump (BFD)----"
9526 echo "BFD (from $chassis):"
9527 # dump BFD config and status to the other chassis
9528 for chassis2 in gw1 gw2 hv1 hv2; do
9529 if [[ "$chassis" != "$chassis2" ]]; then
9530 echo " -> $chassis2:"
9531 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
9532 fi
9533 done
9534 echo "--------------------------"
9535 done
9536}
9537
9538bfd_dump
1da17a0b 9539
9540hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9541hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9542hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9543hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9544
9545echo $hv1_gw1_ofport
9546echo $hv1_gw2_ofport
9547echo $hv2_gw1_ofport
9548echo $hv2_gw2_ofport
9549
9550echo "--- hv1 ---"
9551as hv1 ovs-ofctl dump-flows br-int table=32
9552
9553echo "--- hv2 ---"
9554as hv2 ovs-ofctl dump-flows br-int table=32
9555
508b7f96 9556gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
9557gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9558
1da17a0b 9559AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport | wc -l], [0], [1
9560])
9561
9562AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport | wc -l], [0], [1
9563])
9564
508b7f96 9565sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9566
9567# make sure that flows for handling the outside router port reside on gw1
66d89287 9568AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9569]])
66d89287 9570AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9571]])
9572
9573# make sure ARP responder flows for outside router port reside on gw1 too
9574AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
9575]])
9576AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
9577]])
9578
9579
9580
9581# check that the chassis redirect port has been claimed by the gw1 chassis
9582AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9583 [0],[[1
9584]])
9585
9586
9587# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 9588
9589ovn-nbctl --id=@gc0 create Gateway_Chassis \
9590 name=outside_gw1 chassis_name=gw1 priority=10 -- \
9591 --id=@gc1 create Gateway_Chassis \
9592 name=outside_gw2 chassis_name=gw2 priority=20 -- \
9593 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9594
508b7f96 9595
1da17a0b 9596# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 9597ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 9598
508b7f96 9599# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 9600AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport | wc -l], [0], [1
9601])
9602
9603AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport | wc -l], [0], [1
9604])
9605
508b7f96 9606# check that the chassis redirect port has been reclaimed by the gw2 chassis
9607AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
9608 [0],[[1
9609]])
1da17a0b 9610
3475695e
VA
9611# check BFD enablement on tunnel ports from gw1 #########
9612as gw1
9613for chassis in gw2 hv1 hv2; do
9614 echo "checking gw1 -> $chassis"
9615 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9616 [[enable=true
9617]])
9618done
9619
9620
9621# check BFD enablement on tunnel ports from gw2 ##########
9622as gw2
9623for chassis in gw1 hv1 hv2; do
9624 echo "checking gw2 -> $chassis"
9625 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9626 [[enable=true
9627]])
9628done
9629
9630# check BFD enablement on tunnel ports from hv1 ###########
9631as hv1
9632for chassis in gw1 gw2; do
9633 echo "checking hv1 -> $chassis"
9634 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9635 [[enable=true
9636]])
9637done
9638# make sure BFD is not enabled to hv2, we don't need it
9639AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
2d661a27 9640 [[
3475695e
VA
9641]])
9642
9643
9644# check BFD enablement on tunnel ports from hv2 ##########
9645as hv2
9646for chassis in gw1 gw2; do
9647 echo "checking hv2 -> $chassis"
9648 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9649 [[enable=true
9650]])
9651done
9652# make sure BFD is not enabled to hv1, we don't need it
9653AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
2d661a27 9654 [[
3475695e
VA
9655]])
9656
508b7f96 9657sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9658
9659# make sure that flows for handling the outside router port reside on gw2 now
66d89287 9660AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9661]])
66d89287 9662AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9663]])
9664
9665# disconnect GW2 from the network, GW1 should take over
9666as gw2
9667port=${sandbox}_br-phys
9668as main ovs-vsctl del-port n1 $port
9669sleep 4
9670
9671bfd_dump
9672
9673# make sure that flows for handling the outside router port reside on gw2 now
66d89287 9674AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9675]])
66d89287 9676AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9677]])
9678
9679# check that the chassis redirect port has been reclaimed by the gw1 chassis
9680AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9681 [0],[[1
9682]])
9683
2d661a27
NS
9684ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
9685as gw2
9686for chassis in gw1 hv1 hv2; do
9687 echo "checking gw2 -> $chassis"
9688 OVS_WAIT_UNTIL([
9689 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9690 test "$bfd_cfg" = "enable=true min_rx=2000"
9691])
9692done
9693ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
9694for chassis in gw1 hv1 hv2; do
9695 echo "checking gw2 -> $chassis"
9696 OVS_WAIT_UNTIL([
9697 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9698 test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
9699])
9700done
9701ovn-nbctl remove NB_Global . options "bfd-min-rx"
9702ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
9703for chassis in gw1 hv1 hv2; do
9704 echo "checking gw2 -> $chassis"
9705 OVS_WAIT_UNTIL([
9706 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9707 test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
9708])
9709done
9710
1da17a0b 9711OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
9712
9713AT_CLEANUP
acfc41ff
VAK
9714
9715AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
9716AT_SKIP_IF([test $HAVE_PYTHON = no])
9717ovn_start
9718ovn-nbctl ls-add ls0
9719ovn-nbctl ls-add ls1
9720ovn-nbctl create Logical_Router name=lr0
9721ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
9722
9723ovn-nbctl --id=@gc0 create Gateway_Chassis \
9724 name=outside_gw1 chassis_name=hv2 priority=10 -- \
9725 --id=@gc1 create Gateway_Chassis \
9726 name=outside_gw2 chassis_name=hv3 priority=1 -- \
9727 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9728
9729ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9730 type=router options:router-port=lrp0 addresses="router"
9731ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9732ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9733 type=router options:router-port=lrp1 addresses="router"
9734
9735# Add NAT rules
9736AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
9737
9738net_add n1
9739sim_add hv1
9740as hv1
9741ovs-vsctl add-br br-phys
9742ovn_attach n1 br-phys 192.168.0.1
9743AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9744AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
9745
9746sim_add hv2
9747as hv2
9748ovs-vsctl add-br br-phys
9749ovn_attach n1 br-phys 192.168.0.2
9750AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9751
9752sim_add hv3
9753as hv3
9754ovs-vsctl add-br br-phys
9755ovn_attach n1 br-phys 192.168.0.3
9756AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9757
9758# Create a localnet port.
9759AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9760AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9761AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9762AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
9763
9764# wait for earlier changes to take effect
6c8d3d69 9765AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
acfc41ff
VAK
9766
9767reset_pcap_file() {
9768 local iface=$1
9769 local pcap_file=$2
9770 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9771options:rxq_pcap=dummy-rx.pcap
9772 rm -f ${pcap_file}*.pcap
9773 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9774options:rxq_pcap=${pcap_file}-rx.pcap
9775}
9776
9777as hv1 reset_pcap_file snoopvif hv1/snoopvif
9778as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9779as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9780# add nat-addresses option
6c8d3d69 9781ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
acfc41ff
VAK
9782
9783# Wait for packets to be received through hv2.
9784OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9785trim_zeros() {
9786 sed 's/\(00\)\{1,\}$//'
9787}
9788
2db7bb2c 9789only_broadcast_from_lrp1() {
9790 grep "fffffffffffff00000000001"
9791}
9792
acfc41ff 9793garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 9794echo $garp > expout
9795
9796$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
9797echo "packets on hv1-snoopvif:"
9798cat hv1_snoop_tx
9799AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 9800$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
acfc41ff
VAK
9801echo "packets on hv2 br-phys tx"
9802cat hv2_br_phys_tx
9803AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 9804$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
acfc41ff
VAK
9805echo "packets on hv3 br-phys tx"
9806cat hv3_br_phys_tx
9807AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9808
9809
9810# at this point, we invert the priority of the gw chassis between hv2 and hv3
9811
9812ovn-nbctl --wait=hv \
9813 --id=@gc0 create Gateway_Chassis \
9814 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9815 --id=@gc1 create Gateway_Chassis \
9816 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9817 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9818
9819
9820as hv1 reset_pcap_file snoopvif hv1/snoopvif
9821as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9822as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9823
9824# Wait for packets to be received.
9825OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9826trim_zeros() {
9827 sed 's/\(00\)\{1,\}$//'
9828}
9829
2db7bb2c 9830$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 9831AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 9832$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
acfc41ff 9833AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 9834$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
acfc41ff 9835AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
9836
9837# change localnet port tag.
9838AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9839
9840# wait for earlier changes to take effect
6c8d3d69 9841AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
03b85a58
GL
9842
9843# update nat-addresses option
6c8d3d69
HZ
9844ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9845ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
03b85a58
GL
9846
9847as hv1 reset_pcap_file snoopvif hv1/snoopvif
9848as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9849as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9850
9851# Wait for packets to be received.
9852OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9853trim_zeros() {
9854 sed 's/\(00\)\{1,\}$//'
9855}
9856
9857garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9858echo $garp > expout
9859
9860$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9861AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9862$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9863AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9864$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9865AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9866
acfc41ff
VAK
9867OVN_CLEANUP([hv1],[hv2],[hv3])
9868
9869AT_CLEANUP
79371ff5 9870
9871AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9872AT_SKIP_IF([test $HAVE_PYTHON = no])
9873ovn_start
9874
9875net_add n1
9876
9877# create two gateways with external network connectivity
9878for i in 1 2; do
9879 sim_add gw$i
9880 as gw$i
9881 ovs-vsctl add-br br-phys
9882 ovn_attach n1 br-phys 192.168.0.$i
9883 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9884done
9885
9886ovn-nbctl ls-add inside
9887ovn-nbctl ls-add outside
9888
9889# create one hypervisors with a vif port the internal network
9890sim_add hv1
9891as hv1
9892ovs-vsctl add-br br-phys
9893ovn_attach n1 br-phys 192.168.0.11
9894ovs-vsctl -- add-port br-int hv1-vif1 -- \
9895 set interface hv1-vif1 external-ids:iface-id=inside1 \
9896 options:tx_pcap=hv1/vif1-tx.pcap \
9897 options:rxq_pcap=hv1/vif1-rx.pcap \
9898 ofport-request=1
9899
9900ovn-nbctl lsp-add inside inside1 \
9901 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9902
9903
74868f2c 9904OVN_POPULATE_ARP
79371ff5 9905
9906ovn-nbctl create Logical_Router name=R1
9907
9908# Connect inside to R1
9909ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9910ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9911 type=router options:router-port=inside \
9912 -- lsp-set-addresses rp-inside router
9913
9914# Connect outside to R1 as distributed router gateway port on gw1+gw2
9915ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9916
9917ovn-nbctl --id=@gc0 create Gateway_Chassis \
9918 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9919 --id=@gc1 create Gateway_Chassis \
9920 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9921 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9922
9923ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9924 type=router options:router-port=outside \
9925 -- lsp-set-addresses rp-outside router
9926
9927# Create localnet port in outside
9928ovn-nbctl lsp-add outside ln-outside
9929ovn-nbctl lsp-set-addresses ln-outside unknown
9930ovn-nbctl lsp-set-type ln-outside localnet
9931ovn-nbctl lsp-set-options ln-outside network_name=phys
9932
9933# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 9934ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 9935
9936# currently when ovn-controller is restarted, the old entry is deleted
9937# and a new one is created, which leaves the Gateway_Chassis with
9938# an empty chassis for a while. NOTE: restarting ovn-controller in tests
9939# doesn't have the same effect because "name" is conserved, and the
9940# Chassis entry is not replaced.
9941
3a0c5805 9942> gw1/ovn-controller.log
325b2b1a 9943
79371ff5 9944gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9945ovn-sbctl destroy Chassis $gw2_chassis
9946
9947# Ensure ovn-controller has processed latest sbdb update
9948# ovn-nbctl --wait=hv sync
9949
9950AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9951
9952OVN_CLEANUP([gw1],[gw2],[hv1])
9953
9954AT_CLEANUP
63d91afa 9955
b1a3a6a4
NS
9956AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9957AT_KEYWORDS([ovn-nd_ns for unknown mac])
9958AT_SKIP_IF([test $HAVE_PYTHON = no])
9959ovn_start
9960
9961ovn-nbctl ls-add sw0_ip6
9962ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9963ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9964"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9965
9966ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9967"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9968
9969ovn-nbctl lr-add lr0_ip6
847dc1c2 9970ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
9971ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9972ovn-nbctl lsp-set-type lrp0_ip6-attachment router
bec7c641 9973ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
b1a3a6a4
NS
9974ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9975ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9976
9977ovn-nbctl ls-add public
9978ovn-nbctl lsp-add public ln-public
9979ovn-nbctl lsp-set-addresses ln-public unknown
9980ovn-nbctl lsp-set-type ln-public localnet
9981ovn-nbctl lsp-set-options ln-public network_name=phys
9982
9983ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
99842001:db8:1:0:200:02ff:fe01:0204/64 \
9985-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9986
250ed434
NS
9987#install static route
9988ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
9989ip_prefix="\:\:/0" nexthop="2001\:db8\:1\:0\:200\:02ff\:fe01\:1305" \
9990-- add Logical_Router lr0_ip6 static_routes @lrt
b1a3a6a4
NS
9991
9992ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9993rp-ip6_public type=router options:router-port=ip6_public \
9994-- lsp-set-addresses rp-ip6_public router
9995
9996net_add n1
9997sim_add hv1
9998as hv1
9999ovs-vsctl add-br br-phys
10000ovn_attach n1 br-phys 192.168.0.2
10001
10002ovs-vsctl -- add-port br-int hv1-vif1 -- \
10003 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
10004 options:tx_pcap=hv1/vif1-tx.pcap \
10005 options:rxq_pcap=hv1/vif1-rx.pcap \
10006 ofport-request=1
10007ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10008
86c9d79a 10009OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
bec7c641
NS
10010
10011# There should be 2 Neighbor Advertisement flows for the router port
10012# aef0:: ip address in logical switch pipeline with action nd_na_router.
10013AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
10014grep "nd_na_router" | wc -l], [0], [2
10015])
10016
10017# There should be 4 Neighbor Advertisement flows with action nd_na_router
10018# in the router pipeline for the router lr0_ip6.
10019AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
10020wc -l], [0], [4
10021])
10022
86c9d79a
NS
10023cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
10024
10025# There is only one chassis.
10026chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
10027OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
b1a3a6a4
NS
10028
10029trim_zeros() {
10030 sed 's/\(00\)\{1,\}$//'
10031}
10032
250ed434
NS
10033reset_pcap_file() {
10034 local iface=$1
10035 local pcap_file=$2
10036 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10037options:rxq_pcap=dummy-rx.pcap
10038 rm -f ${pcap_file}*.pcap
10039 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10040options:rxq_pcap=${pcap_file}-rx.pcap
10041}
10042
b1a3a6a4
NS
10043# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
10044# addresses. ovn-controller should generate an IPv6 NS request for IPv6
10045# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
10046# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10047# This function sends ipv6 packet
10048test_ipv6() {
250ed434
NS
10049 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10050 local dst_mcast_mac=$6 mcast_node_ip=$7 nd_target=$8
b1a3a6a4
NS
10051
10052 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
10053 packet=${packet}8000000000000000
b1a3a6a4 10054
b1a3a6a4 10055 src_mac=000002010204
250ed434
NS
10056 expected_packet=${dst_mcast_mac}${src_mac}86dd6000000000203aff${src_ip}
10057 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000
10058 expected_packet=${expected_packet}${nd_target}0101${src_mac}
b1a3a6a4
NS
10059
10060 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
250ed434 10061 rm -f ipv6_ns.expected
b1a3a6a4
NS
10062 echo $expected_packet >> ipv6_ns.expected
10063}
10064
10065src_mac=506400000002
10066dst_mac=00000000af01
10067src_ip=aef0000000000000526400fffe000002
250ed434
NS
10068dst_ip=20010db800010000020002fffe010205
10069dst_mcast_mac=3333ff010205
10070mcast_node_ip=ff0200000000000000000001ff010205
10071nd_target=20010db800010000020002fffe010205
b1a3a6a4
NS
10072# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
10073# should be received by the ports attached to br-phys.
250ed434
NS
10074test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
10075$mcast_node_ip $nd_target
10076
10077OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
10078OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
10079
10080$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
10081trim_zeros > 1.packets
10082$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
10083trim_zeros > 2.packets
10084
10085cat ipv6_ns.expected | cut -c -112 > expout
10086AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
10087AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
10088
10089# Skipping the ICMPv6 checksum
10090cat ipv6_ns.expected | cut -c 117- > expout
10091AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
10092AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
10093
10094# Now send a packet with destination ip other than
10095# 2001:db8:1:0:200:02ff:fe01:0204/64 prefix.
10096reset_pcap_file br-phys_n1 hv1/br-phys_n1
10097reset_pcap_file br-phys hv1/br-phys
10098
10099src_mac=506400000002
10100dst_mac=00000000af01
10101src_ip=aef0000000000000526400fffe000002
10102dst_ip=20020ab8000100000200020000020306
10103# multicast mac of the nexthop IP - 2001:db8:1:0:200:02ff:fe01:1305
10104dst_mcast_mac=3333ff011305
10105mcast_node_ip=ff0200000000000000000001ff011305
10106nd_target=20010db800010000020002fffe011305
10107test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
10108$mcast_node_ip $nd_target
b1a3a6a4 10109
86c9d79a
NS
10110OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
10111OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
10112
b1a3a6a4
NS
10113$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
10114trim_zeros > 1.packets
10115$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
10116trim_zeros > 2.packets
10117
10118cat ipv6_ns.expected | cut -c -112 > expout
10119AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
10120AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
10121
10122# Skipping the ICMPv6 checksum
10123cat ipv6_ns.expected | cut -c 117- > expout
10124AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
10125AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
10126
10127OVN_CLEANUP([hv1])
10128
10129AT_CLEANUP
10130
63d91afa
LR
10131AT_SETUP([ovn -- options:requested-chassis for logical port])
10132ovn_start
10133
10134net_add n1
10135
10136ovn-nbctl ls-add ls0
10137ovn-nbctl lsp-add ls0 lsp0
10138
10139# create two hypervisors, each with one vif port
10140sim_add hv1
10141as hv1
10142ovs-vsctl add-br br-phys
10143ovn_attach n1 br-phys 192.168.0.11
99cc5c92
NS
10144ovs-vsctl -- add-port br-int hv1-vif0 -- \
10145set Interface hv1-vif0 ofport-request=1
63d91afa
LR
10146
10147sim_add hv2
10148as hv2
10149ovs-vsctl add-br br-phys
10150ovn_attach n1 br-phys 192.168.0.12
99cc5c92
NS
10151ovs-vsctl -- add-port br-int hv2-vif0 -- \
10152set Interface hv2-vif0 ofport-request=1
63d91afa
LR
10153
10154# Allow only chassis hv1 to bind logical port lsp0.
10155ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
10156
10157# Allow some time for ovn-northd and ovn-controller to catch up.
10158ovn-nbctl --wait=hv --timeout=3 sync
10159
10160# Retrieve hv1 and hv2 chassis UUIDs from southbound database
2aa57f08
HZ
10161ovn-sbctl wait-until chassis hv1
10162ovn-sbctl wait-until chassis hv2
63d91afa
LR
10163hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
10164hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
10165
10166# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
10167echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
10168as hv2
10169ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
10170
10171OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
10172AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
10173
99cc5c92
NS
10174# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
10175AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
10176AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
10177
10178# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
63d91afa
LR
10179echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
10180as hv1
10181ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
10182
10183OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
2aa57f08 10184AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
63d91afa 10185
99cc5c92
NS
10186# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
10187as hv1 ovs-ofctl dump-flows br-int
10188AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
10189AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
10190
10191# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
63d91afa
LR
10192# the requested chassis for lsp0 is changed from hv1 to hv2.
10193echo "verifying that lsp0 binding moves when requested-chassis is changed"
10194
10195ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
10196OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
2aa57f08 10197OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
63d91afa 10198
99cc5c92
NS
10199# (6) Chassis hv2 should add flows and hv1 should not.
10200AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
10201AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
10202
10203AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
10204AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
10205
63d91afa
LR
10206OVN_CLEANUP([hv1],[hv2])
10207
10208AT_CLEANUP
bd32425f
RB
10209
10210AT_SETUP([ovn -- options:requested-chassis with hostname])
10211
10212ovn_start
10213
10214ovn-nbctl ls-add ls0
10215ovn-nbctl lsp-add ls0 lsp0
10216
10217net_add n1
10218sim_add hv1
10219as hv1
10220ovs-vsctl add-br br-phys
10221ovn_attach n1 br-phys 192.168.0.11
99cc5c92 10222ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
bd32425f 10223
362ab40a 10224ovn-sbctl wait-until chassis hv1
bd32425f
RB
10225hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
10226echo "hv1_hostname=${hv1_hostname}"
10227ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
10228as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
10229
10230hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
10231echo "hv1_uuid=${hv1_uuid}"
10232OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
10233AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
99cc5c92
NS
10234AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
10235AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
bd32425f
RB
10236
10237ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
10238OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
10239ovn-nbctl --wait=hv --timeout=3 sync
10240AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
99cc5c92
NS
10241AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
10242AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
bd32425f
RB
10243
10244OVN_CLEANUP([hv1])
10245
10246AT_CLEANUP
4446661a
MM
10247
10248AT_SETUP([ovn -- IPv6 periodic RA])
10249ovn_start
10250
10251# This test sets up two hypervisors.
10252# hv1 and hv2 run ovn-controllers, and
10253# each has a VIF connected to the same
10254# logical switch in OVN. The logical
10255# switch is connected to a logical
10256# router port that is configured to send
10257# periodic router advertisements.
10258#
10259# The reason for having two ovn-controller
10260# hypervisors is to ensure that the
10261# periodic RAs being sent by each ovn-controller
10262# are kept to their local hypervisors. If the
10263# packets are not kept local, then each port
10264# will receive too many RAs.
10265
10266net_add n1
10267sim_add hv1
10268sim_add hv2
10269as hv1
10270ovs-vsctl add-br br-phys
10271ovn_attach n1 br-phys 192.168.0.2
10272as hv2
10273ovs-vsctl add-br br-phys
10274ovn_attach n1 br-phys 192.168.0.3
10275
10276ovn-nbctl lr-add ro
1ea1b0d0 10277ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
4446661a
MM
10278
10279ovn-nbctl ls-add sw
10280ovn-nbctl lsp-add sw sw-ro
10281ovn-nbctl lsp-set-type sw-ro router
10282ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
10283ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
10284ovn-nbctl lsp-add sw sw-p1
10285ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
10286ovn-nbctl lsp-add sw sw-p2
10287ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
10288
10289ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
10290ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
10291ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
10292ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
10293
86c9d79a
NS
10294for i in 1 2 ; do
10295 as hv$i
10296 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10297 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
10298 options:tx_pcap=hv$i/vif1-tx.pcap \
10299 options:rxq_pcap=hv$i/vif1-rx.pcap \
4446661a
MM
10300 ofport-request=1
10301done
10302
86c9d79a
NS
10303OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
10304OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
4446661a
MM
10305
10306reset_pcap_file() {
10307 local iface=$1
10308 local pcap_file=$2
10309 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10310options:rxq_pcap=dummy-rx.pcap
10311 rm -f ${pcap_file}*.pcap
10312 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10313options:rxq_pcap=${pcap_file}-rx.pcap
10314
10315}
10316
10317construct_expected_ra() {
10318 local src_mac=000000000001
10319 local dst_mac=333300000001
10320 local src_addr=fe80000000000000020000fffe000001
10321 local dst_addr=ff020000000000000000000000000001
10322
10323 local mtu=$1
10324 local ra_mo=$2
10325 local ra_prefix_la=$3
10326
10327 local slla=0101${src_mac}
10328 local mtu_opt=""
10329 if test $mtu != 0; then
10330 mtu_opt=05010000${mtu}
10331 fi
10332 shift 3
10333
10334 local prefix=""
10335 while [[ $# -gt 0 ]] ; do
10336 local size=$1
10337 local net=$2
10338 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
10339 shift 2
10340 done
10341
895ceaf7 10342 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
4446661a
MM
10343 local icmp=8600XXXX${ra}
10344
10345 local ip_len=$(expr ${#icmp} / 2)
1ea1b0d0 10346 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
4446661a
MM
10347
10348 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
10349 local eth=${dst_mac}${src_mac}86dd${ip}
10350 local packet=${eth}
10351 echo $packet >> expected
10352}
10353
10354ra_test() {
10355 construct_expected_ra $@
10356
10357 for i in hv1 hv2 ; do
10358 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
10359
10360 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
10361
10362 cat expected | cut -c -112 > expout
10363 AT_CHECK([cat packets | cut -c -112], [0], [expout])
10364
10365 # Skip ICMPv6 checksum.
10366 cat expected | cut -c 117- > expout
10367 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
10368
10369 rm -f packets
10370 as $i reset_pcap_file $i-vif1 $i/vif1
10371 done
10372
10373 rm -f expected
10374}
10375
10376# Baseline test with no MTU
10377ra_test 0 00 c0 40 aef00000000000000000000000000000
10378
10379# Now make sure an MTU option makes it
10380ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
10381ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
10382
10383# Now test for multiple network prefixes
10384ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
10385ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
10386
10387# Test a different address mode now
10388ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
10389ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
10390
10391# And the other address mode
10392ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
10393ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
10394
10395OVN_CLEANUP([hv1],[hv2])
10396AT_CLEANUP
4826add0
LB
10397
10398AT_SETUP([ovn -- ACL reject rule test])
10399AT_KEYWORDS([acl-reject])
10400AT_SKIP_IF([test $HAVE_PYTHON = no])
10401ovn_start
10402
10403# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
10404#
10405# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10406# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
10407# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
10408# unreachable frame generated from ACL rule hit
10409#
10410# INPORT is a lport number, e.g. 11 for vif11.
10411# HV is a hypervisor number
10412# ETH_SRC and ETH_DST are each 12 hex digits.
10413# IPV4_SRC and IPV4_DST are each 8 hex digits.
10414# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10415test_ip_packet() {
10416 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
10417 local exp_ip_chksum=$8 exp_icmp_chksum=$9
10418 shift 9
10419
10420 local ip_ttl=ff
10421 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
10422
10423 local reply_icmp_ttl=ff
10424 local icmp_type_code_response=0301
10425 local icmp_data=00000000
10426 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
10427 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
10428 echo $reply >> vif$inport.expected
10429
10430 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10431}
10432
c319fabc
LB
10433# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
10434#
10435# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
10436# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
10437# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
10438test_ipv6_packet() {
10439 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
10440 shift 7
10441
10442 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
10443 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
10444
10445 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
10446 echo $reply >> vif$inport.expected
10447
10448 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10449}
10450
c20ab6aa
LB
10451# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
10452#
10453# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10454# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10455# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
10456#
10457# INPORT is an lport number, e.g. 11 for vif11.
10458# HV is an hypervisor number
10459# ETH_SRC and ETH_DST are each 12 hex digits.
10460# IPV4_SRC and IPV4_DST are each 8 hex digits.
10461# TCP_SPORT and TCP_DPORT are 4 hex digits.
10462# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10463test_tcp_syn_packet() {
10464 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
10465 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10466 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10467 shift 12
10468
10469 local ip_ttl=ff
10470 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10471
10472 local tcp_rst_ttl=ff
10473 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10474 echo $reply >> vif$inport.expected
10475
10476 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10477}
10478
4826add0
LB
10479# Create hypervisors hv[123].
10480# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
10481# Add all of the vifs to a single logical switch sw0.
10482
10483net_add n1
10484ovn-nbctl ls-add sw0
10485for i in 1 2 3; do
10486 sim_add hv$i
10487 as hv$i
10488 ovs-vsctl add-br br-phys
10489 ovn_attach n1 br-phys 192.168.0.$i
10490
10491 for j in 1 2 3; do
10492 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
10493 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
10494
10495 ovs-vsctl -- add-port br-int vif$i$j -- \
10496 set interface vif$i$j \
10497 external-ids:iface-id=sw0-p$i$j \
10498 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
10499 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
10500 ofport-request=$i$j
10501 done
10502done
10503
10504OVN_POPULATE_ARP
10505# allow some time for ovn-northd and ovn-controller to catch up.
10506sleep 1
10507
10508ip_to_hex() {
10509 printf "%02x%02x%02x%02x" "$@"
10510}
10511
10512for i in 1 2 3; do
10513 : > vif${i}1.expected
10514done
10515
10516ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
10517ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
10518ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
732965bc
HZ
10519
10520# Allow some time for ovn-northd and ovn-controller to catch up.
10521ovn-nbctl --timeout=3 --wait=hv sync
4826add0
LB
10522
10523test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
10524test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
10525test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
10526
c319fabc
LB
10527test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
10528
c20ab6aa
LB
10529test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 8b40 3039 0000 7d8d 4486
10530test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 7d8d 4486
10531test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 7d82 4486
10532
4826add0
LB
10533for i in 1 2 3; do
10534 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
10535done
10536
10537OVN_CLEANUP([hv1], [hv2], [hv3])
10538AT_CLEANUP
689829d5
HZ
10539
10540AT_SETUP([ovn -- Port Groups])
10541AT_KEYWORDS([ovnpg])
10542AT_SKIP_IF([test $HAVE_PYTHON = no])
10543ovn_start
10544
10545# Logical network:
10546#
10547# Three logical switches ls1, ls2, ls3.
10548# One logical router lr0 connected to ls[123],
10549# with nine subnets, three per logical switch:
10550#
10551# lrp11 on ls1 for subnet 192.168.11.0/24
10552# lrp12 on ls1 for subnet 192.168.12.0/24
10553# lrp13 on ls1 for subnet 192.168.13.0/24
10554# ...
10555# lrp33 on ls3 for subnet 192.168.33.0/24
10556#
10557# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10558# digits are the subnet and the last digit distinguishes the VIF.
10559#
10560# This test will create two port groups and uses them in ACL.
10561
10562get_lsp_uuid () {
10563 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10564}
10565
10566pg1_ports=
10567pg2_ports=
10568for i in 1 2 3; do
10569 ovn-nbctl ls-add ls$i
10570 for j in 1 2 3; do
10571 for k in 1 2 3; do
10572 ovn-nbctl \
10573 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
10574 -- lsp-set-addresses lp$i$j$k \
10575 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
689829d5
HZ
10576 # logical ports lp[12]?1 belongs to port group pg1
10577 if test $i != 3 && test $k == 1; then
10578 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10579 fi
10580 # logical ports lp[23]?2 belongs to port group pg2
10581 if test $i != 1 && test $k == 2; then
10582 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10583 fi
10584 done
10585 done
10586done
10587
10588ovn-nbctl lr-add lr0
10589for i in 1 2 3; do
10590 for j in 1 2 3; do
10591 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10592 ovn-nbctl \
10593 -- lsp-add ls$i lrp$i$j-attachment \
10594 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10595 options:router-port=lrp$i$j \
10596 addresses='"00:00:00:00:ff:'$i$j'"'
10597 done
10598done
10599
10600ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
10601ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10602
10603# create ACLs on all lswitches to drop traffic from pg2 to pg1
10604ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10605ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10606ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10607
10608# Physical network:
10609#
10610# Three hypervisors hv[123].
10611# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10612# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10613# lp?3[123] all on hv3.
10614
10615# Given the name of a logical port, prints the name of the hypervisor
10616# on which it is located.
10617vif_to_hv() {
10618 case $1 in dnl (
10619 ?11) echo 1 ;; dnl (
10620 ?12 | ?21 | ?22) echo 2 ;; dnl (
10621 ?13 | ?23 | ?3?) echo 3 ;;
10622 esac
10623}
10624
10625# Given the name of a logical port, prints the name of its logical router
10626# port, e.g. "vif_to_lrp 123" yields 12.
10627vif_to_lrp() {
10628 echo ${1%?}
10629}
10630
10631# Given the name of a logical port, prints the name of its logical
10632# switch, e.g. "vif_to_ls 123" yields 1.
10633vif_to_ls() {
10634 echo ${1%??}
10635}
10636
10637net_add n1
10638for i in 1 2 3; do
10639 sim_add hv$i
10640 as hv$i
10641 ovs-vsctl add-br br-phys
10642 ovn_attach n1 br-phys 192.168.0.$i
10643done
10644for i in 1 2 3; do
10645 for j in 1 2 3; do
10646 for k in 1 2 3; do
10647 hv=`vif_to_hv $i$j$k`
10648 as hv$hv ovs-vsctl \
10649 -- add-port br-int vif$i$j$k \
10650 -- set Interface vif$i$j$k \
10651 external-ids:iface-id=lp$i$j$k \
10652 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10653 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10654 ofport-request=$i$j$k
10655 done
10656 done
10657done
10658
10659# Pre-populate the hypervisors' ARP tables so that we don't lose any
10660# packets for ARP resolution (native tunneling doesn't queue packets
10661# for ARP resolution).
10662OVN_POPULATE_ARP
10663
10664# Allow some time for ovn-northd and ovn-controller to catch up.
10665# XXX This should be more systematic.
10666sleep 1
10667
10668# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10669#
10670# This shell function causes a packet to be received on INPORT. The packet's
10671# content has Ethernet destination DST and source SRC (each exactly 12 hex
10672# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
10673# more) list the VIFs on which the packet should be received. INPORT and the
10674# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
10675for i in 1 2 3; do
10676 for j in 1 2 3; do
10677 for k in 1 2 3; do
10678 : > $i$j$k.expected
10679 done
10680 done
10681done
10682test_ip() {
10683 # This packet has bad checksums but logical L3 routing doesn't check.
10684 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10685 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
10686 shift; shift; shift; shift; shift
10687 hv=hv`vif_to_hv $inport`
10688 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
10689 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
10690 in_ls=`vif_to_ls $inport`
10691 in_lrp=`vif_to_lrp $inport`
10692 for outport; do
10693 out_ls=`vif_to_ls $outport`
10694 if test $in_ls = $out_ls; then
10695 # Ports on the same logical switch receive exactly the same packet.
10696 echo $packet
10697 else
10698 # Routing decrements TTL and updates source and dest MAC
10699 # (and checksum).
10700 out_lrp=`vif_to_lrp $outport`
10701 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10702 fi >> $outport.expected
10703 done
10704}
10705
10706as hv1 ovs-vsctl --columns=name,ofport list interface
10707as hv1 ovn-sbctl list port_binding
10708as hv1 ovn-sbctl list datapath_binding
10709as hv1 ovn-sbctl list port_group
10710as hv1 ovn-sbctl list address_set
10711as hv1 ovn-sbctl dump-flows
10712as hv1 ovs-ofctl dump-flows br-int
10713
10714# Send IP packets between all pairs of source and destination ports,
10715# packets matches ACL (pg2 to pg1) should be dropped
10716ip_to_hex() {
10717 printf "%02x%02x%02x%02x" "$@"
10718}
10719for is in 1 2 3; do
10720 for js in 1 2 3; do
10721 for ks in 1 2 3; do
10722 bcast=
10723 s=$is$js$ks
10724 smac=f00000000$s
10725 sip=`ip_to_hex 192 168 $is$js $ks`
10726 for id in 1 2 3; do
10727 for jd in 1 2 3; do
10728 for kd in 1 2 3; do
10729 d=$id$jd$kd
10730 dip=`ip_to_hex 192 168 $id$jd $kd`
10731 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10732 if test $d != $s; then unicast=$d; else unicast=; fi
10733
10734 # packets matches ACL should be dropped
10735 if test $id != 3 && test $kd == 1; then
10736 if test $is != 1 && test $ks == 2; then
10737 unicast=
10738 fi
10739 fi
10740 test_ip $s $smac $dmac $sip $dip $unicast #1
10741 done
10742 done
10743 done
10744 done
10745 done
10746done
10747
10748# Allow some time for packet forwarding.
10749# XXX This can be improved.
10750sleep 1
10751
10752# Now check the packets actually received against the ones expected.
10753for i in 1 2 3; do
10754 for j in 1 2 3; do
10755 for k in 1 2 3; do
10756 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10757 [$i$j$k.expected])
10758 done
10759 done
10760done
10761
10762# Gracefully terminate daemons
10763OVN_CLEANUP([hv1], [hv2], [hv3])
10764AT_CLEANUP
1beb60af
HZ
10765
10766AT_SETUP([ovn -- ACLs on Port Groups])
10767AT_KEYWORDS([ovnpg_acl])
10768AT_SKIP_IF([test $HAVE_PYTHON = no])
10769ovn_start
10770
10771# Logical network:
10772#
10773# Three logical switches ls1, ls2, ls3.
10774# One logical router lr0 connected to ls[123],
10775# with nine subnets, three per logical switch:
10776#
10777# lrp11 on ls1 for subnet 192.168.11.0/24
10778# lrp12 on ls1 for subnet 192.168.12.0/24
10779# lrp13 on ls1 for subnet 192.168.13.0/24
10780# ...
10781# lrp33 on ls3 for subnet 192.168.33.0/24
10782#
10783# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10784# digits are the subnet and the last digit distinguishes the VIF.
10785#
10786# This test will create two port groups and ACLs will be applied on them.
10787
10788get_lsp_uuid () {
10789 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10790}
10791
10792pg1_ports=
10793pg2_ports=
10794for i in 1 2 3; do
10795 ovn-nbctl ls-add ls$i
10796 for j in 1 2 3; do
10797 for k in 1 2 3; do
10798 ovn-nbctl \
10799 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
10800 -- lsp-set-addresses lp$i$j$k \
10801 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
1beb60af
HZ
10802 # logical ports lp[12]?1 belongs to port group pg1
10803 if test $i != 3 && test $k == 1; then
10804 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10805 fi
10806 # logical ports lp[23]?2 belongs to port group pg2
10807 if test $i != 1 && test $k == 2; then
10808 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10809 fi
10810 done
10811 done
10812done
10813
10814ovn-nbctl lr-add lr0
10815for i in 1 2 3; do
10816 for j in 1 2 3; do
10817 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10818 ovn-nbctl \
10819 -- lsp-add ls$i lrp$i$j-attachment \
10820 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10821 options:router-port=lrp$i$j \
10822 addresses='"00:00:00:00:ff:'$i$j'"'
10823 done
10824done
10825
d87e0897 10826ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
1beb60af
HZ
10827ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10828
10829# create ACLs on pg1 to drop traffic from pg2 to pg1
d87e0897
HZ
10830ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
10831ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
cdc9a84a 10832 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
1beb60af
HZ
10833
10834# Physical network:
10835#
10836# Three hypervisors hv[123].
10837# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10838# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10839# lp?3[123] all on hv3.
10840
10841# Given the name of a logical port, prints the name of the hypervisor
10842# on which it is located.
10843vif_to_hv() {
10844 case $1 in dnl (
10845 ?11) echo 1 ;; dnl (
10846 ?12 | ?21 | ?22) echo 2 ;; dnl (
10847 ?13 | ?23 | ?3?) echo 3 ;;
10848 esac
10849}
10850
10851# Given the name of a logical port, prints the name of its logical router
10852# port, e.g. "vif_to_lrp 123" yields 12.
10853vif_to_lrp() {
10854 echo ${1%?}
10855}
10856
10857# Given the name of a logical port, prints the name of its logical
10858# switch, e.g. "vif_to_ls 123" yields 1.
10859vif_to_ls() {
10860 echo ${1%??}
10861}
10862
10863net_add n1
10864for i in 1 2 3; do
10865 sim_add hv$i
10866 as hv$i
10867 ovs-vsctl add-br br-phys
10868 ovn_attach n1 br-phys 192.168.0.$i
10869done
10870for i in 1 2 3; do
10871 for j in 1 2 3; do
10872 for k in 1 2 3; do
10873 hv=`vif_to_hv $i$j$k`
10874 as hv$hv ovs-vsctl \
10875 -- add-port br-int vif$i$j$k \
10876 -- set Interface vif$i$j$k \
10877 external-ids:iface-id=lp$i$j$k \
10878 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10879 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10880 ofport-request=$i$j$k
10881 done
10882 done
10883done
10884
10885# Pre-populate the hypervisors' ARP tables so that we don't lose any
10886# packets for ARP resolution (native tunneling doesn't queue packets
10887# for ARP resolution).
10888OVN_POPULATE_ARP
10889
10890# Allow some time for ovn-northd and ovn-controller to catch up.
10891# XXX This should be more systematic.
10892sleep 1
10893
cdc9a84a
HZ
10894lsp_to_mac() {
10895 echo f0:00:00:00:0${1:0:1}:${1:1:2}
10896}
10897
10898lrp_to_mac() {
10899 echo 00:00:00:00:ff:$1
10900}
10901
10902# test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
1beb60af 10903#
cdc9a84a
HZ
10904# This shell function causes a ICMP packet to be received on INPORT.
10905# The OUTPORTs (zero or more) list the VIFs on which the packet should
10906# be received. INPORT and the OUTPORTs are specified as logical switch
10907# port numbers, e.g. 123 for vif123.
1beb60af
HZ
10908for i in 1 2 3; do
10909 for j in 1 2 3; do
10910 for k in 1 2 3; do
10911 : > $i$j$k.expected
10912 done
10913 done
10914done
cdc9a84a
HZ
10915
10916test_icmp() {
10917 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
10918 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
10919 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
10920 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
10921 icmp4.code==0"
10922 shift; shift; shift; shift; shift; shift
1beb60af 10923 hv=hv`vif_to_hv $inport`
cdc9a84a 10924 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
1beb60af
HZ
10925 in_ls=`vif_to_ls $inport`
10926 in_lrp=`vif_to_lrp $inport`
10927 for outport; do
10928 out_ls=`vif_to_ls $outport`
10929 if test $in_ls = $out_ls; then
10930 # Ports on the same logical switch receive exactly the same packet.
cdc9a84a 10931 echo $packet | ovstest test-ovn expr-to-packets
1beb60af
HZ
10932 else
10933 # Routing decrements TTL and updates source and dest MAC
10934 # (and checksum).
10935 out_lrp=`vif_to_lrp $outport`
cdc9a84a
HZ
10936 exp_smac=`lrp_to_mac $out_lrp`
10937 exp_dmac=`lsp_to_mac $outport`
10938 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
10939 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
10940 icmp4.type==$icmp_type && icmp4.code==0"
10941 echo $exp_packet | ovstest test-ovn expr-to-packets
10942
1beb60af
HZ
10943 fi >> $outport.expected
10944 done
10945}
10946
10947as hv1 ovs-vsctl --columns=name,ofport list interface
10948as hv1 ovn-sbctl list port_binding
10949as hv1 ovn-sbctl list datapath_binding
10950as hv1 ovn-sbctl list port_group
10951as hv1 ovn-sbctl list address_set
10952as hv1 ovn-sbctl dump-flows
10953as hv1 ovs-ofctl dump-flows br-int
10954
10955# Send IP packets between all pairs of source and destination ports,
10956# packets matches ACL1 but not ACL2 should be dropped
10957ip_to_hex() {
10958 printf "%02x%02x%02x%02x" "$@"
10959}
10960for is in 1 2 3; do
10961 for js in 1 2 3; do
10962 for ks in 1 2 3; do
10963 bcast=
10964 s=$is$js$ks
cdc9a84a
HZ
10965 slsp_mac=`lsp_to_mac $s`
10966 slrp_mac=`lrp_to_mac $is$js`
10967 sip=192.168.$is$js.$ks
1beb60af
HZ
10968 for id in 1 2 3; do
10969 for jd in 1 2 3; do
10970 for kd in 1 2 3; do
10971 d=$id$jd$kd
cdc9a84a
HZ
10972 dlsp_mac=`lsp_to_mac $d`
10973 dlrp_mac=`lrp_to_mac $id$jd`
10974 dip=192.168.$id$jd.$kd
10975 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
1beb60af
HZ
10976 if test $d != $s; then unicast=$d; else unicast=; fi
10977
10978 # packets matches ACL1 but not ACL2 should be dropped
10979 if test $id != 3 && test $kd == 1; then
10980 if test $is == 1 || test $ks != 2; then
10981 unicast=
10982 fi
10983 fi
cdc9a84a
HZ
10984 # icmp request (type = 8)
10985 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
10986
10987 # if packets are not dropped, test the return traffic (icmp echo)
10988 # to make sure stateful works, too.
10989 if test x$unicast != x; then
10990 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
10991 # icmp echo (type = 0)
10992 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
10993 fi
1beb60af
HZ
10994 done
10995 done
10996 done
10997 done
10998 done
10999done
11000
11001# Allow some time for packet forwarding.
11002# XXX This can be improved.
11003sleep 1
11004
11005# Now check the packets actually received against the ones expected.
11006for i in 1 2 3; do
11007 for j in 1 2 3; do
11008 for k in 1 2 3; do
11009 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11010 [$i$j$k.expected])
11011 done
11012 done
11013done
11014
11015# Gracefully terminate daemons
11016OVN_CLEANUP([hv1], [hv2], [hv3])
11017AT_CLEANUP
55b25947 11018
2342c266
JS
11019AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
11020ovn_start
11021
11022ovn-nbctl ls-add ls1
11023
11024ovn-nbctl lsp-add ls1 lp1
11025ovn-nbctl lsp-add ls1 lp2
11026ovn-nbctl lsp-add ls1 lp3
11027
11028ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
11029ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
11030ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
11031
11032ovn-nbctl create Port_Group name=pg1
11033ovn-nbctl create Port_Group name=pg2
11034
11035ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
11036ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
11037ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
11038ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
11039
11040ovn-nbctl --wait=sb sync
11041
11042dnl Check if port group address sets were populated with ports' addresses
11043AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11044 [0], [[["10.0.0.1", "10.0.0.2"]]
11045])
11046AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
11047 [0], [[["10.0.0.2", "10.0.0.3"]]
11048])
11049AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11050 [0], [[["2001:db8::1", "2001:db8::2"]]
11051])
11052AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
11053 [0], [[["2001:db8::2", "2001:db8::3"]]
11054])
11055
11056ovn-nbctl --wait=sb lsp-set-addresses lp1 \
11057 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
11058
11059dnl Check if updated address got propagated to the port group address sets
11060AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11061 [0], [[["10.0.0.11", "10.0.0.2"]]
11062])
11063AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11064 [0], [[["2001:db8::11", "2001:db8::2"]]
11065])
11066
11067AT_CLEANUP
11068
984c7d5e
JS
11069AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
11070ovn_start
11071
11072ovn-nbctl ls-add ls1
11073ovn-nbctl ls-add ls2
11074ovn-nbctl ls-add ls3
11075
11076ovn-nbctl set Logical_Switch ls1 \
11077 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
11078ovn-nbctl set Logical_Switch ls2 \
11079 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
11080ovn-nbctl set Logical_Switch ls3 \
11081 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
11082
11083ovn-nbctl lsp-add ls1 lp1
11084ovn-nbctl lsp-add ls2 lp2
11085ovn-nbctl lsp-add ls3 lp3
11086
11087ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
11088ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
11089ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
11090
11091ovn-nbctl create Port_Group name=pg1
11092ovn-nbctl create Port_Group name=pg2
11093
11094ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
11095ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
11096ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
11097ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
11098
11099ovn-nbctl --wait=sb sync
11100
11101dnl Check if port group address sets were populated with ports' addresses
11102AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11103 [0], [[["10.1.0.2", "10.2.0.2"]]
11104])
11105AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
11106 [0], [[["10.2.0.2", "10.3.0.2"]]
11107])
11108AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11109 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
11110])
11111AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
11112 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
11113])
11114
11115ovn-nbctl set Logical_Switch ls1 \
11116 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
11117
11118dnl Check if updated address got propagated to the port group address sets
11119AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
451624fe 11120 [0], [[["10.11.0.2", "10.2.0.2"]]
984c7d5e
JS
11121])
11122AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
451624fe 11123 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
984c7d5e
JS
11124])
11125
11126AT_CLEANUP
11127
55b25947
NS
11128AT_SETUP([ovn -- ACL conjunction])
11129ovn_start
11130
11131ovn-nbctl ls-add ls1
11132
11133ovn-nbctl lsp-add ls1 ls1-lp1 \
11134-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
11135
11136ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
11137
11138ovn-nbctl lsp-add ls1 ls1-lp2 \
11139-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
11140
11141ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
11142
11143net_add n1
11144sim_add hv1
11145
11146as hv1
11147ovs-vsctl add-br br-phys
11148ovn_attach n1 br-phys 192.168.0.1
11149ovs-vsctl -- add-port br-int hv1-vif1 -- \
11150 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
11151 options:tx_pcap=hv1/vif1-tx.pcap \
11152 options:rxq_pcap=hv1/vif1-rx.pcap \
11153 ofport-request=1
11154
11155ovs-vsctl -- add-port br-int hv1-vif2 -- \
11156 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
11157 options:tx_pcap=hv1/vif2-tx.pcap \
11158 options:rxq_pcap=hv1/vif2-rx.pcap \
11159 ofport-request=2
11160
11161ovn-nbctl create Address_Set name=set1 \
11162addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
11163ovn-nbctl create Address_Set name=set2 \
11164addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
11165ovn-nbctl acl-add ls1 to-lport 1002 \
11166'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
11167ovn-nbctl acl-add ls1 to-lport 1001 \
11168'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
11169
11170# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11171#
11172# This shell function causes an ip packet to be received on INPORT.
11173# The packet's content has Ethernet destination DST and source SRC
11174# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
11175# The OUTPORTs (zero or more) list the VIFs on which the packet should
11176# be received. INPORT and the OUTPORTs are specified as logical switch
11177# port numbers, e.g. 11 for vif11.
11178test_ip() {
11179 # This packet has bad checksums but logical L3 routing doesn't check.
11180 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11181 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
11182${dst_ip}0035111100080000
11183 shift; shift; shift; shift; shift
11184 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
11185 for outport; do
11186 echo $packet >> $outport.expected
11187 done
11188}
11189
11190ip_to_hex() {
11191 printf "%02x%02x%02x%02x" "$@"
11192}
11193
11194reset_pcap_file() {
11195 local iface=$1
11196 local pcap_file=$2
11197 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11198options:rxq_pcap=dummy-rx.pcap
11199 rm -f ${pcap_file}*.pcap
11200 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11201options:rxq_pcap=${pcap_file}-rx.pcap
11202}
11203
11204
11205sip=`ip_to_hex 10 0 0 4`
11206dip=`ip_to_hex 10 0 0 6`
11207
11208test_ip 1 f00000000001 f00000000002 $sip $dip 2
11209
11210cat 2.expected > expout
11211$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
11212AT_CHECK([cat 2.packets], [0], [expout])
11213
11214# There should be total of 12 flows present with conjunction action and 2 flows
11215# with conj match. Eg.
11216# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
11217# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
11218# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
11219# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
11220# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
11221# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
11222# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
11223# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
11224# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
11225# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
11226# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
11227# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
11228# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
11229# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
11230
11231OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
11232grep conjunction | wc -l`])
11233OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
11234grep conj_id | wc -l`])
11235
11236as hv1 ovs-ofctl dump-flows br-int
11237
11238# Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
11239ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
11240ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
11241
11242reset_pcap_file hv1-vif2 hv1/vif2
11243
11244rm -f 2.packets
11245
11246sip=`ip_to_hex 10 0 0 4`
11247dip=`ip_to_hex 10 0 0 7`
11248
11249test_ip 1 f00000000001 f00000000002 $sip $dip
11250$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
11251AT_CHECK([cat 2.packets], [0], [])
11252
11253AT_CLEANUP
0e2751ed
LB
11254
11255AT_SETUP([ovn -- TTL exceeded])
11256AT_KEYWORDS([ttl-exceeded])
11257AT_SKIP_IF([test $HAVE_PYTHON = no])
11258ovn_start
11259
11260# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
11261#
11262# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
11263# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
11264# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
11265# generated by OVN logical router
11266#
11267# INPORT is a lport number, e.g. 11 for vif11.
11268# HV is a hypervisor number
11269# ETH_SRC and ETH_DST are each 12 hex digits.
11270# IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
11271# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
11272test_ip_packet() {
11273 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
11274 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
11275 shift 10
11276
11277 local ip_ttl=01
11278 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
11279
11280 local reply_icmp_ttl=fe
11281 local icmp_type_code_response=0b00
11282 local icmp_data=00000000
11283 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
11284 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
11285 echo $reply >> vif$inport.expected
11286
11287 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11288}
11289
e6a84e1e
LB
11290# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
11291#
11292# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
11293# packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
11294# IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
11295# packet sent by OVN logical router
11296test_ip6_packet() {
11297 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
11298 shift 8
11299
11300 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
11301 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
11302
11303 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
11304 echo $reply >> vif$inport.expected
11305
11306 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11307}
11308
0e2751ed
LB
11309ip_to_hex() {
11310 printf "%02x%02x%02x%02x" "$@"
11311}
11312
11313for i in 1 2; do
11314 net_add n$i
11315 ovn-nbctl ls-add sw$i
11316
11317 sim_add hv$i
11318 as hv$i
11319 ovs-vsctl add-br br-phys
11320 ovn_attach n$i br-phys 192.168.$i.1
11321
11322 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
e6a84e1e 11323 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
0e2751ed
LB
11324
11325 ovs-vsctl -- add-port br-int vif$i -- \
11326 set interface vif$i \
11327 external-ids:iface-id=sw$i-p${i}0 \
11328 options:tx_pcap=hv$i/vif$i-tx.pcap \
11329 options:rxq_pcap=hv$i/vif$i-rx.pcap \
11330 ofport-request=$i
11331done
11332
11333ovn-nbctl lr-add lr0
11334for i in 1 2; do
e6a84e1e 11335 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
0e2751ed
LB
11336 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
11337 -- set Logical_Switch_Port lrp$i-attachment type=router \
e6a84e1e 11338 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
0e2751ed
LB
11339done
11340
11341OVN_POPULATE_ARP
11342# allow some time for ovn-northd and ovn-controller to catch up.
11343ovn-nbctl --wait=hv sync
11344
11345test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 1 254) 0000 7dae f4ff
e6a84e1e 11346test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
0e2751ed
LB
11347OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
11348
11349OVN_CLEANUP([hv1], [hv2])
11350AT_CLEANUP
86558ac2
LB
11351
11352AT_SETUP([ovn -- router port unreachable])
11353AT_KEYWORDS([router-port-unreachable])
11354AT_SKIP_IF([test $HAVE_PYTHON = no])
11355ovn_start
11356
11357# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER L4_PROTCOL IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM EXP_ICMP_CODE
11358#
11359# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
11360# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
11361# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
11362# EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
11363#
11364# INPORT is a lport number, e.g. 11 for vif11.
11365# HV is a hypervisor number
11366# ETH_SRC and ETH_DST are each 12 hex digits.
11367# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
11368# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
11369test_ip_packet() {
11370 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
11371 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
11372 shift 11
11373
11374 local ip_ttl=ff
11375 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
11376
11377 local reply_icmp_ttl=fe
11378 local icmp_data=00000000
11379 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
11380 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
11381 echo $reply >> vif$inport.expected
11382
11383 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11384}
11385
159932c9
LB
11386# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
11387#
11388# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
11389# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
11390# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
11391#
11392# INPORT is an lport number, e.g. 11 for vif11.
11393# HV is an hypervisor number
11394# ETH_SRC and ETH_DST are each 12 hex digits.
11395# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
11396# TCP_SPORT and TCP_DPORT are 4 hex digits.
11397# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
11398test_tcp_syn_packet() {
11399 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
11400 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
11401 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
11402 shift 12
11403
11404 local ip_ttl=ff
11405 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
11406
11407 local tcp_rst_ttl=fe
11408 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ip_router}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
11409 echo $reply >> vif$inport.expected
11410
11411 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11412}
11413
98af55fc
LB
11414# test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
11415#
11416# Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
11417# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
11418# EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
11419test_tcp6_packet() {
11420 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
11421 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
11422 local exp_tcp_rst_chksum=${10}
11423 shift 10
11424
11425 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
11426 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
11427
11428 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
11429 echo $reply >> vif$inport.expected
11430
11431 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11432}
11433
4c25c3b8
LB
11434# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
11435#
11436# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
11437# packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
11438# EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
11439test_ip6_packet() {
11440 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_proto=$7 ipv6_len=$8 data=$9
11441 local exp_icmp_code=${10} exp_icmp_chksum=${11}
11442 shift 11
11443
11444 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
11445 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
11446
11447 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
11448 echo $reply >> vif$inport.expected
11449
11450 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11451}
11452
86558ac2
LB
11453ip_to_hex() {
11454 printf "%02x%02x%02x%02x" "$@"
11455}
11456
11457for i in 1 2; do
11458 net_add n$i
11459 ovn-nbctl ls-add sw$i
11460
11461 sim_add hv$i
11462 as hv$i
11463 ovs-vsctl add-br br-phys
11464 ovn_attach n$i br-phys 192.168.$i.1
11465
11466 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
4c25c3b8 11467 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
86558ac2
LB
11468
11469 ovs-vsctl -- add-port br-int vif$i -- \
11470 set interface vif$i \
11471 external-ids:iface-id=sw$i-p${i}0 \
11472 options:tx_pcap=hv$i/vif$i-tx.pcap \
11473 options:rxq_pcap=hv$i/vif$i-rx.pcap \
11474 ofport-request=$i
11475done
11476
11477ovn-nbctl lr-add lr0
11478for i in 1 2; do
4c25c3b8 11479 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
86558ac2
LB
11480 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
11481 -- set Logical_Switch_Port lrp$i-attachment type=router \
4c25c3b8 11482 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
86558ac2
LB
11483done
11484
11485OVN_POPULATE_ARP
11486# allow some time for ovn-northd and ovn-controller to catch up.
11487ovn-nbctl --wait=hv sync
11488
11489test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 11 0000 7dae fcfc 0303
0e858e05 11490test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 84 0000 7dae fcfd 0302
4c25c3b8 11491test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
86558ac2
LB
11492OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
11493
159932c9 11494test_tcp_syn_packet 2 2 000000000002 00000000ff02 $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 2 254) 0000 8b40 3039 0000 7bae 4486
9c937ec5 11495test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
98af55fc 11496test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
159932c9
LB
11497OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
11498
86558ac2
LB
11499OVN_CLEANUP([hv1], [hv2])
11500AT_CLEANUP
96ea0ecb
MM
11501
11502AT_SETUP([ovn -- ovn-controller exit])
11503AT_SKIP_IF([test $HAVE_PYTHON = no])
11504ovn_start
11505# Logical network:
11506# One Logical Router: ro, with two logical switches sw1 and sw2.
11507# sw1 is for subnet 10.0.0.0/8
11508# sw2 is for subnet 20.0.0.0/8
11509# sw1 has a single port bound on hv1
11510# sw2 has a single port bound on hv2
11511
11512ovn-nbctl lr-add ro
11513ovn-nbctl ls-add sw1
11514ovn-nbctl ls-add sw2
11515
11516sw1_ro_mac=00:00:10:00:00:01
11517sw1_ro_ip=10.0.0.1
11518sw2_ro_mac=00:00:20:00:00:01
11519sw2_ro_ip=20.0.0.1
11520sw1_p1_mac=00:00:10:00:00:02
11521sw1_p1_ip=10.0.0.2
11522sw2_p1_mac=00:00:20:00:00:02
11523sw2_p1_ip=20.0.0.2
11524
11525ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11526ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11527ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11528 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11529ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11530 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11531
11532ovn-nbctl lsp-add sw1 sw1-p1 \
11533-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11534
11535ovn-nbctl lsp-add sw2 sw2-p1 \
11536-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11537
11538net_add n1
11539
11540sim_add hv1
11541as hv1
11542ovs-vsctl add-br br-phys
11543ovn_attach n1 br-phys 192.168.0.1
11544ovs-vsctl -- add-port br-int hv1-vif1 -- \
11545 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11546 options:tx_pcap=hv1/vif1-tx.pcap \
11547 options:rxq_pcap=hv1/vif1-rx.pcap \
11548 ofport-request=1
11549
11550sim_add hv2
11551as hv2
11552ovs-vsctl add-br br-phys
11553ovn_attach n1 br-phys 192.168.0.2
11554ovs-vsctl -- add-port br-int hv2-vif1 -- \
11555 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11556 options:tx_pcap=hv2/vif1-tx.pcap \
11557 options:rxq_pcap=hv2/vif1-rx.pcap \
11558 ofport-request=1
11559
11560OVN_POPULATE_ARP
11561
11562sleep 1
11563
11564packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11565 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11566 udp && udp.src==53 && udp.dst==4369"
11567
11568# Start by Sending the packet and make sure it makes it there as expected
11569as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11570
11571# Expected packet has TTL decreased by 1
11572expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11573 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11574 udp && udp.src==53 && udp.dst==4369"
11575echo $expected | ovstest test-ovn expr-to-packets > expected
11576
11577OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11578
11579# Stop ovn-controller on hv2
11580as hv2 ovs-appctl -t ovn-controller exit
11581
11582# Now send the packet again. This time, it should not arrive.
11583as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11584
11585OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11586
11587# Start ovn-controller again just so OVN_CLEANUP doesn't complain
11588as hv2 start_daemon ovn-controller
11589
11590OVN_CLEANUP([hv1],[hv2])
11591AT_CLEANUP
11592
11593AT_SETUP([ovn -- ovn-controller restart])
11594AT_SKIP_IF([test $HAVE_PYTHON = no])
11595ovn_start
11596
11597# Logical network:
11598# One Logical Router: ro, with two logical switches sw1 and sw2.
11599# sw1 is for subnet 10.0.0.0/8
11600# sw2 is for subnet 20.0.0.0/8
11601# sw1 has a single port bound on hv1
11602# sw2 has a single port bound on hv2
11603
11604ovn-nbctl lr-add ro
11605ovn-nbctl ls-add sw1
11606ovn-nbctl ls-add sw2
11607
11608sw1_ro_mac=00:00:10:00:00:01
11609sw1_ro_ip=10.0.0.1
11610sw2_ro_mac=00:00:20:00:00:01
11611sw2_ro_ip=20.0.0.1
11612sw1_p1_mac=00:00:10:00:00:02
11613sw1_p1_ip=10.0.0.2
11614sw2_p1_mac=00:00:20:00:00:02
11615sw2_p1_ip=20.0.0.2
11616
11617ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11618ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11619ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11620 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11621ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11622 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11623
11624ovn-nbctl lsp-add sw1 sw1-p1 \
11625-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11626
11627ovn-nbctl lsp-add sw2 sw2-p1 \
11628-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11629
11630net_add n1
11631
11632sim_add hv1
11633as hv1
11634ovs-vsctl add-br br-phys
11635ovn_attach n1 br-phys 192.168.0.1
11636ovs-vsctl -- add-port br-int hv1-vif1 -- \
11637 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11638 options:tx_pcap=hv1/vif1-tx.pcap \
11639 options:rxq_pcap=hv1/vif1-rx.pcap \
11640 ofport-request=1
11641
11642sim_add hv2
11643as hv2
11644ovs-vsctl add-br br-phys
11645ovn_attach n1 br-phys 192.168.0.2
11646ovs-vsctl -- add-port br-int hv2-vif1 -- \
11647 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11648 options:tx_pcap=hv2/vif1-tx.pcap \
11649 options:rxq_pcap=hv2/vif1-rx.pcap \
11650 ofport-request=1
11651
11652OVN_POPULATE_ARP
11653
11654sleep 1
11655
11656packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11657 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11658 udp && udp.src==53 && udp.dst==4369"
11659
11660# Start by Sending the packet and make sure it makes it there as expected
11661as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11662
11663# Expected packet has TTL decreased by 1
11664expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11665 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11666 udp && udp.src==53 && udp.dst==4369"
11667echo $expected | ovstest test-ovn expr-to-packets > expected
11668
11669OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11670
11671# Stop ovn-controller on hv2 with --restart flag
11672as hv2 ovs-appctl -t ovn-controller exit --restart
11673
11674# Now send the packet again. This time, it should still arrive
11675as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11676
11677cat expected expected > expected2
11678
11679OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
11680
11681# Start ovn-controller again just so OVN_CLEANUP doesn't complain
11682as hv2 start_daemon ovn-controller
11683
11684OVN_CLEANUP([hv1],[hv2])
11685
11686AT_CLEANUP
863fb61f
MM
11687
11688AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
11689ovn_start
11690
11691# Set up a switch with some switch ports of varying address types
11692ovn-nbctl ls-add sw1
11693ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
11694
11695ovn-nbctl lsp-add sw1 sw1-p1
11696ovn-nbctl lsp-add sw1 sw1-p2
11697ovn-nbctl lsp-add sw1 sw1-p3
11698ovn-nbctl lsp-add sw1 sw1-p4
11699
11700ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1" "00:00:00:00:00:02 10.0.0.2 aef0::2"
11701ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
11702ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
11703ovn-nbctl lsp-set-addresses sw1-p4 "router"
11704ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
11705
11706ovn-nbctl list logical_switch_port
11707
11708# Now try to add duplicate addresses on a new port. These should all fail
11709ovn-nbctl lsp-add sw1 sw1-p5
11710AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
11711[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
11712])
11713AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
11714[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
11715])
11716AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
11717[ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
11718])
11719AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
11720[ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
11721])
11722AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
11723[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
11724])
11725AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
11726[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
11727])
11728
11729# Now try re-setting sw1-p1. This should succeed
11730AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
11731
11732# Now create a new switch and try setting IP addresses the same as the
11733# first switch. This should succeed.
11734ovn-nbctl ls-add sw2
11735ovn-nbctl lsp-add sw2 sw2-p1
11736
11737AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
11738AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
11739AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
11740AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
11741
11742AT_CLEANUP
d7abfe39
LB
11743
11744AT_SETUP([ovn -- IP packet buffering])
11745AT_KEYWORDS([ip-buffering])
11746AT_SKIP_IF([test $HAVE_PYTHON = no])
11747ovn_start
11748
11749# Logical network:
11750# One LR lr0 that has switches sw0 (192.168.1.0/24) and
11751# sw1 (172.16.1.0/24) connected to it.
11752#
11753# Physical network:
11754# Tw0 hypervisors hv[12].
11755# hv1 hosts vif sw0-p0.
11756# hv1 hosts vif sw1-p0.
11757
11758send_icmp_packet() {
11759 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
11760 shift 8
11761
11762 local ip_ttl=ff
11763 local ip_len=001c
11764 local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
11765 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
11766}
11767
11768send_icmp6_packet() {
11769 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
11770 shift 8
11771
11772 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
11773 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
11774
11775 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
11776}
11777
11778get_arp_req() {
11779 local eth_src=$1 spa=$2 tpa=$3
11780 local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
11781 echo $request
11782}
11783
11784send_arp_reply() {
11785 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
11786 local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
11787 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
11788}
11789
11790send_na() {
11791 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
11792 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
11793 local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
11794
11795 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
11796}
11797
11798get_nd() {
11799 local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
11800 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
11801 request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
11802
11803 echo $request
11804}
11805
11806net_add n1
11807
11808sim_add hv1
11809as hv1
11810ovs-vsctl add-br br-phys
11811ovn_attach n1 br-phys 192.168.0.1
11812ovs-vsctl -- add-port br-int hv1-vif1 -- \
11813 set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
11814 options:tx_pcap=hv1/vif1-tx.pcap \
11815 options:rxq_pcap=hv1/vif1-rx.pcap \
11816 ofport-request=1
11817
11818sim_add hv2
11819as hv2
11820ovs-vsctl add-br br-phys
11821ovn_attach n1 br-phys 192.168.0.2
11822ovs-vsctl -- add-port br-int hv2-vif1 -- \
11823 set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
11824 options:tx_pcap=hv2/vif1-tx.pcap \
11825 options:rxq_pcap=hv2/vif1-rx.pcap \
11826 ofport-request=1
11827
11828ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
11829ovn-nbctl ls-add sw0
11830ovn-nbctl ls-add sw1
11831
11832ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001::1/64
11833ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
11834 type=router options:router-port=sw0 \
11835 -- lsp-set-addresses rp-sw0 router
11836
11837ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002::1/64
11838ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
11839 type=router options:router-port=sw1 \
11840 -- lsp-set-addresses rp-sw1 router
11841
11842ovn-nbctl lsp-add sw0 sw0-p0 \
11843 -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
11844
11845ovn-nbctl lsp-add sw1 sw1-p0 \
11846 -- lsp-set-addresses sw1-p0 unknown
11847
11848OVN_POPULATE_ARP
11849ovn-nbctl --wait=hv sync
11850
11851ip_to_hex() {
11852 printf "%02x%02x%02x%02x" "$@"
11853}
11854
11855src_mac=f00000010203
11856src_ip=$(ip_to_hex 192 168 1 2)
11857src_ip6=20010000000000000000000000000002
11858
11859router_mac0=000001010203
11860router_mac1=000002010203
11861router_ip=$(ip_to_hex 172 16 1 1)
11862router_ip6=20020000000000000000000000000001
11863
11864dst_mac=001122334455
11865dst_ip=$(ip_to_hex 172 16 1 10)
11866dst_ip6=20020000000000000000000000000010
11867
11868data=0800bee4391a0001
11869
11870send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
11871send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
11872echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
11873echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
11874
11875OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11876
11877nd_ip=ff0200000000000000000001ff000010
11878ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
11879
11880send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
11881echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
11882echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
11883send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
11884
11885OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11886
11887OVN_CLEANUP([hv1],[hv2])
11888AT_CLEANUP
81e92852
DA
11889
11890AT_SETUP([ovn -- neighbor update on same HV])
11891AT_SKIP_IF([test $HAVE_PYTHON = no])
11892ovn_start
11893
11894# Logical network:
11895# A public switch (pub) with a localnet port connected to two LRs (lr0 and lr1)
11896# each with a distributed gateway port.
11897# Two VMs: lp0 on sw0 connected to lr0
11898# lp1 on sw1 connected to lr1
11899#
11900# This test adds a floating IP to each VM so when they are bound to the same
11901# hypervisor, it checks that the GARP sent by ovn-controller causes the
11902# MAC_Binding entries to be updated properly on each logical router.
11903# It will also capture packets on the physical interface to make sure that the
11904# GARPs have been sent out to the external network as well.
11905
11906# Create logical switches
11907ovn-nbctl ls-add sw0
11908ovn-nbctl ls-add sw1
11909ovn-nbctl ls-add pub
11910
11911# Created localnet port on public switch
11912ovn-nbctl lsp-add pub ln-pub
11913ovn-nbctl lsp-set-type ln-pub localnet
11914ovn-nbctl lsp-set-addresses ln-pub unknown
11915ovn-nbctl lsp-set-options ln-pub network_name=phys
11916
11917# Create logical routers and connect them to public switch
11918ovn-nbctl create Logical_Router name=lr0
11919ovn-nbctl create Logical_Router name=lr1
11920
11921ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
11922ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
11923 type=router options:router-port=lr0-pub options:nat-addresses="router" addresses="router"
11924ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
11925ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
11926 type=router options:router-port=lr1-pub options:nat-addresses="router" addresses="router"
11927
11928ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
11929ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
11930
11931# Connect sw0 and sw1 to lr0 and lr1
11932ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
11933ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
11934 options:router-port=lr0-sw0 addresses="router"
11935ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
11936ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
11937 options:router-port=lr1-sw1 addresses="router"
11938
11939
11940# Add SNAT rules
11941ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
11942ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
11943
11944net_add n1
11945sim_add hv1
11946as hv1
11947ovs-vsctl add-br br-phys
11948ovn_attach n1 br-phys 172.24.4.1
11949ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
11950
11951ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
11952ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
11953
11954ovn-nbctl lsp-add sw0 lp0
11955ovn-nbctl lsp-add sw1 lp1
11956ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
11957ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
11958
11959OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp0` = xup])
11960OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
11961
11962# Create two floating IPs, one for each VIF
11963ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
11964ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
11965
11966# Check that the MAC_Binding entries have been properly created
11967OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr0-pub" ip="172.24.4.200" | wc -l` -gt 0])
11968OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr1-pub" ip="172.24.4.100" | wc -l` -gt 0])
11969
11970# Check that the GARPs went also to the external physical network
11971# Wait until at least 4 packets have arrived and copy them to a separate file as
11972# more GARPs are expected in the capture in order to avoid race conditions.
11973OVS_WAIT_UNTIL([test `$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | wc -l` -gt 4])
11974$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | head -n4 > hv1/br-phys-tx4.pcap
11975
11976# GARP for lp0 172.24.4.100 on lr0-pub MAC (f0:00:00:00:00:01)
11977echo "fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464" > expout
11978# GARP for 172.24.4.220 on lr0-pub (f0:00:00:00:00:01)
11979echo "fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc" >> expout
11980# GARP for lp1 172.24.4.200 on lr1-pub MAC (f0:00:00:00:01:01)
11981echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8" >> expout
11982# GARP for 172.24.4.221 on lr1-pub (f0:00:00:00:01:01)
11983echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd" >> expout
11984AT_CHECK([sort hv1/br-phys-tx4.pcap], [0], [expout])
11985#OVN_CHECK_PACKETS([hv1/br-phys-tx4.pcap], [br-phys.expected])
11986
11987OVN_CLEANUP([hv1])
11988AT_CLEANUP