]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
OVN: add mac address only support to IPAM/MACAM
[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
10b9890f
LB
5757# request to assign mac only
5758#
5759ovn-nbctl ls-add sw8
5760ovn-nbctl --wait=sb set Logical-Switch sw8 other_config:mac_only=true
5761for n in $(seq 1 3); do
5762 ovn-nbctl --wait=sb lsp-add sw8 "p8$n" -- lsp-set-addresses "p8$n" dynamic
5763done
5764AT_CHECK([ovn-nbctl get Logical-Switch-Port p81 dynamic_addresses], [0],
5765 ["00:11:22:00:00:06"
5766])
5767AT_CHECK([ovn-nbctl get Logical-Switch-Port p82 dynamic_addresses], [0],
5768 ["00:11:22:00:00:07"
5769])
5770AT_CHECK([ovn-nbctl get Logical-Switch-Port p83 dynamic_addresses], [0],
5771 ["00:11:22:00:00:08"
5772])
5773
8639f9be
ND
5774as ovn-sb
5775OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5776
5777as ovn-nb
5778OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5779
5780as northd
5781OVS_APP_EXIT_AND_WAIT([ovn-northd])
5782
5783AT_CLEANUP
5784
5785AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5786AT_SKIP_IF([test $HAVE_PYTHON = no])
5787ovn_start
5788
5789ovn-nbctl lr-add R1
5790
5791# Test for a ping using dynamically allocated addresses.
5792ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5793ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5794
5795# Connect foo to R1
5796ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5797ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5798 options:router-port=foo \
5799 -- lsp-set-addresses rp-foo router
8639f9be
ND
5800
5801# Connect alice to R1
5802ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5803ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5804 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5805
5806# Create logical port foo1 in foo
fd3b31e9 5807ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5808-- lsp-set-addresses foo1 "dynamic"
c814545b 5809AT_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
5810
5811# Create logical port alice1 in alice
fd3b31e9 5812ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5813-- lsp-set-addresses alice1 "dynamic"
c814545b 5814AT_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
5815
5816# Create logical port foo2 in foo
fd3b31e9 5817ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5818-- lsp-set-addresses foo2 "dynamic"
c814545b 5819AT_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
5820
5821# Create a hypervisor and create OVS ports corresponding to logical ports.
5822net_add n1
5823
5824sim_add hv1
5825as hv1
5826ovs-vsctl add-br br-phys
5827ovn_attach n1 br-phys 192.168.0.1
5828ovs-vsctl -- add-port br-int hv1-vif1 -- \
5829 set interface hv1-vif1 external-ids:iface-id=foo1 \
5830 options:tx_pcap=hv1/vif1-tx.pcap \
5831 options:rxq_pcap=hv1/vif1-rx.pcap \
5832 ofport-request=1
5833
5834ovs-vsctl -- add-port br-int hv1-vif2 -- \
5835 set interface hv1-vif2 external-ids:iface-id=foo2 \
5836 options:tx_pcap=hv1/vif2-tx.pcap \
5837 options:rxq_pcap=hv1/vif2-rx.pcap \
5838 ofport-request=2
5839
5840ovs-vsctl -- add-port br-int hv1-vif3 -- \
5841 set interface hv1-vif3 external-ids:iface-id=alice1 \
5842 options:tx_pcap=hv1/vif3-tx.pcap \
5843 options:rxq_pcap=hv1/vif3-rx.pcap \
5844 ofport-request=3
5845
5846# Allow some time for ovn-northd and ovn-controller to catch up.
5847# XXX This should be more systematic.
5848sleep 1
5849
5850ip_to_hex() {
5851 printf "%02x%02x%02x%02x" "$@"
5852}
8639f9be
ND
5853
5854# Send ip packets between foo1 and foo2
c814545b
LB
5855src_mac="0a0000a80103"
5856dst_mac="0a0000a80104"
8639f9be
ND
5857src_ip=`ip_to_hex 192 168 1 2`
5858dst_ip=`ip_to_hex 192 168 1 3`
5859packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5860as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5861
5862# Send ip packets between foo1 and alice1
c814545b 5863src_mac="0a0000a80103"
8639f9be
ND
5864dst_mac="000000010203"
5865src_ip=`ip_to_hex 192 168 1 2`
5866dst_ip=`ip_to_hex 192 168 2 2`
5867packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5868as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5869
5870echo "---------NB dump-----"
5871ovn-nbctl show
5872echo "---------------------"
5873ovn-nbctl list logical_router
5874echo "---------------------"
5875ovn-nbctl list logical_router_port
5876echo "---------------------"
5877
5878echo "---------SB dump-----"
5879ovn-sbctl list datapath_binding
5880echo "---------------------"
5881ovn-sbctl list port_binding
5882echo "---------------------"
5883
5884echo "------ hv1 dump ----------"
5885as hv1 ovs-ofctl dump-flows br-int
5886
5887# Packet to Expect at foo2
c814545b
LB
5888src_mac="0a0000a80103"
5889dst_mac="0a0000a80104"
8639f9be
ND
5890src_ip=`ip_to_hex 192 168 1 2`
5891dst_ip=`ip_to_hex 192 168 1 3`
5892expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5893
e4543cfe
DDP
5894$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5895echo $expected > expout
8639f9be
ND
5896AT_CHECK([cat received1.packets], [0], [expout])
5897
5898# Packet to Expect at alice1
5899src_mac="000000010204"
c814545b 5900dst_mac="0a0000a80203"
8639f9be
ND
5901src_ip=`ip_to_hex 192 168 1 2`
5902dst_ip=`ip_to_hex 192 168 2 2`
5903expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5904
e4543cfe
DDP
5905$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5906echo $expected > expout
8639f9be
ND
5907AT_CHECK([cat received2.packets], [0], [expout])
5908
5909OVN_CLEANUP([hv1])
5910
5911AT_CLEANUP
f5792c3f
NS
5912
5913AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5914AT_KEYWORDS([vswitchd])
f5792c3f
NS
5915AT_SKIP_IF([test $HAVE_PYTHON = no])
5916ovn_start
5917
5918ovn-nbctl ls-add ls1
5919
5920ovn-nbctl lsp-add ls1 ls1-lp1 \
5921-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5922
5923ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5924
5925net_add n1
5926sim_add hv1
5927
5928as hv1
5929ovs-vsctl add-br br-phys
5930ovn_attach n1 br-phys 192.168.0.1
5931ovs-vsctl -- add-port br-int hv1-vif1 -- \
5932 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5933 options:tx_pcap=hv1/vif1-tx.pcap \
5934 options:rxq_pcap=hv1/vif1-rx.pcap \
5935 ofport-request=1
5936
74868f2c 5937OVN_POPULATE_ARP
f5792c3f
NS
5938sleep 2
5939
5940as hv1 ovs-vsctl show
5941
5942echo "---------------------"
5943ovn-sbctl dump-flows
5944echo "---------------------"
5945
5946echo "------ hv1 dump ----------"
5947as hv1 ovs-ofctl dump-flows br-int
5948total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5949
5950echo "Total flows before vswitchd restart = " $total_flows
5951
5952# Code taken from ovs-save utility
5953save_flows () {
5954 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5955 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5956 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5957 echo "EOF" >> restore_flows.sh
5958}
5959
5960restart_vswitchd () {
5961 restore_flows=$1
5962
5963 if test $restore_flows = true; then
5964 save_flows
5965 fi
5966
5967 as hv1
5968 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5969
5970 if test $restore_flows = true; then
5971 as hv1
5972 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5973 fi
5974
5975 as hv1
5976 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5977 ovs-ofctl dump-flows br-int
5978
5979 if test $restore_flows = true; then
5980 sh ./restore_flows.sh
5981 echo "Flows after restore"
5982 as hv1
5983 ovs-ofctl dump-flows br-int
5984 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5985 flow-restore-wait="true"
5986 fi
5987}
5988
5989# Save the flows, restart vswitchd and restore the flows
5990restart_vswitchd true
5991OVS_WAIT_UNTIL([
5992 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5993 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5994 test "${total_flows}" = "${total_flows_after_restart}"
5995])
5996
5997# Restart vswitchd without restoring
5998restart_vswitchd false
5999OVS_WAIT_UNTIL([
6000 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6001 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6002 test "${total_flows}" = "${total_flows_after_restart}"
6003])
6004
6005OVN_CLEANUP([hv1])
6006AT_CLEANUP
47021598
CSV
6007
6008AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
6009AT_SKIP_IF([test $HAVE_PYTHON = no])
6010ovn_start
6011
6012# Topology: Two LSs - ls1 and ls2 are connected via router r0
6013
6014# Create logical switches
6015ovn-nbctl ls-add ls1
6016ovn-nbctl ls-add ls2
6017
6018# Create router
6019ovn-nbctl create Logical_Router name=lr0
6020
6021# Add router ls1p1 port to gateway router
6022ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
6023ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
6024 type=router options:router-port=lrp-ls1lp1 \
6025 addresses='"f0:00:00:00:00:01 192.168.0.1"'
6026
6027# Add router ls2p2 port to gateway router
6028ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
6029ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
6030 type=router options:router-port=lrp-ls2lp1 \
6031 addresses='"f0:00:00:00:00:02 192.168.1.1"'
6032
6033# Set default gateway (nexthop) to 192.168.1.254
6034ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
6035
6036# Create logical port ls1lp2 in ls1
6037ovn-nbctl lsp-add ls1 ls1lp2 \
6038-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
6039
6040# Create logical port ls2lp2 in ls2
6041ovn-nbctl lsp-add ls2 ls2lp2 \
6042-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
6043
6044net_add n1
6045sim_add hv1
6046as hv1
6047ovs-vsctl add-br br-phys
6048ovn_attach n1 br-phys 192.168.0.1
6049ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
6050 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
6051 options:tx_pcap=hv1/ls1lp2-tx.pcap \
6052 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
6053 ofport-request=1
6054ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
6055 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
6056 options:tx_pcap=hv1/ls2lp2-tx.pcap \
6057 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
6058 ofport-request=2
6059
6060# Allow some time for ovn-northd and ovn-controller to catch up.
6061# XXX This should be more systematic.
6062sleep 1
6063
6064echo "---------NB dump-----"
6065ovn-nbctl show
6066echo "---------------------"
6067ovn-nbctl list logical_router
6068echo "---------------------"
6069ovn-nbctl list logical_router_port
6070echo "---------------------"
6071
6072echo "---------SB dump-----"
6073ovn-sbctl list datapath_binding
6074echo "---------------------"
6075ovn-sbctl list port_binding
6076echo "---------------------"
6077ovn-sbctl dump-flows
6078echo "---------------------"
6079ovn-sbctl list chassis
6080ovn-sbctl list encap
6081echo "---------------------"
6082
6083echo "------Flows dump-----"
6084as hv1
6085ovs-ofctl dump-flows
6086echo "---------------------"
6087
6088ip_to_hex() {
6089 printf "%02x%02x%02x%02x" "$@"
6090}
6091
6092src_mac="f00000000003"
6093dst_mac="f00000000001"
6094src_ip=`ip_to_hex 192 168 0 2`
6095dst_ip=`ip_to_hex 8 8 8 8`
6096packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6097
6098# Send IP packet destined to 8.8.8.8 from lsp1lp2
6099as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
6100
6101trim_zeros() {
6102 sed 's/\(00\)\{1,\}$//'
6103}
6104
6105# ARP packet should be received with Target IP Address set to 192.168.1.254 and
6106# not 8.8.8.8
6107
6108$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
6109expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
6110echo $expected > expout
6111AT_CHECK([cat packets], [0], [expout])
6112cat packets
6113
6114OVN_CLEANUP([hv1])
6115
6116AT_CLEANUP
8439c2eb
CSV
6117
6118AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
6119AT_SKIP_IF([test $HAVE_PYTHON = no])
6120ovn_start
6121# Create logical switch
6122ovn-nbctl ls-add ls0
6123# Create gateway router
6124ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6125# Add router port to gateway router
6126ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6127ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 6128 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
6129# Add nat-address option
6130ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
6131
6132net_add n1
6133sim_add hv1
6134as hv1
6135ovs-vsctl \
6136 -- add-br br-phys \
6137 -- add-br br-eth0
6138
6139ovn_attach n1 br-phys 192.168.0.1
6140
6141AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6142AT_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])
6143
6144# Create a localnet port.
6145AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6146AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6147AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6148AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6149
6150
6151# Wait for packet to be received.
6152OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6153trim_zeros() {
6154 sed 's/\(00\)\{1,\}$//'
6155}
6156$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6157expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6158echo $expected > expout
6159AT_CHECK([sort packets], [0], [expout])
6160cat packets
6161
6162OVN_CLEANUP([hv1])
6163
6164AT_CLEANUP
6e31816f 6165
e914fb54
MS
6166AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6167AT_SKIP_IF([test $HAVE_PYTHON = no])
6168ovn_start
6169# Create logical switch
6170ovn-nbctl ls-add ls0
6171# Create gateway router
6172ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6173# Add router port to gateway router
6174ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6175ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 6176 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
6177# Add nat-address option
6178ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6179# Add NAT rules
6180AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6181AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6182# Add load balancers
6183AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6184AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6185AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6186AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6187
6188net_add n1
6189sim_add hv1
6190as hv1
6191ovs-vsctl \
6192 -- add-br br-phys \
6193 -- add-br br-eth0
6194
6195ovn_attach n1 br-phys 192.168.0.1
6196
6197AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6198AT_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])
6199
6200# Create a localnet port.
6201AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6202AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6203AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6204AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6205
6206
6207# Wait for packet to be received.
6208OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6209trim_zeros() {
6210 sed 's/\(00\)\{1,\}$//'
6211}
6212$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6213expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6214echo $expected > expout
6215expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6216echo $expected >> expout
6217expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6218echo $expected >> expout
6219AT_CHECK([sort packets], [0], [expout])
6220cat packets
6221
6222OVN_CLEANUP([hv1])
6223
6224AT_CLEANUP
6225
6e31816f 6226AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
6227ovn_start
6228net_add n1
6229sim_add hv1
6230as hv1
6231ovs-vsctl -- add-br br-phys
6232ovn_attach n1 br-phys 192.168.0.1
6233# Create logical switch ls0
6234ovn-nbctl ls-add ls0
6235# Create ports lp0, lp1 in ls0
6236ovn-nbctl lsp-add ls0 lp0
6237ovn-nbctl lsp-add ls0 lp1
6238ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6239ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6240dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6241ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6242ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6243ovn-sbctl find MAC_Binding
093aa761 6244# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
6245ovn-nbctl lsp-del lp0
6246ovn-sbctl find MAC_Binding
093aa761
BP
6247OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6248# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
6249ovn-nbctl ls-del ls0
6250ovn-sbctl find MAC_Binding
093aa761 6251OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
6252
6253OVN_CLEANUP([hv1])
6254
6255AT_CLEANUP
926c34fd
RM
6256
6257AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
6258AT_SKIP_IF([test $HAVE_PYTHON = no])
6259ovn_start
6260
6261# Logical network:
6262# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6263# connected to a router R1.
6264# foo has foo1 to act as a client.
6265# bar has bar1, bar2, bar3 to act as servers.
6266
6267net_add n1
6268
6269sim_add hv1
6270as hv1
6271ovs-vsctl add-br br-phys
6272ovn_attach n1 br-phys 192.168.0.1
6273for i in foo1 bar1 bar2 bar3; do
6274 ovs-vsctl -- add-port br-int $i -- \
6275 set interface $i external-ids:iface-id=$i \
6276 options:tx_pcap=hv1/$i-tx.pcap \
6277 options:rxq_pcap=hv1/$i-rx.pcap
6278done
6279
6280ovn-nbctl create Logical_Router name=R1
6281ovn-nbctl ls-add foo
6282ovn-nbctl ls-add bar
6283
6284# Connect foo to R1
6285ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6286ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6287 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6288
6289# Connect bar to R1
6290ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6291ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6292 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6293
6294# Create logical port foo1 in foo
6295ovn-nbctl lsp-add foo foo1 \
6296-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6297
6298# Create logical port bar1, bar2 and bar3 in bar
6299for i in `seq 1 3`; do
6300 ip=`expr $i + 1`
6301 ovn-nbctl lsp-add bar bar$i \
6302 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6303done
6304
6305OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6306
6307OVN_CLEANUP([hv1])
6308
6309AT_CLEANUP
b511690b
GS
6310
6311AT_SETUP([ovn -- tag allocation])
b511690b
GS
6312ovn_start
6313
6314AT_CHECK([ovn-nbctl ls-add ls0])
6315AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6316AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6317AT_CHECK([ovn-nbctl ls-add ls1])
6318
6319dnl When a tag is provided, no allocation is done
6320AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6321AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6322])
6323dnl The same 'tag' gets created in southbound database.
6324AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6325logical_port="c0"], [0], [3
6326])
6327
6328dnl Allocate tags and see it getting created in both NB and SB
6329AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6330AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6331])
6332AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6333logical_port="c1"], [0], [1
6334])
6335
6336AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6337AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6338])
6339AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6340logical_port="c2"], [0], [2
6341])
6342AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6343AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6344])
6345AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6346logical_port="c3"], [0], [4
6347])
6348
6349dnl A different parent.
6350AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6351AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6352])
6353AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6354logical_port="c4"], [0], [1
6355])
6356
6357AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6358AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6359])
6360AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6361logical_port="c5"], [0], [2
6362])
6363
6364dnl Delete a logical port and create a new one.
6365AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6366AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6367AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6368])
6369AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6370logical_port="c6"], [0], [1
6371])
6372
6373dnl Restart northd to see that the same allocation remains.
6374as northd
6375OVS_APP_EXIT_AND_WAIT([ovn-northd])
6376start_daemon ovn-northd \
6377 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6378 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6379
6380dnl Create a switch to make sure that ovn-northd has run through the main loop.
6381AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6382AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6383])
6384AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6385])
6386AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6387])
6388AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6389])
6390AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6391])
6392AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6393])
6394
6395dnl Create a switch port with a tag that has already been allocated.
6396dnl It should go through fine with a duplicate tag.
6397AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6398AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6399])
6400AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6401logical_port="c7"], [0], [2
6402])
6403AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6404])
6405
6406AT_CHECK([ovn-nbctl ls-add ls2])
6407dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
6408dnl gets copied to 'tag'
6409AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
6410AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
6411])
6412dnl The same 'tag' gets created in southbound database.
6413AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6414logical_port="local0"], [0], [25
6415])
6416dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
6417AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
6418AT_CHECK([ovn-nbctl lsp-get-tag local1])
6419dnl change the tag_request.
6420AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
6421AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
6422])
6423
6424AT_CLEANUP
57afd0c0
RR
6425
6426AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
6427ovn_start
6428ovn-nbctl ls-add lsw0
6429net_add n1
6430for i in 1 2; do
6431 sim_add hv$i
6432 as hv$i
6433 ovs-vsctl add-br br-phys
6434 ovn_attach n1 br-phys 192.168.0.$i
6435 ovs-vsctl add-br br-eth0
6436 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6437done
6438
6439# Create a localnet port.
6440AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
6441AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6442AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6443AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6444
6445
6446# Create 3 vifs.
6447AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6448AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6449AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6450AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
863fb61f 6451AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
57afd0c0
RR
6452AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6453AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6454AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6455AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6456
6457# Bind the localvif1 to hv1.
6458as hv1
6459AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6460
6461# On hv1, check that there are no flows outputting bcast to tunnel
6462OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6463
1ea9b847 6464# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 6465as hv2
1ea9b847 6466OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
6467
6468# Now bind vif2 on hv2.
6469AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6470
6471# At this point, the broadcast flow on vif2 should be deleted.
6472# because, there is now a localnet vif bound (table=32 programming logic)
6473OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6474
6475# Verify that the local net patch port exists on hv2.
6476OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6477
6478# Now bind vif3 on hv2.
6479AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6480
6481# Verify that the local net patch port still exists on hv2
6482OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6483
6484# Delete localvif2
6485AT_CHECK([ovn-nbctl lsp-del localvif2])
6486
6487# Verify that the local net patch port still exists on hv2,
6488# because, localvif3 is still bound.
6489OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6490
57afd0c0 6491OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
6492
6493AT_CLEANUP
6494
d383eed5
JP
6495
6496AT_SETUP([ovn -- ACL logging])
6497AT_KEYWORDS([ovn])
6498ovn_start
6499
6500net_add n1
6501
6502sim_add hv
6503as hv
6504ovs-vsctl add-br br-phys
6505ovn_attach n1 br-phys 192.168.0.1
6506for i in lp1 lp2; do
6507 ovs-vsctl -- add-port br-int $i -- \
6508 set interface $i external-ids:iface-id=$i \
6509 options:tx_pcap=hv/$i-tx.pcap \
6510 options:rxq_pcap=hv/$i-rx.pcap
6511done
6512
6513lp1_mac="f0:00:00:00:00:01"
6514lp1_ip="192.168.1.2"
6515
6516lp2_mac="f0:00:00:00:00:02"
6517lp2_ip="192.168.1.3"
6518
6519ovn-nbctl ls-add lsw0
6520ovn-nbctl --wait=sb lsp-add lsw0 lp1
6521ovn-nbctl --wait=sb lsp-add lsw0 lp2
6522ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6523ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6524ovn-nbctl --wait=sb sync
6525
6526ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6527ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6528
6529ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6530ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6531
6532ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6533ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6534
6535ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6536ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6537
6538ovn-sbctl dump-flows
6539
6540
6541# Send packet that should be dropped without logging.
6542packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6543 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6544 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6545as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6546
6547# Send packet that should be dropped with logging.
6548packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6549 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6550 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6551as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6552
6553# Send packet that should be allowed without logging.
6554packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6555 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6556 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6557as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6558
6559# Send packet that should be allowed with logging.
6560packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6561 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6562 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6563as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6564
6565# Send packet that should allow related flows without logging.
6566packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6567 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6568 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6569as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6570
6571# Send packet that should allow related flows with logging.
6572packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6573 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6574 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6575as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6576
df48cfc7 6577# Send packet that should be rejected without logging.
d383eed5
JP
6578packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6579 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6580 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6581as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6582
df48cfc7 6583# Send packet that should be rejected with logging.
d383eed5
JP
6584packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6585 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6586 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6587as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6588
c1f272f9
NS
6589OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6590
d383eed5
JP
6591AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6592name="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
6593name="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
6594name="<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
6595name="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
6596])
6597
6598OVN_CLEANUP([hv])
6599AT_CLEANUP
6600
6601
23749245
JP
6602AT_SETUP([ovn -- ACL rate-limited logging])
6603AT_KEYWORDS([ovn])
6604ovn_start
6605
6606net_add n1
6607
6608sim_add hv
6609as hv
6610ovs-vsctl add-br br-phys
6611ovn_attach n1 br-phys 192.168.0.1
6612for i in lp1 lp2; do
6613 ovs-vsctl -- add-port br-int $i -- \
6614 set interface $i external-ids:iface-id=$i \
6615 options:tx_pcap=hv/$i-tx.pcap \
6616 options:rxq_pcap=hv/$i-rx.pcap
6617done
6618
6619lp1_mac="f0:00:00:00:00:01"
6620lp1_ip="192.168.1.2"
6621
6622lp2_mac="f0:00:00:00:00:02"
6623lp2_ip="192.168.1.3"
6624
6625ovn-nbctl ls-add lsw0
6626ovn-nbctl --wait=sb lsp-add lsw0 lp1
6627ovn-nbctl --wait=sb lsp-add lsw0 lp2
6628ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6629ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6630ovn-nbctl --wait=sb sync
6631
6632
6633# Add an ACL that rate-limits logs at 10 per second.
6634ovn-nbctl meter-add http-rl1 drop 10 pktps
6635ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6636
6637# Add an ACL that rate-limits logs at 5 per second.
6638ovn-nbctl meter-add http-rl2 drop 5 pktps
6639ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
6640
6641# Add an ACL that doesn't rate-limit logs.
6642ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
6643
6644
6645# For each ACL, send 100 packets.
6646for i in `seq 1 100`; do
6647 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)'
6648
6649 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)'
6650
6651 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)'
6652done
6653
2600ef02
JP
6654# The rate at which packets are sent is highly system-dependent, so we
6655# can't count on precise drop counts. To work around that, we just
6656# check that exactly 100 "http-acl3" actions were logged and that there
6657# were more "http-acl1" actions than "http-acl2" ones.
6658OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
6659
6660# On particularly slow or overloaded systems, the transmission rate may
6661# be lower than the configured meter rate. To prevent false test
6662# failures, we check the duration count of the meter, and if it's
6663# greater than nine seconds, just skip the test.
6664d_secs=$(as hv ovs-ofctl -O OpenFlow13 meter-stats br-int | grep "meter:1" | sed 's/.* duration:\([[0-9]]\{1,\}\)\.[[0-9]]\+s .*/\1/')
6665
6666echo "Meter duration: $d_secs"
6667AT_SKIP_IF([test $d_secs -gt 9])
6668
23749245
JP
6669# Print some information that may help debugging.
6670as hv ovs-appctl -t ovn-controller meter-table-list
6671as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
6672
23749245
JP
6673n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
6674n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
6675n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
6676
6677AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
6678AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
6679
23749245
JP
6680OVN_CLEANUP([hv])
6681AT_CLEANUP
6682
6683
66d89287 6684AT_SETUP([ovn -- DSCP marking and meter check])
1a03fc7d
BS
6685AT_KEYWORDS([ovn])
6686ovn_start
6687
6688ovn-nbctl ls-add lsw0
6689ovn-nbctl --wait=sb lsp-add lsw0 lp1
6690ovn-nbctl --wait=sb lsp-add lsw0 lp2
e50ed58a 6691ovn-nbctl --wait=sb lsp-add lsw0 lp3
1a03fc7d
BS
6692ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6693ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
e50ed58a 6694ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
1a03fc7d
BS
6695ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6696ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6697ovn-nbctl --wait=sb sync
6698net_add n1
6699sim_add hv
6700as hv
6701ovs-vsctl add-br br-phys
6702ovn_attach n1 br-phys 192.168.0.1
6703ovs-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
6704ovs-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
6705
6706AT_CAPTURE_FILE([trace])
6707ovn_trace () {
6708 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6709}
6710
6711# Extracts nw_tos from the final flow from ofproto/trace output and prints
6712# it on stdout. Prints "none" if no nw_tos was included.
6713get_final_nw_tos() {
6714 if flow=$(grep '^Final flow:' stdout); then :; else
6715 # The output didn't have a final flow.
6716 return 99
6717 fi
6718
6719 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6720 case $tos in
6721 '') echo none ;;
5a0e4aec 6722 *) echo $tos ;;
1a03fc7d
BS
6723 esac
6724}
6725
6726# check_tos TOS
6727#
6728# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6729check_tos() {
6730 # First check with ovn-trace for logical flows.
6731 echo "checking for tos $1"
6732 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6733 echo 'output("lp2");') > expout
6734 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])
6735
6736 # Then re-check with ofproto/trace for a physical packet.
6737 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])
6738 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6739])
6740}
6741
6742# check at L2
6743AT_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");
6744])
6745AT_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])
6746AT_CHECK([get_final_nw_tos], [0], [none
6747])
6748
6749# check at L3 without dscp marking
6750check_tos 0
6751
6752# Mark DSCP with a valid value
e50ed58a 6753qos_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
6754AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6755])
1a03fc7d
BS
6756check_tos 48
6757
66d89287
GL
6758# check at hv without qos meter
6759AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6760])
6761
6762# Update the meter rate
6763ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6764
6765# check at hv with a qos meter table
6766AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6767])
6768AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6769])
6770
1a03fc7d
BS
6771# Update the DSCP marking
6772ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6773check_tos 63
6774
66d89287
GL
6775# Update the meter rate
6776ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6777
6778# check at hv with a qos meter table
6779AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6780])
6781AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6782])
6783
1a03fc7d
BS
6784ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6785check_tos 63
6786
6787# Disable DSCP marking
5ee33cbd
GL
6788ovn-nbctl --wait=hv qos-del lsw0
6789AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6790])
1a03fc7d
BS
6791check_tos 0
6792
66d89287
GL
6793# check at hv without qos meter
6794AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6795])
6796
e50ed58a
GL
6797# check meter with chassis not resident
6798ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6799AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6800])
6801
6802# check no meter table
6803AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6804])
6805AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6806])
6807
1a03fc7d 6808OVN_CLEANUP([hv])
57afd0c0 6809AT_CLEANUP
7fff4eb7
LR
6810
6811AT_SETUP([ovn -- read-only sb db:ptcp access])
6812AT_SKIP_IF([test $HAVE_PYTHON = no])
6813
6814: > .$1.db.~lock~
6815ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6816
6817# Add read-only remote to sb ovsdb-server
6818AT_CHECK(
6819 [ovsdb-tool transact ovn-sb.db \
6820 ['["OVN_Southbound",
6821 {"op": "insert",
6822 "table": "SB_Global",
6823 "row": {
6824 "connections": ["set", [["named-uuid", "xyz"]]]}},
6825 {"op": "insert",
6826 "table": "Connection",
6827 "uuid-name": "xyz",
6828 "row": {"target": "ptcp:0:127.0.0.1",
6829 "read_only": true}}]']], [0], [ignore], [ignore])
6830
6831start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6832
6833PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6834
6835# read-only accesses should succeed
6836AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6837AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6838
6839# write access should fail
6840AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6841[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6842])
6843
6844OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6845AT_CLEANUP
6846
6847AT_SETUP([ovn -- read-only sb db:pssl access])
6848AT_SKIP_IF([test $HAVE_PYTHON = no])
6849AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6850PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6851AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6852\\]"])
6853
6854: > .$1.db.~lock~
6855ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6856
6857# Add read-only remote to sb ovsdb-server
6858AT_CHECK(
6859 [ovsdb-tool transact ovn-sb.db \
6860 ['["OVN_Southbound",
6861 {"op": "insert",
6862 "table": "SB_Global",
6863 "row": {
6864 "connections": ["set", [["named-uuid", "xyz"]]]}},
6865 {"op": "insert",
6866 "table": "Connection",
6867 "uuid-name": "xyz",
6868 "row": {"target": "pssl:0:127.0.0.1",
6869 "read_only": true}}]']], [0], [ignore], [ignore])
6870
6871start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6872 --remote=db:OVN_Southbound,SB_Global,connections \
6873 --private-key="$PKIDIR/testpki-privkey2.pem" \
6874 --certificate="$PKIDIR/testpki-cert2.pem" \
6875 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6876 ovn-sb.db
6877
6878PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6879
6880# read-only accesses should succeed
6881AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6882 --private-key=$PKIDIR/testpki-privkey.pem \
6883 --certificate=$PKIDIR/testpki-cert.pem \
6884 --ca-cert=$PKIDIR/testpki-cacert.pem \
6885 list SB_Global], [0], [stdout], [ignore])
6886AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6887 --private-key=$PKIDIR/testpki-privkey.pem \
6888 --certificate=$PKIDIR/testpki-cert.pem \
6889 --ca-cert=$PKIDIR/testpki-cacert.pem \
6890 list Connection], [0], [stdout], [ignore])
6891
6892# write access should fail
6893AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6894 --private-key=$PKIDIR/testpki-privkey.pem \
6895 --certificate=$PKIDIR/testpki-cert.pem \
6896 --ca-cert=$PKIDIR/testpki-cacert.pem \
6897 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6898[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6899])
6900
6901OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6902AT_CLEANUP
6903
821302cf
LR
6904AT_SETUP([ovn -- nb connection/ssl commands])
6905AT_SKIP_IF([test $HAVE_PYTHON = no])
6906AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6907PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6908AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6909\\]"])
6910
6911: > .$1.db.~lock~
6912ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6913
6914# Start nb db server using db connection/ssl entries (unpopulated initially)
6915start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6916 --remote=db:OVN_Northbound,NB_Global,connections \
6917 --private-key=db:OVN_Northbound,SSL,private_key \
6918 --certificate=db:OVN_Northbound,SSL,certificate \
6919 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6920 ovn-nb.db
6921
6922# Populate SSL configuration entries in nb db
6923AT_CHECK(
6924 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6925 $PKIDIR/testpki-cert.pem \
6926 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6927
6928# Populate a passive SSL connection in nb db
6929AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6930
6931PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6932
6933# Verify SSL connetivity to nb db server
6934AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6935 --private-key=$PKIDIR/testpki-privkey.pem \
6936 --certificate=$PKIDIR/testpki-cert.pem \
6937 --ca-cert=$PKIDIR/testpki-cacert.pem \
6938 list NB_Global],
6939 [0], [stdout], [ignore])
6940AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6941 --private-key=$PKIDIR/testpki-privkey.pem \
6942 --certificate=$PKIDIR/testpki-cert.pem \
6943 --ca-cert=$PKIDIR/testpki-cacert.pem \
6944 list Connection],
6945 [0], [stdout], [ignore])
6946AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6947 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6948 --certificate=$PKIDIR/testpki-cert.pem \
6949 --ca-cert=$PKIDIR/testpki-cacert.pem \
6950 get-connection],
6951 [0], [stdout], [ignore])
6952
6953OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6954AT_CLEANUP
6955
6956AT_SETUP([ovn -- sb connection/ssl commands])
6957AT_SKIP_IF([test $HAVE_PYTHON = no])
6958AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6959PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6960AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6961\\]"])
6962
6963: > .$1.db.~lock~
6964ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6965
6966# Start sb db server using db connection/ssl entries (unpopulated initially)
6967start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6968 --remote=db:OVN_Southbound,SB_Global,connections \
6969 --private-key=db:OVN_Southbound,SSL,private_key \
6970 --certificate=db:OVN_Southbound,SSL,certificate \
6971 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6972 ovn-sb.db
6973
6974# Populate SSL configuration entries in sb db
6975AT_CHECK(
6976 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6977 $PKIDIR/testpki-cert.pem \
6978 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6979
6980# Populate a passive SSL connection in sb db
6981AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6982
6983PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6984
6985# Verify SSL connetivity to sb db server
6986AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6987 --private-key=$PKIDIR/testpki-privkey.pem \
6988 --certificate=$PKIDIR/testpki-cert.pem \
6989 --ca-cert=$PKIDIR/testpki-cacert.pem \
6990 list SB_Global],
6991 [0], [stdout], [ignore])
6992AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6993 --private-key=$PKIDIR/testpki-privkey.pem \
6994 --certificate=$PKIDIR/testpki-cert.pem \
6995 --ca-cert=$PKIDIR/testpki-cacert.pem \
6996 list Connection],
6997 [0], [stdout], [ignore])
6998AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6999 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
7000 --certificate=$PKIDIR/testpki-cert.pem \
7001 --ca-cert=$PKIDIR/testpki-cacert.pem \
7002 get-connection],
7003 [0], [stdout], [ignore])
7004
7005OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7006AT_CLEANUP
7007
75fd74f8
GS
7008AT_SETUP([ovn -- nested containers])
7009ovn_start
7010
7011# Physical network:
7012# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
7013
7014# Logical network:
7015# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
7016# and "bar" (192.168.2.0/24). They are all connected to router R1.
7017
7018ovn-nbctl lr-add R1
7019ovn-nbctl ls-add mgmt
7020ovn-nbctl ls-add foo
7021ovn-nbctl ls-add bar
7022
7023# Connect mgmt to R1
7024ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
7025ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
7026 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
7027
7028# Connect foo to R1
7029ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
7030ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7031 options:router-port=foo addresses=\"00:00:00:01:02:03\"
7032
7033# Connect bar to R1
7034ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
7035ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7036 options:router-port=bar addresses=\"00:00:00:01:02:04\"
7037
7038# "mgmt" has VM1 and VM2 connected
7039ovn-nbctl lsp-add mgmt vm1 \
7040-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
7041
7042ovn-nbctl lsp-add mgmt vm2 \
7043-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
7044
7045# "foo1" and "foo2" are containers belonging to switch "foo"
7046# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
7047ovn-nbctl lsp-add foo foo1 vm1 1 \
7048-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
7049
7050ovn-nbctl lsp-add foo foo2 vm2 2 \
7051-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7052
7053# "bar1" and "bar2" are containers belonging to switch "bar"
7054# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
7055ovn-nbctl lsp-add bar bar1 vm1 2 \
7056-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
7057
7058ovn-nbctl lsp-add bar bar2 vm2 1 \
7059-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
7060
7061# bar3 is a standalone VM belonging to switch "bar"
7062ovn-nbctl lsp-add bar bar3 \
7063-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
7064
7065# Create two hypervisor and create OVS ports corresponding to logical ports.
7066net_add n1
7067
7068sim_add hv1
7069as hv1
7070ovs-vsctl add-br br-phys
7071ovn_attach n1 br-phys 192.168.0.1
7072ovs-vsctl -- add-port br-int vm1 -- \
7073 set interface vm1 external-ids:iface-id=vm1 \
7074 options:tx_pcap=hv1/vm1-tx.pcap \
7075 options:rxq_pcap=hv1/vm1-rx.pcap \
7076 ofport-request=1
7077
7078ovs-vsctl -- add-port br-int bar3 -- \
7079 set interface bar3 external-ids:iface-id=bar3 \
7080 options:tx_pcap=hv1/bar3-tx.pcap \
7081 options:rxq_pcap=hv1/bar3-rx.pcap \
7082 ofport-request=2
7083
7084sim_add hv2
7085as hv2
7086ovs-vsctl add-br br-phys
7087ovn_attach n1 br-phys 192.168.0.2
7088ovs-vsctl -- add-port br-int vm2 -- \
7089 set interface vm2 external-ids:iface-id=vm2 \
7090 options:tx_pcap=hv2/vm2-tx.pcap \
7091 options:rxq_pcap=hv2/vm2-rx.pcap \
7092 ofport-request=1
7093
7094# Pre-populate the hypervisors' ARP tables so that we don't lose any
7095# packets for ARP resolution (native tunneling doesn't queue packets
7096# for ARP resolution).
74868f2c 7097OVN_POPULATE_ARP
75fd74f8
GS
7098
7099# Allow some time for ovn-northd and ovn-controller to catch up.
7100# XXX This should be more systematic.
7101sleep 1
7102
7103ip_to_hex() {
7104 printf "%02x%02x%02x%02x" "$@"
7105}
7106
7107# Send ip packets between foo1 and foo2 (same switch, different HVs and
7108# different VLAN tags).
7109src_mac="f00000010205"
7110dst_mac="f00000010206"
7111src_ip=`ip_to_hex 192 168 1 2`
7112dst_ip=`ip_to_hex 192 168 1 3`
7113packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7114as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7115
7116# expected packet at foo2
7117packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7118echo $packet > expected
7119OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7120
7121# Send ip packets between foo1 and bar2 (different switch, different HV)
7122src_mac="f00000010205"
7123dst_mac="000000010203"
7124src_ip=`ip_to_hex 192 168 1 2`
7125dst_ip=`ip_to_hex 192 168 2 3`
7126packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7127as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7128
7129# expected packet at bar2
7130src_mac="000000010204"
7131dst_mac="f00000010208"
7132packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7133echo $packet >> expected
7134OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7135
7136# Send ip packets between foo1 and bar1
7137# (different switch, loopback to same vm but different tag)
7138src_mac="f00000010205"
7139dst_mac="000000010203"
7140src_ip=`ip_to_hex 192 168 1 2`
7141dst_ip=`ip_to_hex 192 168 2 2`
7142packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7143as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7144
7145# expected packet at bar1
7146src_mac="000000010204"
7147dst_mac="f00000010207"
7148packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7149echo $packet > expected1
7150OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7151
7152# Send ip packets between bar1 and bar3
7153# (same switch. But one is container and another is a standalone VM)
7154src_mac="f00000010207"
7155dst_mac="f00000010209"
7156src_ip=`ip_to_hex 192 168 2 2`
7157dst_ip=`ip_to_hex 192 168 2 3`
7158packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7159as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7160
7161# expected packet at bar3
7162packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7163echo $packet > expected
7164OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7165
7166# Send ip packets between foo1 and vm1.
7167(different switch, container to the VM hosting it.)
7168src_mac="f00000010205"
7169dst_mac="000000010203"
7170src_ip=`ip_to_hex 192 168 1 2`
7171dst_ip=`ip_to_hex 172 16 1 2`
7172packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7173as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7174
7175# expected packet at vm1
7176src_mac="000000010202"
7177dst_mac="f00000010203"
7178packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7179echo $packet >> expected1
7180OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7181
7182# Send packets from vm1 to bar1.
7183(different switch, A hosting VM to a container inside it)
7184src_mac="f00000010203"
7185dst_mac="000000010202"
7186src_ip=`ip_to_hex 172 16 1 2`
7187dst_ip=`ip_to_hex 192 168 2 2`
7188packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7189as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7190
7191# expected packet at vm1
7192src_mac="000000010204"
7193dst_mac="f00000010207"
7194packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7195echo $packet >> expected1
7196OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7197
22e506d3
NS
7198# Send broadcast packet from foo1. foo1 should not receive the same packet.
7199src_mac="f00000010205"
7200dst_mac="ffffffffffff"
7201src_ip=`ip_to_hex 192 168 1 2`
7202dst_ip=`ip_to_hex 255 255 255 255`
7203packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7204as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7205
7206# expected packet at VM1
7207OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7208
75fd74f8
GS
7209OVN_CLEANUP([hv1],[hv2])
7210
7211AT_CLEANUP
440a9f4b
GS
7212
7213AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7214AT_SKIP_IF([test $HAVE_PYTHON = no])
7215ovn_start
7216
7217# Logical network:
7218# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7219# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7220# (192.168.2.0/24) connected to it.
7221#
7222# R2 and R3 are gateway routers.
7223# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7224# connected to it. Note how both alice and bob have the same subnet behind it.
7225# We are trying to simulate external network via those 2 switches. In real
7226# world the switch ports of these switches will have addresses set as "unknown"
7227# to make them learning switches. Or those switches will be "localnet" ones.
7228
7229# Create three hypervisors and create OVS ports corresponding to logical ports.
7230net_add n1
7231
7232sim_add hv1
7233as hv1
7234ovs-vsctl add-br br-phys
7235ovn_attach n1 br-phys 192.168.0.1
7236ovs-vsctl -- add-port br-int hv1-vif1 -- \
7237 set interface hv1-vif1 external-ids:iface-id=foo1 \
7238 options:tx_pcap=hv1/vif1-tx.pcap \
7239 options:rxq_pcap=hv1/vif1-rx.pcap \
7240 ofport-request=1
7241
7242ovs-vsctl -- add-port br-int hv1-vif2 -- \
7243 set interface hv1-vif2 external-ids:iface-id=bar1 \
7244 options:tx_pcap=hv1/vif2-tx.pcap \
7245 options:rxq_pcap=hv1/vif2-rx.pcap \
7246 ofport-request=2
7247
7248sim_add hv2
7249as hv2
7250ovs-vsctl add-br br-phys
7251ovn_attach n1 br-phys 192.168.0.2
7252ovs-vsctl -- add-port br-int hv2-vif1 -- \
7253 set interface hv2-vif1 external-ids:iface-id=alice1 \
7254 options:tx_pcap=hv2/vif1-tx.pcap \
7255 options:rxq_pcap=hv2/vif1-rx.pcap \
7256 ofport-request=1
7257
7258sim_add hv3
7259as hv3
7260ovs-vsctl add-br br-phys
7261ovn_attach n1 br-phys 192.168.0.3
7262ovs-vsctl -- add-port br-int hv3-vif1 -- \
7263 set interface hv3-vif1 external-ids:iface-id=bob1 \
7264 options:tx_pcap=hv3/vif1-tx.pcap \
7265 options:rxq_pcap=hv3/vif1-rx.pcap \
7266 ofport-request=1
7267
7268
7269ovn-nbctl create Logical_Router name=R1
7270ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7271ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7272
7273ovn-nbctl ls-add foo
7274ovn-nbctl ls-add bar
7275ovn-nbctl ls-add alice
7276ovn-nbctl ls-add bob
7277ovn-nbctl ls-add join
7278
7279# Connect foo to R1
7280ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7281ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7282 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7283
7284# Connect bar to R1
7285ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7286ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7287 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7288
7289# Connect alice to R2
7290ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7291ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7292 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7293
7294# Connect bob to R3
7295ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7296ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7297 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7298
7299# Connect R1 to join
7300ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7301ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7302 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7303
7304# Connect R2 to join
7305ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7306ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7307 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7308
7309# Connect R3 to join
7310ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7311ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7312 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7313
7314# Install static routes with source ip address as the policy for routing.
7315# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7316ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7317ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7318
7319# Install static routes with destination ip address as the policy for routing.
7320ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7321
7322ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7323
7324# Create logical port foo1 in foo
7325ovn-nbctl lsp-add foo foo1 \
7326-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7327
7328# Create logical port bar1 in bar
7329ovn-nbctl lsp-add bar bar1 \
7330-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7331
7332# Create logical port alice1 in alice
7333ovn-nbctl lsp-add alice alice1 \
7334-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7335
7336# Create logical port bob1 in bob
7337ovn-nbctl lsp-add bob bob1 \
7338-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7339
7340# Pre-populate the hypervisors' ARP tables so that we don't lose any
7341# packets for ARP resolution (native tunneling doesn't queue packets
7342# for ARP resolution).
74868f2c 7343OVN_POPULATE_ARP
440a9f4b
GS
7344
7345# Allow some time for ovn-northd and ovn-controller to catch up.
7346# XXX This should be more systematic.
7347sleep 1
7348
7349ip_to_hex() {
7350 printf "%02x%02x%02x%02x" "$@"
7351}
7352trim_zeros() {
7353 sed 's/\(00\)\{1,\}$//'
7354}
7355
7356# Send ip packets between foo1 and bar1
7357# (East-west traffic should flow normally)
7358src_mac="f00000010203"
7359dst_mac="000001010203"
7360src_ip=`ip_to_hex 192 168 1 2`
7361dst_ip=`ip_to_hex 192 168 2 2`
7362packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7363as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7364
7365# Send ip packets between foo1 and alice1
7366src_mac="f00000010203"
7367dst_mac="000001010203"
7368src_ip=`ip_to_hex 192 168 1 2`
7369dst_ip=`ip_to_hex 172 16 1 3`
7370packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7371as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 7372as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
7373
7374# Send ip packets between bar1 and bob1
7375src_mac="f00000010204"
7376dst_mac="000001010204"
7377src_ip=`ip_to_hex 192 168 2 2`
7378dst_ip=`ip_to_hex 172 16 1 4`
7379packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7380as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7381#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7382
7383# Packet to expect at bar1
7384src_mac="000001010204"
7385dst_mac="f00000010204"
7386src_ip=`ip_to_hex 192 168 1 2`
7387dst_ip=`ip_to_hex 192 168 2 2`
7388expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7389echo $expected > expected
7390OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7391
7392# Packet to Expect at alice1
7393src_mac="000002010203"
7394dst_mac="f00000010205"
7395src_ip=`ip_to_hex 192 168 1 2`
7396dst_ip=`ip_to_hex 172 16 1 3`
7397expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7398echo $expected > expected
7399OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7400
7401# Packet to Expect at bob1
7402src_mac="000003010203"
7403dst_mac="f00000010206"
7404src_ip=`ip_to_hex 192 168 2 2`
7405dst_ip=`ip_to_hex 172 16 1 4`
7406expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7407echo $expected > expected
7408OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
7409
7410for sim in hv1 hv2 hv3; do
7411 as $sim
7412 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7413 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7414 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7415done
7416
7417as ovn-sb
7418OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7419
7420as ovn-nb
7421OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7422
7423as northd
7424OVS_APP_EXIT_AND_WAIT([ovn-northd])
7425
7426as main
7427OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7428OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7429
7430AT_CLEANUP
41a15b71 7431
302eda27
NS
7432AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
7433AT_SKIP_IF([test $HAVE_PYTHON = no])
7434ovn_start
7435
7436ovn-nbctl ls-add ls1
7437
7438ovn-nbctl lsp-add ls1 ls1-lp1 \
7439-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7440
7441ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7442
7443ovn-nbctl lsp-add ls1 ls1-lp2 \
7444-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7445
7446ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7447
7448DNS1=`ovn-nbctl create DNS records={}`
7449DNS2=`ovn-nbctl create DNS records={}`
7450
7451ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7452ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
7453ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
7454
7455ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
7456
7457net_add n1
7458sim_add hv1
7459
7460as hv1
7461ovs-vsctl add-br br-phys
7462ovn_attach n1 br-phys 192.168.0.1
7463ovs-vsctl -- add-port br-int hv1-vif1 -- \
7464 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
7465 options:tx_pcap=hv1/vif1-tx.pcap \
7466 options:rxq_pcap=hv1/vif1-rx.pcap \
7467 ofport-request=1
7468
7469ovs-vsctl -- add-port br-int hv1-vif2 -- \
7470 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
7471 options:tx_pcap=hv1/vif2-tx.pcap \
7472 options:rxq_pcap=hv1/vif2-rx.pcap \
7473 ofport-request=2
7474
74868f2c 7475OVN_POPULATE_ARP
302eda27
NS
7476sleep 2
7477as hv1 ovs-vsctl show
7478
7479echo "*************************"
7480ovn-sbctl list DNS
7481echo "*************************"
7482
7483ip_to_hex() {
7484 printf "%02x%02x%02x%02x" "$@"
7485}
7486
7487reset_pcap_file() {
7488 local iface=$1
7489 local pcap_file=$2
7490 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7491options:rxq_pcap=dummy-rx.pcap
7492 rm -f ${pcap_file}*.pcap
7493 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7494options:rxq_pcap=${pcap_file}-rx.pcap
7495}
7496
7497# set_dns_params host_name
7498# Sets the dns_req_data and dns_resp_data
7499set_dns_params() {
7500 local hname=$1
7501 local ttl=00000e10
7502 an_count=0001
7503 type=0001
7504 case $hname in
7505 vm1)
7506 # vm1.ovn.org
7507 query_name=03766d31036f766e036f726700
7508 # IPv4 address - 10.0.0.4
7509 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7510 ;;
7511 vm2)
7512 # vm2.ovn.org
7513 query_name=03766d32036f766e036f726700
7514 # IPv4 address - 10.0.0.6
7515 expected_dns_answer=${query_name}00010001${ttl}00040a000006
7516 # IPv4 address - 20.0.0.4
7517 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
7518 an_count=0002
7519 ;;
7520 vm3)
7521 # vm3.ovn.org
7522 query_name=03766d33036f766e036f726700
7523 # IPv4 address - 40.0.0.4
7524 expected_dns_answer=${query_name}00010001${ttl}000428000004
7525 ;;
7526 vm1_ipv6_only)
7527 # vm1.ovn.org
7528 query_name=03766d31036f766e036f726700
7529 # IPv6 address - aef0::4
7530 type=001c
7531 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
7532 ;;
7533 vm1_ipv4_v6)
7534 # vm1.ovn.org
7535 query_name=03766d31036f766e036f726700
7536 type=00ff
7537 an_count=0002
7538 # IPv4 address - 10.0.0.4
7539 # IPv6 address - aef0::4
7540 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7541 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7542 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7543 ;;
7544 vm1_invalid_type)
7545 # vm1.ovn.org
7546 query_name=03766d31036f766e036f726700
7547 # IPv6 address - aef0::4
7548 type=0002
7549 ;;
7550 vm1_incomplete)
7551 # set type to none
7552 type=''
7553 esac
7554 # TTL - 3600
7555 local dns_req_header=010201200001000000000000
7556 local dns_resp_header=010281200001${an_count}00000000
7557 dns_req_data=${dns_req_header}${query_name}${type}0001
7558 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7559}
7560
7561# This shell function sends a DNS request packet
7562# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7563test_dns() {
7564 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7565 local dns_query_data=$7
7566 shift; shift; shift; shift; shift; shift; shift;
7567 # Packet size => IPv4 header (20) + UDP header (8) +
7568 # DNS data (header + query)
7569 ip_len=`expr 28 + ${#dns_query_data} / 2`
7570 udp_len=`expr $ip_len - 20`
7571 ip_len=$(printf "%x" $ip_len)
7572 udp_len=$(printf "%x" $udp_len)
7573 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7574 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7575 # dns data
7576 request=${request}${dns_query_data}
7577
7578 if test $dns_reply != 0; then
7579 local dns_reply=$1
7580 ip_len=`expr 28 + ${#dns_reply} / 2`
7581 udp_len=`expr $ip_len - 20`
7582 ip_len=$(printf "%x" $ip_len)
7583 udp_len=$(printf "%x" $udp_len)
7584 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7585 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7586 echo $reply >> $inport.expected
7587 else
7588 for outport; do
7589 echo $request >> $outport.expected
7590 done
7591 fi
7592 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7593}
7594
f8e79d82
MM
7595test_dns6() {
7596 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7597 local dns_query_data=$7
7598 shift; shift; shift; shift; shift; shift; shift;
7599 # Packet size => UDP header (8) +
7600 # DNS data (header + query)
7601 ip_len=`expr 8 + ${#dns_query_data} / 2`
7602 udp_len=$ip_len
7603 ip_len=$(printf "%x" $ip_len)
7604 udp_len=$(printf "%x" $udp_len)
7605 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7606 request=${request}9234003500${udp_len}0000
7607 #dns data
7608 request=${request}${dns_query_data}
7609
7610 if test $dns_reply != 0; then
7611 local dns_reply=$1
7612 ip_len=`expr 8 + ${#dns_reply} / 2`
7613 udp_len=$ip_len
7614 ip_len=$(printf "%x" $ip_len)
7615 udp_len=$(printf "%x" $udp_len)
7616 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7617 reply=${reply}0035923400${udp_len}0000${dns_reply}
7618 echo $reply >> $inport.expected
7619 else
7620 for outport; do
7621 echo $request >> $outport.expected
7622 done
7623 fi
7624 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7625}
7626
302eda27
NS
7627AT_CAPTURE_FILE([ofctl_monitor0.log])
7628as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7629--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7630
7631set_dns_params vm2
7632src_ip=`ip_to_hex 10 0 0 4`
7633dst_ip=`ip_to_hex 10 0 0 1`
7634dns_reply=1
7635test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7636
7637# NXT_RESUMEs should be 1.
7638OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7639
7640$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7641cat 1.expected | cut -c -48 > expout
7642AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7643# Skipping the IPv4 checksum.
7644cat 1.expected | cut -c 53- > expout
7645AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7646
7647reset_pcap_file hv1-vif1 hv1/vif1
7648reset_pcap_file hv1-vif2 hv1/vif2
7649rm -f 1.expected
7650rm -f 2.expected
7651
7652set_dns_params vm1
7653src_ip=`ip_to_hex 10 0 0 6`
7654dst_ip=`ip_to_hex 10 0 0 1`
7655dns_reply=1
7656test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7657
7658# NXT_RESUMEs should be 2.
7659OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7660
7661$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7662cat 2.expected | cut -c -48 > expout
7663AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7664# Skipping the IPv4 checksum.
7665cat 2.expected | cut -c 53- > expout
7666AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7667
7668reset_pcap_file hv1-vif1 hv1/vif1
7669reset_pcap_file hv1-vif2 hv1/vif2
7670rm -f 1.expected
7671rm -f 2.expected
7672
7673# Clear the query name options for ls1-lp2
7674ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7675
7676set_dns_params vm2
7677src_ip=`ip_to_hex 10 0 0 4`
7678dst_ip=`ip_to_hex 10 0 0 1`
7679dns_reply=0
7680test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7681
7682# NXT_RESUMEs should be 3.
7683OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7684
7685$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7686AT_CHECK([cat 1.packets], [0], [])
7687
7688reset_pcap_file hv1-vif1 hv1/vif1
7689reset_pcap_file hv1-vif2 hv1/vif2
7690rm -f 1.expected
7691rm -f 2.expected
7692
7693# Clear the query name for ls1-lp1
7694# Since ls1 has no query names configued,
7695# ovn-northd should not add the DNS flows.
7696ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7697
7698set_dns_params vm1
7699src_ip=`ip_to_hex 10 0 0 6`
7700dst_ip=`ip_to_hex 10 0 0 1`
7701dns_reply=0
7702test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7703
7704# NXT_RESUMEs should be 3 only.
7705OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7706
7707$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7708AT_CHECK([cat 2.packets], [0], [])
7709
7710reset_pcap_file hv1-vif1 hv1/vif1
7711reset_pcap_file hv1-vif2 hv1/vif2
7712rm -f 1.expected
7713rm -f 2.expected
7714
7715# Test IPv6 (AAAA records) using IPv4 packet.
7716# Add back the DNS options for ls1-lp1.
4f4ac4bb 7717ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
302eda27
NS
7718
7719set_dns_params vm1_ipv6_only
7720src_ip=`ip_to_hex 10 0 0 6`
7721dst_ip=`ip_to_hex 10 0 0 1`
7722dns_reply=1
7723test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7724
7725# NXT_RESUMEs should be 4.
7726OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7727
7728$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7729cat 2.expected | cut -c -48 > expout
7730AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7731# Skipping the IPv4 checksum.
7732cat 2.expected | cut -c 53- > expout
7733AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7734
7735reset_pcap_file hv1-vif1 hv1/vif1
7736reset_pcap_file hv1-vif2 hv1/vif2
7737rm -f 1.expected
7738rm -f 2.expected
7739
7740# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7741set_dns_params vm1_ipv4_v6
7742src_ip=`ip_to_hex 10 0 0 6`
7743dst_ip=`ip_to_hex 10 0 0 1`
7744dns_reply=1
7745test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7746
7747# NXT_RESUMEs should be 5.
7748OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7749
7750$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7751cat 2.expected | cut -c -48 > expout
7752AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7753# Skipping the IPv4 checksum.
7754cat 2.expected | cut -c 53- > expout
7755AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7756
7757reset_pcap_file hv1-vif1 hv1/vif1
7758reset_pcap_file hv1-vif2 hv1/vif2
7759rm -f 1.expected
7760rm -f 2.expected
7761
7762# Invalid type.
7763set_dns_params vm1_invalid_type
7764src_ip=`ip_to_hex 10 0 0 6`
7765dst_ip=`ip_to_hex 10 0 0 1`
7766dns_reply=0
7767test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7768
7769# NXT_RESUMEs should be 6.
7770OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7771
7772$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7773AT_CHECK([cat 2.packets], [0], [])
7774
7775reset_pcap_file hv1-vif1 hv1/vif1
7776reset_pcap_file hv1-vif2 hv1/vif2
7777rm -f 1.expected
7778rm -f 2.expected
7779
7780# Incomplete DNS packet.
7781set_dns_params vm1_incomplete
7782src_ip=`ip_to_hex 10 0 0 6`
7783dst_ip=`ip_to_hex 10 0 0 1`
7784dns_reply=0
7785test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7786
7787# NXT_RESUMEs should be 7.
7788OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7789
7790$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7791AT_CHECK([cat 2.packets], [0], [])
7792
7793reset_pcap_file hv1-vif1 hv1/vif1
7794reset_pcap_file hv1-vif2 hv1/vif2
7795rm -f 1.expected
7796rm -f 2.expected
7797
7798# Add one more DNS record to the ls1.
7799ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7800
7801set_dns_params vm3
7802src_ip=`ip_to_hex 10 0 0 4`
7803dst_ip=`ip_to_hex 10 0 0 1`
7804dns_reply=1
7805test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7806
7807# NXT_RESUMEs should be 8.
7808OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7809
7810$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7811cat 1.expected | cut -c -48 > expout
7812AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7813# Skipping the IPv4 checksum.
7814cat 1.expected | cut -c 53- > expout
7815AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7816
7817reset_pcap_file hv1-vif1 hv1/vif1
7818reset_pcap_file hv1-vif2 hv1/vif2
7819rm -f 1.expected
7820rm -f 2.expected
7821
f8e79d82
MM
7822# Try DNS query over IPv6
7823set_dns_params vm1
7824src_ip=aef00000000000000000000000000004
7825dst_ip=aef00000000000000000000000000001
7826dns_reply=1
7827test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7828
7829# NXT_RESUMEs should be 9.
7830OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7831
7832$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
b75f2651
MM
7833# Skipping the UDP checksum.
7834cat 1.expected | cut -c 1-120,125- > expout
7835AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
f8e79d82
MM
7836
7837reset_pcap_file hv1-vif1 hv1/vif1
7838reset_pcap_file hv1-vif2 hv1/vif2
7839rm -f 1.expected
7840rm -f 2.expected
7841
302eda27
NS
7842as hv1
7843 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7844OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7845OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7846
7847as ovn-sb
7848OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7849
7850as ovn-nb
7851OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7852
7853as northd
7854OVS_APP_EXIT_AND_WAIT([ovn-northd])
7855
7856as main
7857OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7858OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7859AT_CLEANUP
7860
75f9e007 7861AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 7862AT_SKIP_IF([test $HAVE_PYTHON = no])
7863ovn_start
7864
7865net_add n1
7866
7867sim_add hv1
7868as hv1
7869ovs-vsctl add-br br-phys
7870ovn_attach n1 br-phys 192.168.0.1
7871ovs-vsctl -- add-port br-int hv1-vif1 -- \
7872 set interface hv1-vif1 external-ids:iface-id=foo1 \
7873 options:tx_pcap=hv1/vif1-tx.pcap \
7874 options:rxq_pcap=hv1/vif1-rx.pcap \
7875 ofport-request=1
7876
7877sim_add gw1
7878as gw1
7879ovs-vsctl add-br br-phys
7880ovn_attach n1 br-phys 192.168.0.2
7881
7882sim_add gw2
7883as gw2
7884ovs-vsctl add-br br-phys
7885ovn_attach n1 br-phys 192.168.0.4
7886
7887sim_add ext1
7888as ext1
7889ovs-vsctl add-br br-phys
7890ovn_attach n1 br-phys 192.168.0.3
7891ovs-vsctl -- add-port br-int ext1-vif1 -- \
7892 set interface ext1-vif1 external-ids:iface-id=outside1 \
7893 options:tx_pcap=ext1/vif1-tx.pcap \
7894 options:rxq_pcap=ext1/vif1-rx.pcap \
7895 ofport-request=1
7896
7897# Pre-populate the hypervisors' ARP tables so that we don't lose any
7898# packets for ARP resolution (native tunneling doesn't queue packets
7899# for ARP resolution).
74868f2c 7900OVN_POPULATE_ARP
1da17a0b 7901
7902ovn-nbctl create Logical_Router name=R1
7903
7904ovn-nbctl ls-add foo
7905ovn-nbctl ls-add alice
7906ovn-nbctl ls-add outside
7907
7908# Connect foo to R1
7909ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7910ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7911 type=router options:router-port=foo \
7912 -- lsp-set-addresses rp-foo router
7913
7914# Connect alice to R1 as distributed router gateway port on gw1
7915ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7916
7917ovn-nbctl \
7918 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7919 chassis_name=gw1 \
7920 priority=20 -- \
7921 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7922 chassis_name=gw2 \
7923 priority=10 -- \
7924 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7925
7926ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7927 type=router options:router-port=alice \
7928 -- lsp-set-addresses rp-alice router
7929
7930# Create logical port foo1 in foo
7931ovn-nbctl lsp-add foo foo1 \
7932-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7933
7934# Create logical port outside1 in outside
7935ovn-nbctl lsp-add outside outside1 \
7936-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7937
7938# Create localnet port in alice
7939ovn-nbctl lsp-add alice ln-alice
7940ovn-nbctl lsp-set-addresses ln-alice unknown
7941ovn-nbctl lsp-set-type ln-alice localnet
7942ovn-nbctl lsp-set-options ln-alice network_name=phys
7943
7944# Create localnet port in outside
7945ovn-nbctl lsp-add outside ln-outside
7946ovn-nbctl lsp-set-addresses ln-outside unknown
7947ovn-nbctl lsp-set-type ln-outside localnet
7948ovn-nbctl lsp-set-options ln-outside network_name=phys
7949
7950# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7951# mapping to the external network, is the one generating packets
7952as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7953as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7954as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7955
7956AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7957
7958# Allow some time for ovn-northd and ovn-controller to catch up.
7959# XXX This should be more systematic.
7960sleep 2
7961
7962ip_to_hex() {
7963 printf "%02x%02x%02x%02x" "$@"
7964}
7965
7966reset_pcap_file() {
7967 local iface=$1
7968 local pcap_file=$2
7969 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7970options:rxq_pcap=dummy-rx.pcap
7971 rm -f ${pcap_file}*.pcap
7972 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7973options:rxq_pcap=${pcap_file}-rx.pcap
7974}
7975
7976test_ip_packet()
7977{
7978 local active_gw=$1
7979 local backup_gw=$2
7980
7981 # Send ip packet between foo1 and outside1
7982 src_mac="f00000010203" # foo1 mac
7983 dst_mac="000001010203" # rp-foo mac (internal router leg)
7984 src_ip=`ip_to_hex 192 168 1 2`
7985 dst_ip=`ip_to_hex 172 16 1 3`
7986 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7987
7988 # ARP request packet to expect at outside1
7989 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7990
7991 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7992
7993 # Send ARP reply from outside1 back to the router
7994 # XXX: note, we could avoid this if we plug this port into a netns
7995 # and setup the IP address into the port, so the kernel would simply reply
7996 src_mac="000002010203"
7997 reply_mac="f00000010204"
7998 dst_ip=`ip_to_hex 172 16 1 3`
7999 src_ip=`ip_to_hex 172 16 1 1`
8000 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8001
8002 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8003
86c9d79a
NS
8004 OVS_WAIT_UNTIL([
8005 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8006grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8007 ])
8008
1da17a0b 8009 # Packet to Expect at ext1 chassis, outside1 port
8010 src_mac="000002010203"
8011 dst_mac="f00000010204"
8012 src_ip=`ip_to_hex 192 168 1 2`
8013 dst_ip=`ip_to_hex 172 16 1 3`
8014 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8015 echo $expected > ext1-vif1.expected
8016
8017 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8018 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8019 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8020
8021 # Resend packet from foo1 to outside1
8022 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8023
8024 sleep 1
8025
8026 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8027 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8028 AT_CHECK([grep $expected packets | sort], [0], [expout])
8029 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8030 AT_CHECK([grep $expected packets | sort], [0], [])
8031}
8032
8033test_ip_packet gw1 gw2
8034
75f9e007
GZ
8035ovn-nbctl --timeout=3 --wait=hv \
8036 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8037 chassis_name=gw1 \
8038 priority=10 -- \
8039 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8040 chassis_name=gw2 \
8041 priority=20 -- \
8042 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8043
8044test_ip_packet gw2 gw1
8045
8046OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8047AT_CLEANUP
8048
8049AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
8050AT_SKIP_IF([test $HAVE_PYTHON = no])
8051ovn_start
8052
8053net_add n1
8054
8055sim_add hv1
8056as hv1
8057ovs-vsctl add-br br-phys
8058ovn_attach n1 br-phys 192.168.0.1
8059ovs-vsctl -- add-port br-int hv1-vif1 -- \
8060 set interface hv1-vif1 external-ids:iface-id=foo1 \
8061 options:tx_pcap=hv1/vif1-tx.pcap \
8062 options:rxq_pcap=hv1/vif1-rx.pcap \
8063 ofport-request=1
8064
8065sim_add gw1
8066as gw1
8067ovs-vsctl add-br br-phys
8068ovn_attach n1 br-phys 192.168.0.2
8069
8070sim_add gw2
8071as gw2
8072ovs-vsctl add-br br-phys
8073ovn_attach n1 br-phys 192.168.0.4
8074
8075sim_add ext1
8076as ext1
8077ovs-vsctl add-br br-phys
8078ovn_attach n1 br-phys 192.168.0.3
8079ovs-vsctl -- add-port br-int ext1-vif1 -- \
8080 set interface ext1-vif1 external-ids:iface-id=outside1 \
8081 options:tx_pcap=ext1/vif1-tx.pcap \
8082 options:rxq_pcap=ext1/vif1-rx.pcap \
8083 ofport-request=1
8084
8085# Pre-populate the hypervisors' ARP tables so that we don't lose any
8086# packets for ARP resolution (native tunneling doesn't queue packets
8087# for ARP resolution).
74868f2c 8088OVN_POPULATE_ARP
75f9e007
GZ
8089
8090ovn-nbctl create Logical_Router name=R0
8091ovn-nbctl create Logical_Router name=R1
8092
8093ovn-nbctl ls-add foo
8094ovn-nbctl ls-add join
8095ovn-nbctl ls-add alice
8096ovn-nbctl ls-add outside
8097
8098#Connect foo to R0
8099ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
8100ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
8101 type=router options:router-port=R0-foo \
8102 -- lsp-set-addresses foo-R0 router
8103
8104#Connect R0 to join
8105ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
8106ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
8107 type=router options:router-port=R0-join \
8108 -- lsp-set-addresses join-R0 router
8109
8110#Connect join to R1
8111ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
8112ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
8113 type=router options:router-port=R1-join \
8114 -- lsp-set-addresses join-R1 router
8115
8116#add route rules
8117ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
8118ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
8119
8120# Connect alice to R1 as distributed router gateway port on gw1
8121ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8122
8123ovn-nbctl \
8124 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8125 chassis_name=gw1 \
8126 priority=20 -- \
8127 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8128 chassis_name=gw2 \
8129 priority=10 -- \
8130 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8131
8132ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8133 type=router options:router-port=alice \
8134 -- lsp-set-addresses rp-alice router
8135
8136# Create logical port foo1 in foo
8137ovn-nbctl lsp-add foo foo1 \
8138-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8139
8140# Create logical port outside1 in outside
8141ovn-nbctl lsp-add outside outside1 \
8142-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8143
8144# Create localnet port in alice
8145ovn-nbctl lsp-add alice ln-alice
8146ovn-nbctl lsp-set-addresses ln-alice unknown
8147ovn-nbctl lsp-set-type ln-alice localnet
8148ovn-nbctl lsp-set-options ln-alice network_name=phys
8149
8150# Create localnet port in outside
8151ovn-nbctl lsp-add outside ln-outside
8152ovn-nbctl lsp-set-addresses ln-outside unknown
8153ovn-nbctl lsp-set-type ln-outside localnet
8154ovn-nbctl lsp-set-options ln-outside network_name=phys
8155
8156# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8157# mapping to the external network, is the one generating packets
8158as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8159as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8160as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8161
8162AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8163
8164# Allow some time for ovn-northd and ovn-controller to catch up.
8165# XXX This should be more systematic.
8166sleep 2
8167
8168ip_to_hex() {
8169 printf "%02x%02x%02x%02x" "$@"
8170}
8171
8172reset_pcap_file() {
8173 local iface=$1
8174 local pcap_file=$2
8175 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8176options:rxq_pcap=dummy-rx.pcap
8177 rm -f ${pcap_file}*.pcap
8178 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8179options:rxq_pcap=${pcap_file}-rx.pcap
8180}
8181
8182test_ip_packet()
8183{
8184 local active_gw=$1
8185 local backup_gw=$2
8186
8187 # Send ip packet between foo1 and outside1
8188 src_mac="f00000010203" # foo1 mac
8189 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8190 src_ip=`ip_to_hex 192 168 1 2`
8191 dst_ip=`ip_to_hex 172 16 1 3`
8192 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8193
8194 # ARP request packet to expect at outside1
8195 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8196
8197 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8198
8199 # Send ARP reply from outside1 back to the router
8200 # XXX: note, we could avoid this if we plug this port into a netns
8201 # and setup the IP address into the port, so the kernel would simply reply
8202 src_mac="000002010203"
8203 reply_mac="f00000010204"
8204 dst_ip=`ip_to_hex 172 16 1 3`
8205 src_ip=`ip_to_hex 172 16 1 1`
8206 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8207
8208 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8209
86c9d79a
NS
8210 OVS_WAIT_UNTIL([
8211 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8212grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8213 ])
8214
75f9e007
GZ
8215 # Packet to Expect at ext1 chassis, outside1 port
8216 src_mac="000002010203"
8217 dst_mac="f00000010204"
8218 src_ip=`ip_to_hex 192 168 1 2`
8219 dst_ip=`ip_to_hex 172 16 1 3`
8220 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8221 echo $expected > ext1-vif1.expected
8222
8223 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8224 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8225 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8226
8227 # Resend packet from foo1 to outside1
8228 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8229
8230 sleep 1
8231
8232 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8233 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8234 AT_CHECK([grep $expected packets | sort], [0], [expout])
8235 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8236 AT_CHECK([grep $expected packets | sort], [0], [])
8237}
8238
8239test_ip_packet gw1 gw2
8240
8e1d9349 8241ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 8242 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8243 chassis_name=gw1 \
8244 priority=10 -- \
8245 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8246 chassis_name=gw2 \
8247 priority=20 -- \
8248 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8249
8250test_ip_packet gw2 gw1
8251
8252OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8253AT_CLEANUP
8254
41a15b71
MS
8255AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8256AT_SKIP_IF([test $HAVE_PYTHON = no])
8257ovn_start
8258
8259# Logical network:
8260# One LR R1 that has switches foo (192.168.1.0/24) and
8261# alice (172.16.1.0/24) connected to it. The logical port
8262# between R1 and alice has a "redirect-chassis" specified,
8263# i.e. it is the distributed router gateway port.
8264# Switch alice also has a localnet port defined.
8265# An additional switch outside has a localnet port and the
8266# same subnet as alice (172.16.1.0/24).
8267
8268# Physical network:
8269# Three hypervisors hv[123].
8270# hv1 hosts vif foo1.
8271# hv2 is the "redirect-chassis" that hosts the distributed
8272# router gateway port.
8273# hv3 hosts vif outside1.
8274# In order to show that connectivity works only through hv2,
8275# an initial round of tests is run without any bridge-mapping
8276# defined for the localnet on hv2. These tests are expected
8277# to fail.
8278# Subsequent tests are run after defining the bridge-mapping
8279# for the localnet on hv2. These tests are expected to succeed.
8280
8281# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 8282# to logical ports.
41a15b71
MS
8283net_add n1
8284
8285sim_add hv1
8286as hv1
8287ovs-vsctl add-br br-phys
8288ovn_attach n1 br-phys 192.168.0.1
8289ovs-vsctl -- add-port br-int hv1-vif1 -- \
8290 set interface hv1-vif1 external-ids:iface-id=foo1 \
8291 options:tx_pcap=hv1/vif1-tx.pcap \
8292 options:rxq_pcap=hv1/vif1-rx.pcap \
8293 ofport-request=1
8294
8295sim_add hv2
8296as hv2
8297ovs-vsctl add-br br-phys
8298ovn_attach n1 br-phys 192.168.0.2
8299
8300sim_add hv3
8301as hv3
8302ovs-vsctl add-br br-phys
8303ovn_attach n1 br-phys 192.168.0.3
8304ovs-vsctl -- add-port br-int hv3-vif1 -- \
8305 set interface hv3-vif1 external-ids:iface-id=outside1 \
8306 options:tx_pcap=hv3/vif1-tx.pcap \
8307 options:rxq_pcap=hv3/vif1-rx.pcap \
8308 ofport-request=1
8309
8310# Pre-populate the hypervisors' ARP tables so that we don't lose any
8311# packets for ARP resolution (native tunneling doesn't queue packets
8312# for ARP resolution).
74868f2c 8313OVN_POPULATE_ARP
41a15b71
MS
8314
8315ovn-nbctl create Logical_Router name=R1
8316
8317ovn-nbctl ls-add foo
8318ovn-nbctl ls-add alice
8319ovn-nbctl ls-add outside
8320
8321# Connect foo to R1
8322ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8323ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8324 type=router options:router-port=foo \
8325 -- lsp-set-addresses rp-foo router
8326
8327# Connect alice to R1 as distributed router gateway port on hv2
8328ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8329 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8330ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8331 type=router options:router-port=alice \
8332 -- lsp-set-addresses rp-alice router
8333
8334# Create logical port foo1 in foo
8335ovn-nbctl lsp-add foo foo1 \
8336-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8337
8338# Create logical port outside1 in outside
8339ovn-nbctl lsp-add outside outside1 \
8340-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8341
8342# Create localnet port in alice
8343ovn-nbctl lsp-add alice ln-alice
8344ovn-nbctl lsp-set-addresses ln-alice unknown
8345ovn-nbctl lsp-set-type ln-alice localnet
8346ovn-nbctl lsp-set-options ln-alice network_name=phys
8347
8348# Create localnet port in outside
8349ovn-nbctl lsp-add outside ln-outside
8350ovn-nbctl lsp-set-addresses ln-outside unknown
8351ovn-nbctl lsp-set-type ln-outside localnet
8352ovn-nbctl lsp-set-options ln-outside network_name=phys
8353
8354# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8355as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8356as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8357
8358
8359# Allow some time for ovn-northd and ovn-controller to catch up.
8360# XXX This should be more systematic.
8361sleep 2
8362
8363echo "---------NB dump-----"
8364ovn-nbctl show
8365echo "---------------------"
8366ovn-nbctl list logical_router
8367echo "---------------------"
8368ovn-nbctl list logical_router_port
8369echo "---------------------"
8370
8371echo "---------SB dump-----"
8372ovn-sbctl list datapath_binding
8373echo "---------------------"
8374ovn-sbctl list port_binding
8375echo "---------------------"
8376ovn-sbctl dump-flows
8377echo "---------------------"
8378ovn-sbctl list chassis
8379ovn-sbctl list encap
1da17a0b 8380echo "------ Gateway_Chassis dump (SBDB) -------"
8381ovn-sbctl list Gateway_Chassis
8382echo "------ Port_Binding chassisredirect -------"
8383ovn-sbctl find Port_Binding type=chassisredirect
8384echo "-------------------------------------------"
41a15b71
MS
8385
8386echo "------ hv1 dump ----------"
8387as hv1 ovs-ofctl show br-int
8388as hv1 ovs-ofctl dump-flows br-int
8389echo "------ hv2 dump ----------"
8390as hv2 ovs-ofctl show br-int
8391as hv2 ovs-ofctl dump-flows br-int
8392echo "------ hv3 dump ----------"
8393as hv3 ovs-ofctl show br-int
8394as hv3 ovs-ofctl dump-flows br-int
8395echo "--------------------------"
8396
1da17a0b 8397
41a15b71
MS
8398# Check that redirect mapping is programmed only on hv2
8399AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8400])
8401AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
8402])
8403# Check that hv1 sends chassisredirect port traffic to hv2
8404AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
8405])
8406AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8407])
8408# Check that arp reply on distributed gateway port is only programmed on hv2
b0684540 8409AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
41a15b71 8410])
b0684540 8411AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
41a15b71
MS
8412])
8413
8414
8415ip_to_hex() {
8416 printf "%02x%02x%02x%02x" "$@"
8417}
8418
8419
8420: > hv2-vif1.expected
8421: > hv3-vif1.expected
8422
8423# test_arp INPORT SHA SPA TPA [REPLY_HA]
8424#
8425# Causes a packet to be received on INPORT. The packet is an ARP
8426# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
8427# it should be the hardware address of the target to expect to receive in an
8428# ARP reply; otherwise no reply is expected.
8429#
8430# INPORT is an logical switch port number, e.g. 11 for vif11.
8431# SHA and REPLY_HA are each 12 hex digits.
8432# SPA and TPA are each 8 hex digits.
8433test_arp() {
8434 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
8435 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
8436 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
8437
8438 if test X$reply_ha != X; then
8439 # Expect to receive the reply, if any.
8440 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
8441 echo $reply >> hv${hv}-vif$inport.expected
8442 fi
8443}
8444
8445rtr_ip=$(ip_to_hex 172 16 1 1)
8446foo_ip=$(ip_to_hex 192 168 1 2)
8447outside_ip=$(ip_to_hex 172 16 1 3)
8448
8449echo $rtr_ip
8450echo $foo_ip
8451echo $outside_ip
8452
8453# ARP for router IP address from outside1, no response expected
8454test_arp 3 1 f00000010204 $outside_ip $rtr_ip
8455
8456# Now check the packets actually received against the ones expected.
8457OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8458
8459# Send ip packet between foo1 and outside1
8460src_mac="f00000010203"
8461dst_mac="000001010203"
8462src_ip=`ip_to_hex 192 168 1 2`
8463dst_ip=`ip_to_hex 172 16 1 3`
8464packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8465
8466# Now check the packets actually received against the ones expected.
8467OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8468
8469# Now add bridge-mappings on hv2, which should make everything work
8470as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8471
8472# Allow some time for ovn-northd and ovn-controller to catch up.
8473# XXX This should be more systematic.
8474sleep 2
8475
8476# ARP for router IP address from outside1
8477test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
8478
8479# Now check the packets actually received against the ones expected.
8480OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8481
8482# Send ip packet between foo1 and outside1
8483src_mac="f00000010203"
8484dst_mac="000001010203"
8485src_ip=`ip_to_hex 192 168 1 2`
8486dst_ip=`ip_to_hex 172 16 1 3`
8487packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8488
41a15b71
MS
8489# Packet to Expect at outside1
8490src_mac="000002010203"
8491dst_mac="f00000010204"
41a15b71
MS
8492expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8493
41a15b71
MS
8494as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8495
8496echo "------ hv1 dump ----------"
8497as hv1 ovs-ofctl show br-int
8498as hv1 ovs-ofctl dump-flows br-int
8499echo "------ hv2 dump ----------"
8500as hv2 ovs-ofctl show br-int
8501as hv2 ovs-ofctl dump-flows br-int
8502echo "------ hv3 dump ----------"
8503as hv3 ovs-ofctl show br-int
8504as hv3 ovs-ofctl dump-flows br-int
8505echo "----------------------------"
8506
8507echo $expected >> hv3-vif1.expected
8508OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8509
8510#Check ovn-trace over "chassisredirect" port
8511AT_CAPTURE_FILE([trace])
8512ovn_trace () {
8513 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
8514}
8515
8516echo 'ip.ttl--;' > expout
8517echo 'eth.src = 00:00:02:01:02:03;' >> expout
8518echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8519echo 'output("ln-alice");' >> expout
8520AT_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])
8521
8522# Create logical port alice1 in alice on hv1
8523as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8524 set interface hv1-vif2 external-ids:iface-id=alice1 \
8525 options:tx_pcap=hv1/vif2-tx.pcap \
8526 options:rxq_pcap=hv1/vif2-rx.pcap \
8527 ofport-request=1
8528
8529ovn-nbctl lsp-add alice alice1 \
8530-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8531
8532# Create logical port foo2 in foo on hv2
8533as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8534 set interface hv2-vif1 external-ids:iface-id=foo2 \
8535 options:tx_pcap=hv2/vif1-tx.pcap \
8536 options:rxq_pcap=hv2/vif1-rx.pcap \
8537 ofport-request=1
8538
8539ovn-nbctl lsp-add foo foo2 \
8540-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8541
8542# Allow some time for ovn-northd and ovn-controller to catch up.
8543# XXX This should be more systematic.
8544sleep 1
8545
8546: > hv1-vif2.expected
8547
8548# Send ip packet between alice1 and foo2
8549src_mac="f00000010205"
8550dst_mac="000002010203"
8551src_ip=`ip_to_hex 172 16 1 4`
8552dst_ip=`ip_to_hex 192 168 1 3`
8553packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8554
8555as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8556
8557# Packet to Expect at foo2
8558src_mac="000001010203"
8559dst_mac="f00000010206"
8560src_ip=`ip_to_hex 172 16 1 4`
8561dst_ip=`ip_to_hex 192 168 1 3`
8562expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8563
8564echo $expected >> hv2-vif1.expected
f5f64552 8565OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 8566
0d31e5be 8567AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 8568])
8569
8e1d9349 8570ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 8571
0d31e5be 8572AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 8573])
8574
41a15b71
MS
8575OVN_CLEANUP([hv1],[hv2],[hv3])
8576
8577AT_CLEANUP
26b9e08d
MS
8578
8579AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8580AT_SKIP_IF([test $HAVE_PYTHON = no])
8581ovn_start
8582# Create logical switches
8583ovn-nbctl ls-add ls0
8584ovn-nbctl ls-add ls1
8585# Create distributed router
8586ovn-nbctl create Logical_Router name=lr0
8587# Add distributed gateway port to distributed router
8588ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8589 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8590ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8591 type=router options:router-port=lrp0 addresses="router"
8592# Add router port to ls1
8593ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8594ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8595 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
8596# Add logical ports for NAT rules
8597ovn-nbctl lsp-add ls1 foo1 \
8598-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8599ovn-nbctl lsp-add ls1 foo2 \
8600-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
8601# Add nat-addresses option
8602ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8603# Add NAT rules
8604AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8605AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8606AT_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 8607AT_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
8608
8609net_add n1
8610sim_add hv1
8611as hv1
8612ovs-vsctl add-br br-phys
8613ovn_attach n1 br-phys 192.168.0.1
8614
8615AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8616AT_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])
8617
8618sim_add hv2
8619as hv2
8620ovs-vsctl add-br br-phys
8621ovn_attach n1 br-phys 192.168.0.2
8622# Initially test with no bridge-mapping on hv2, expect to receive no packets
8623
f40c5588
MS
8624sim_add hv3
8625as hv3
8626ovs-vsctl add-br br-phys
8627ovn_attach n1 br-phys 192.168.0.3
8628# Initially test with no bridge-mapping on hv3
8629
26b9e08d
MS
8630# Create a localnet port.
8631AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8632AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8633AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8634AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8635
8636# Allow some time for ovn-northd and ovn-controller to catch up.
8637# XXX This should be more systematic.
8638sleep 2
8639
8640# Expect no packets when hv2 bridge-mapping is not present
8641: > packets
8642OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8643
8644# Add bridge-mapping on hv2
f40c5588 8645AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
8646
8647# Wait for packets to be received.
8648OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8649trim_zeros() {
8650 sed 's/\(00\)\{1,\}$//'
8651}
8652$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8653expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8654echo $expected > expout
8655expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8656echo $expected >> expout
8657AT_CHECK([sort packets], [0], [expout])
f40c5588 8658sort packets | cat
26b9e08d 8659
f40c5588
MS
8660# Temporarily remove nat-addresses option to avoid race conditions
8661# due to GARP backoff
8662ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8663
8664reset_pcap_file() {
8665 local iface=$1
8666 local pcap_file=$2
8667 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8668options:rxq_pcap=dummy-rx.pcap
8669 rm -f ${pcap_file}*.pcap
8670 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8671options:rxq_pcap=${pcap_file}-rx.pcap
8672}
8673
8674as hv1 reset_pcap_file snoopvif hv1/snoopvif
8675
8676# Add OVS ports for foo1 and foo2 on hv3
8677ovs-vsctl -- add-port br-int hv3-vif1 -- \
8678 set interface hv3-vif1 external-ids:iface-id=foo1 \
8679 ofport-request=1
8680ovs-vsctl -- add-port br-int hv3-vif2 -- \
8681 set interface hv3-vif2 external-ids:iface-id=foo2 \
8682 ofport-request=2
8683
8684# Add bridge-mapping on hv3
8685AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8686
8687# Re-add nat-addresses option
8688ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8689
8690# Wait for packets to be received.
8691OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8692trim_zeros() {
8693 sed 's/\(00\)\{1,\}$//'
8694}
8695
8696$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8697expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8698echo $expected >> expout
8699expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8700echo $expected >> expout
8701AT_CHECK([sort packets], [0], [expout])
8702sort packets | cat
8703
8704OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
8705
8706AT_CLEANUP
6b785fd8 8707
85706c34
NS
8708# VLAN traffic for external network redirected through distributed router
8709# gateway port should use vlans(i.e input network vlan tag) across hypervisors
8710# instead of tunneling.
8711AT_SETUP([ovn -- vlan traffic for external network with distributed router gateway port])
8712AT_SKIP_IF([test $HAVE_PYTHON = no])
8713ovn_start
8714
8715# Logical network:
8716# # One LR R1 that has switches foo (192.168.1.0/24) and
8717# # alice (172.16.1.0/24) connected to it. The logical port
8718# # between R1 and alice has a "redirect-chassis" specified,
8719# # i.e. it is the distributed router gateway port(172.16.1.6).
8720# # Switch alice also has a localnet port defined.
8721# # An additional switch outside has the same subnet as alice
8722# # (172.16.1.0/24), a localnet port and nexthop port(172.16.1.1)
8723# # which will receive the packet destined for external network
8724# # (i.e 8.8.8.8 as destination ip).
8725
8726# Physical network:
8727# # Three hypervisors hv[123].
8728# # hv1 hosts vif foo1.
8729# # hv2 is the "redirect-chassis" that hosts the distributed router gateway port.
8730# # hv3 hosts nexthop port vif outside1.
8731# # All other tests connect hypervisors to network n1 through br-phys for tunneling.
8732# # But in this test, hv1 won't connect to n1(and no br-phys in hv1), and
8733# # in order to show vlans(instead of tunneling) used between hv1 and hv2,
8734# # a new network n2 created and hv1 and hv2 connected to this network through br-ex.
8735# # hv2 and hv3 are still connected to n1 network through br-phys.
8736net_add n1
8737
8738# We are not calling ovn_attach for hv1, to avoid adding br-phys.
8739# Tunneling won't work in hv1 as ovn-encap-ip is not added to any bridge in hv1
8740sim_add hv1
8741as hv1
8742ovs-vsctl \
8743 -- set Open_vSwitch . external-ids:system-id=hv1 \
8744 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
8745 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
8746 -- set Open_vSwitch . external-ids:ovn-encap-ip=192.168.0.1 \
8747 -- add-br br-int \
8748 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
8749 -- set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-ex
8750
8751start_daemon ovn-controller
8752ovs-vsctl -- add-port br-int hv1-vif1 -- \
8753 set interface hv1-vif1 external-ids:iface-id=foo1 \
8754 ofport-request=1
8755
8756sim_add hv2
8757as hv2
8758ovs-vsctl add-br br-phys
8759ovn_attach n1 br-phys 192.168.0.2
8760ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
8761
8762sim_add hv3
8763as hv3
8764ovs-vsctl add-br br-phys
8765ovn_attach n1 br-phys 192.168.0.3
8766ovs-vsctl -- add-port br-int hv3-vif1 -- \
8767 set interface hv3-vif1 external-ids:iface-id=outside1 \
8768 options:tx_pcap=hv3/vif1-tx.pcap \
8769 options:rxq_pcap=hv3/vif1-rx.pcap \
8770 ofport-request=1
8771ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="phys:br-phys"
8772
8773# Create network n2 for vlan connectivity between hv1 and hv2
8774net_add n2
8775
8776as hv1
8777ovs-vsctl add-br br-ex
8778net_attach n2 br-ex
8779
8780as hv2
8781ovs-vsctl add-br br-ex
8782net_attach n2 br-ex
8783
8784OVN_POPULATE_ARP
8785
8786ovn-nbctl create Logical_Router name=R1
8787
8788ovn-nbctl ls-add foo
8789ovn-nbctl ls-add alice
8790ovn-nbctl ls-add outside
8791
8792# Connect foo to R1
8793ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8794ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8795 type=router options:router-port=foo \
8796 -- lsp-set-addresses rp-foo router
8797
8798# Connect alice to R1 as distributed router gateway port (172.16.1.6) on hv2
8799ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.6/24 \
8800 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8801ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8802 type=router options:router-port=alice \
8803 -- lsp-set-addresses rp-alice router \
8804
8805# Create logical port foo1 in foo
8806ovn-nbctl lsp-add foo foo1 \
8807-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8808
8809# Create logical port outside1 in outside, which is a nexthop address
8810# for 172.16.1.0/24
8811ovn-nbctl lsp-add outside outside1 \
8812-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.1"
8813
8814# Set default gateway (nexthop) to 172.16.1.1
8815ovn-nbctl lr-route-add R1 "0.0.0.0/0" 172.16.1.1 alice
8816AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.6 192.168.1.1/24])
8817ovn-nbctl set Logical_Switch_Port rp-alice options:nat-addresses=router
8818
8819ovn-nbctl lsp-add foo ln-foo
8820ovn-nbctl lsp-set-addresses ln-foo unknown
8821ovn-nbctl lsp-set-options ln-foo network_name=public
8822ovn-nbctl lsp-set-type ln-foo localnet
8823AT_CHECK([ovn-nbctl set Logical_Switch_Port ln-foo tag=2])
8824
8825# Create localnet port in alice
8826ovn-nbctl lsp-add alice ln-alice
8827ovn-nbctl lsp-set-addresses ln-alice unknown
8828ovn-nbctl lsp-set-type ln-alice localnet
8829ovn-nbctl lsp-set-options ln-alice network_name=phys
8830
8831# Create localnet port in outside
8832ovn-nbctl lsp-add outside ln-outside
8833ovn-nbctl lsp-set-addresses ln-outside unknown
8834ovn-nbctl lsp-set-type ln-outside localnet
8835ovn-nbctl lsp-set-options ln-outside network_name=phys
8836
8837# Allow some time for ovn-northd and ovn-controller to catch up.
8838# XXX This should be more systematic.
8839ovn-nbctl --wait=hv --timeout=3 sync
8840
8841# Check that there is a logical flow in logical switch foo's pipeline
8842# to set the outport to rp-foo (which is expected).
8843OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
8844grep rp-foo | grep -v is_chassis_resident | wc -l`])
8845
8846# Set the option 'reside-on-redirect-chassis' for foo
8847ovn-nbctl set logical_router_port foo options:reside-on-redirect-chassis=true
8848# Check that there is a logical flow in logical switch foo's pipeline
8849# to set the outport to rp-foo with the condition is_chassis_redirect.
8850ovn-sbctl dump-flows foo
8851OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
8852grep rp-foo | grep is_chassis_resident | wc -l`])
8853
8854echo "---------NB dump-----"
8855ovn-nbctl show
8856echo "---------------------"
8857ovn-nbctl list logical_router
8858echo "---------------------"
8859ovn-nbctl list nat
8860echo "---------------------"
8861ovn-nbctl list logical_router_port
8862echo "---------------------"
8863
8864echo "---------SB dump-----"
8865ovn-sbctl list datapath_binding
8866echo "---------------------"
8867ovn-sbctl list port_binding
8868echo "---------------------"
8869ovn-sbctl dump-flows
8870echo "---------------------"
8871ovn-sbctl list chassis
8872echo "---------------------"
8873
8874for chassis in hv1 hv2 hv3; do
8875 as $chassis
8876 echo "------ $chassis dump ----------"
8877 ovs-vsctl show br-int
8878 ovs-ofctl show br-int
8879 ovs-ofctl dump-flows br-int
8880 echo "--------------------------"
8881done
8882
8883ip_to_hex() {
8884 printf "%02x%02x%02x%02x" "$@"
8885}
8886
8887foo1_ip=$(ip_to_hex 192 168 1 2)
8888gw_ip=$(ip_to_hex 172 16 1 6)
8889dst_ip=$(ip_to_hex 8 8 8 8)
8890nexthop_ip=$(ip_to_hex 172 16 1 1)
8891
8892foo1_mac="f00000010203"
8893foo_mac="000001010203"
8894gw_mac="000002010203"
8895nexthop_mac="f00000010204"
8896
8897# Send ip packet from foo1 to 8.8.8.8
8898src_mac="f00000010203"
8899dst_mac="000001010203"
8900packet=${foo_mac}${foo1_mac}08004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
8901
81e92852 8902# Wait for GARPs announcing gw IP to arrive
85706c34
NS
8903OVS_WAIT_UNTIL([
8904 test `as hv2 ovs-ofctl dump-flows br-int | grep table=66 | \
8905grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8906 ])
8907
8908# VLAN tagged packet with router port(192.168.1.1) MAC as destination MAC
8909# is expected on bridge connecting hv1 and hv2
8910expected=${foo_mac}${foo1_mac}8100000208004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
8911echo $expected > hv1-br-ex_n2.expected
8912
8913# Packet to Expect at outside1 i.e nexthop(172.16.1.1) port.
8914# As connection tracking not enabled for this test, snat can't be done on the packet.
8915# We still see foo1 as the source ip address. But source mac(gateway MAC) and
8916# dest mac(nexthop mac) are properly configured.
8917expected=${nexthop_mac}${gw_mac}08004500001c000000003f110100${foo1_ip}${dst_ip}0035111100080000
8918echo $expected > hv3-vif1.expected
8919
8920reset_pcap_file() {
8921 local iface=$1
8922 local pcap_file=$2
8923 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8924options:rxq_pcap=dummy-rx.pcap
8925 rm -f ${pcap_file}*.pcap
8926 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8927options:rxq_pcap=${pcap_file}-rx.pcap
8928}
8929
8930as hv1 reset_pcap_file br-ex_n2 hv1/br-ex_n2
8931as hv3 reset_pcap_file hv3-vif1 hv3/vif1
8932sleep 2
81e92852
DA
8933# Take note of how many packets arrived on the VLAN switch before generating
8934# further traffic
8e905f76 8935n_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
8936as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8937sleep 2
8938
8939# On hv1, the packet should not go from vlan switch pipleline to router
81e92852 8940# pipeline
85706c34 8941as hv1 ovs-ofctl dump-flows br-int
85706c34 8942AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep "priority=100,reg15=0x1,metadata=0x2" \
81e92852 8943| grep actions=clone | grep -v n_packets=$n_packets | wc -l], [0], [[0
85706c34
NS
8944]])
8945
8946# On hv1, table 32 check that no packet goes via the tunnel port
8947AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 \
8948| grep "NXM_NX_TUN_ID" | grep -v n_packets=0 | wc -l], [0], [[0
8949]])
8950
8951ip_packet() {
8952 grep "1010203f00000010203"
8953}
8954
8955# Check vlan tagged packet on the bridge connecting hv1 and hv2 with the
8956# foo1's mac.
8957$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-ex_n2-tx.pcap | ip_packet | uniq > hv1-br-ex_n2
8958cat hv1-br-ex_n2.expected > expout
8959AT_CHECK([sort hv1-br-ex_n2], [0], [expout])
8960
8961# Check expected packet on nexthop interface
8962$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/vif1-tx.pcap | grep ${foo1_ip}${dst_ip} | uniq > hv3-vif1
8963cat hv3-vif1.expected > expout
8964AT_CHECK([sort hv3-vif1], [0], [expout])
8965
8966OVN_CLEANUP([hv1],[hv2],[hv3])
8967AT_CLEANUP
8968
4364646c
ZKL
8969AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8970AT_KEYWORDS([ovn-nd_ra])
8971AT_SKIP_IF([test $HAVE_PYTHON = no])
8972ovn_start
8973
8974# In this test case we create 1 lswitch with 3 VIF ports attached,
8975# and a lrouter connected to the lswitch.
8976# We generate the Router solicitation packet and verify the Router Advertisement
8977# reply packet from the ovn-controller.
8978
8979# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8980# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8981# 'slaac' to allow lrp0 send RA for SLAAC mode.
8982ovn-nbctl ls-add lsw0
8983ovn-nbctl lr-add lr0
8984ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8985ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8986ovn-nbctl \
8987 -- lsp-add lsw0 lsp0 \
8988 -- set Logical_Switch_Port lsp0 type=router \
8989 options:router-port=lrp0 \
8990 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8991net_add n1
8992sim_add hv1
8993as hv1
8994ovs-vsctl add-br br-phys
8995ovn_attach n1 br-phys 192.168.0.2
8996
8997ovn-nbctl lsp-add lsw0 lp1
8998ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8999ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
9000
9001ovn-nbctl lsp-add lsw0 lp2
9002ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
9003ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
9004
9005ovn-nbctl lsp-add lsw0 lp3
9006ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
9007ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
9008
9009# Add ACL rule for ICMPv6 on lsw0
9010ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
9011ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
9012ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
9013ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
9014
9015ovs-vsctl -- add-port br-int hv1-vif1 -- \
9016 set interface hv1-vif1 external-ids:iface-id=lp1 \
9017 options:tx_pcap=hv1/vif1-tx.pcap \
9018 options:rxq_pcap=hv1/vif1-rx.pcap \
9019 ofport-request=1
9020
9021ovs-vsctl -- add-port br-int hv1-vif2 -- \
9022 set interface hv1-vif2 external-ids:iface-id=lp2 \
9023 options:tx_pcap=hv1/vif2-tx.pcap \
9024 options:rxq_pcap=hv1/vif2-rx.pcap \
9025 ofport-request=2
9026
9027ovs-vsctl -- add-port br-int hv1-vif3 -- \
9028 set interface hv1-vif3 external-ids:iface-id=lp3 \
9029 options:tx_pcap=hv1/vif3-tx.pcap \
9030 options:rxq_pcap=hv1/vif3-rx.pcap \
9031 ofport-request=3
9032
9033# Allow some time for ovn-northd and ovn-controller to catch up.
9034# XXX This should be more systematic.
9035sleep 1
9036
9037reset_pcap_file() {
9038 local iface=$1
9039 local pcap_file=$2
9040 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9041options:rxq_pcap=dummy-rx.pcap
9042 rm -f ${pcap_file}*.pcap
9043 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9044options:rxq_pcap=${pcap_file}-rx.pcap
9045}
9046
9047# Make sure that ovn-controller has installed the corresponding OF Flow.
9048OVS_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"`])
9049
9050# This shell function sends a Router Solicitation packet.
9051# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
9052test_ipv6_ra() {
9053 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
9054 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
9055
9056 local len=24
9057 local mtu_opt=""
9058 if test $mtu != 0; then
9059 len=`expr $len + 8`
9060 mtu_opt=05010000${mtu}
9061 fi
9062
9063 if test ${#prefix_opt} != 0; then
9064 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
9065 len=`expr $len + ${#prefix_opt} / 2`
9066 fi
9067
9068 len=$(printf "%x" $len)
9069 local lrp_mac=fa163e000001
9070 local lrp_lla=fe80000000000000f8163efffe000001
9071 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
9072 echo $reply >> $inport.expected
9073
9074 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
9075}
9076
9077AT_CAPTURE_FILE([ofctl_monitor0.log])
9078as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
9079--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
9080
9081# MTU is not set and the address mode is set to slaac
9082addr_mode=00
9083default_prefix_option_config=030440c0ffffffffffffffff00000000
9084src_mac=fa163e000002
9085src_lla=fe80000000000000f8163efffe000002
9086test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
9087
9088# NXT_RESUME should be 1.
9089OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9090
9091$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9092
9093cat 1.expected | cut -c -112 > expout
9094AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9095
9096# Skipping the ICMPv6 checksum.
9097cat 1.expected | cut -c 117- > expout
9098AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9099
9100rm -f *.expected
9101reset_pcap_file hv1-vif1 hv1/vif1
9102reset_pcap_file hv1-vif2 hv1/vif2
9103reset_pcap_file hv1-vif3 hv1/vif3
9104
9105# Set the MTU to 1500
9106ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
9107
9108# Make sure that ovn-controller has installed the corresponding OF Flow.
9109OVS_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"`])
9110
9111addr_mode=00
9112default_prefix_option_config=030440c0ffffffffffffffff00000000
9113src_mac=fa163e000003
9114src_lla=fe80000000000000f8163efffe000003
9115mtu=000005dc
9116
9117test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9118
9119# NXT_RESUME should be 2.
9120OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9121
9122$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
9123
9124cat 2.expected | cut -c -112 > expout
9125AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9126
9127# Skipping the ICMPv6 checksum.
9128cat 2.expected | cut -c 117- > expout
9129AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9130
9131rm -f *.expected
9132reset_pcap_file hv1-vif1 hv1/vif1
9133reset_pcap_file hv1-vif2 hv1/vif2
9134reset_pcap_file hv1-vif3 hv1/vif3
9135
9136# Set the address mode to dhcpv6_stateful
9137ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
9138# Make sure that ovn-controller has installed the corresponding OF Flow.
9139OVS_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"`])
9140
9141addr_mode=80
9142default_prefix_option_config=""
9143src_mac=fa163e000004
9144src_lla=fe80000000000000f8163efffe000004
9145mtu=000005dc
9146
9147test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9148
9149# NXT_RESUME should be 3.
9150OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9151
9152$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
9153
9154cat 3.expected | cut -c -112 > expout
9155AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
9156
9157# Skipping the ICMPv6 checksum.
9158cat 3.expected | cut -c 117- > expout
9159AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
9160
9161rm -f *.expected
9162reset_pcap_file hv1-vif1 hv1/vif1
9163reset_pcap_file hv1-vif2 hv1/vif2
9164reset_pcap_file hv1-vif3 hv1/vif3
9165
9166# Set the address mode to dhcpv6_stateless
9167ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
9168# Make sure that ovn-controller has installed the corresponding OF Flow.
9169OVS_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"`])
9170
9171addr_mode=40
9172default_prefix_option_config=030440c0ffffffffffffffff00000000
9173src_mac=fa163e000002
9174src_lla=fe80000000000000f8163efffe000002
9175mtu=000005dc
9176
9177test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9178
9179# NXT_RESUME should be 4.
9180OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9181
9182$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9183
9184cat 1.expected | cut -c -112 > expout
9185AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9186
9187# Skipping the ICMPv6 checksum.
9188cat 1.expected | cut -c 117- > expout
9189AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9190
9191rm -f *.expected
9192reset_pcap_file hv1-vif1 hv1/vif1
9193reset_pcap_file hv1-vif2 hv1/vif2
9194reset_pcap_file hv1-vif3 hv1/vif3
9195
9196# Set the address mode to invalid.
9197ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
9198# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
9199OVS_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"`])
9200
9201addr_mode=40
9202default_prefix_option_config=""
9203src_mac=fa163e000002
9204src_lla=fe80000000000000f8163efffe000002
9205mtu=000005dc
9206
9207test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9208
9209# NXT_RESUME should be 4 only.
9210OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9211
9212$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9213AT_CHECK([cat 1.packets], [0], [])
9214
9215OVN_CLEANUP([hv1])
9216AT_CLEANUP
9217
6b785fd8
GS
9218AT_SETUP([ovn -- /32 router IP address])
9219AT_SKIP_IF([test $HAVE_PYTHON = no])
9220ovn_start
9221
9222# Logical network:
9223# 2 LS 'foo' and 'alice' connected via router R1.
9224# R1 connects to 'alice' with a /32 IP address. We use static routes and
9225# nexthop to push traffic to a logical port in switch 'alice'
9226
9227ovn-nbctl lr-add R1
9228
9229ovn-nbctl ls-add foo
9230ovn-nbctl ls-add alice
9231
9232# Connect foo to R1
9233ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
9234ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
9235 options:router-port=foo addresses=\"00:00:00:01:02:03\"
9236
9237# Connect alice to R1.
9238ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
9239ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9240 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
9241
9242# Create logical port foo1 in foo
9243ovn-nbctl lsp-add foo foo1 \
9244-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9245
9246# Create logical port alice1 in alice
9247ovn-nbctl lsp-add alice alice1 \
9248-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
9249
9250#install default route in R1 to use alice1's IP address as nexthop
9251ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
9252
9253# Create two hypervisor and create OVS ports corresponding to logical ports.
9254net_add n1
9255
9256sim_add hv1
9257as hv1
9258ovs-vsctl add-br br-phys
9259ovn_attach n1 br-phys 192.168.0.1
9260ovs-vsctl -- add-port br-int hv1-vif1 -- \
9261 set interface hv1-vif1 external-ids:iface-id=foo1 \
9262 options:tx_pcap=hv1/vif1-tx.pcap \
9263 options:rxq_pcap=hv1/vif1-rx.pcap \
9264 ofport-request=1
9265
9266sim_add hv2
9267as hv2
9268ovs-vsctl add-br br-phys
9269ovn_attach n1 br-phys 192.168.0.2
9270ovs-vsctl -- add-port br-int hv2-vif1 -- \
9271 set interface hv2-vif1 external-ids:iface-id=alice1 \
9272 options:tx_pcap=hv2/vif1-tx.pcap \
9273 options:rxq_pcap=hv2/vif1-rx.pcap \
9274 ofport-request=1
9275
9276
9277# Pre-populate the hypervisors' ARP tables so that we don't lose any
9278# packets for ARP resolution (native tunneling doesn't queue packets
9279# for ARP resolution).
74868f2c 9280OVN_POPULATE_ARP
6b785fd8
GS
9281
9282# Allow some time for ovn-northd and ovn-controller to catch up.
9283# XXX This should be more systematic.
9284sleep 1
9285
9286ip_to_hex() {
9287 printf "%02x%02x%02x%02x" "$@"
9288}
9289
9290# Send ip packets between foo1 and alice1
9291src_mac="f00000010203"
9292dst_mac="000000010203"
9293src_ip=`ip_to_hex 192 168 1 2`
9294dst_ip=`ip_to_hex 10 0 0 2`
9295packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9296
9297# Send the first packet to trigger a ARP response and population of
9298# mac_bindings table.
9299as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9300OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
b0b27a83 9301ovn-nbctl --wait=hv sync
6b785fd8
GS
9302
9303# Packet to Expect at 'alice1'
9304src_mac="000000010204"
9305dst_mac="f00000010204"
9306src_ip=`ip_to_hex 192 168 1 2`
9307dst_ip=`ip_to_hex 10 0 0 2`
9308echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
9309
9310OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
9311
9312OVN_CLEANUP([hv1],[hv2])
9313
9314AT_CLEANUP
2a38ef45
DA
9315
9316AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
9317AT_SKIP_IF([test $HAVE_PYTHON = no])
9318ovn_start
9319
9320ovn-nbctl ls-add ls1
9321
9322# Add localport to the switch
9323ovn-nbctl lsp-add ls1 lp01
9324ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
9325ovn-nbctl lsp-set-type lp01 localport
9326
9327net_add n1
9328
9329for i in 1 2; do
9330 sim_add hv$i
9331 as hv$i
9332 ovs-vsctl add-br br-phys
9333 ovn_attach n1 br-phys 192.168.0.$i
9334 ovs-vsctl add-port br-int vif01 -- \
9335 set Interface vif01 external-ids:iface-id=lp01 \
9336 options:tx_pcap=hv${i}/vif01-tx.pcap \
9337 options:rxq_pcap=hv${i}/vif01-rx.pcap \
9338 ofport-request=${i}0
9339
9340 ovs-vsctl add-port br-int vif${i}1 -- \
9341 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
9342 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
9343 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
9344 ofport-request=${i}1
9345
9346 ovn-nbctl lsp-add ls1 lp${i}1
9347 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
9348 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
9349
9350 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
9351done
9352
9353ovn-nbctl --wait=sb sync
9354ovn-sbctl dump-flows
9355
74868f2c 9356OVN_POPULATE_ARP
2a38ef45
DA
9357
9358# Given the name of a logical port, prints the name of the hypervisor
9359# on which it is located.
9360vif_to_hv() {
9361 echo hv${1%?}
9362}
9363#
9364# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
9365#
9366# This shell function causes a packet to be received on INPORT. The packet's
9367# content has Ethernet destination DST and source SRC (each exactly 12 hex
9368# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
9369# logical switch port numbers, e.g. 11 for vif11.
9370#
9371# EOUT is the end-to-end output port, that is, where the packet will end up
9372# after possibly bouncing through one or more localnet ports. LOUT is the
9373# logical output port, which might be a localnet port, as seen by ovn-trace
9374# (which doesn't know what localnet ports are connected to and therefore can't
9375# figure out the end-to-end answer).
9376#
9377# DEFHV is the default hypervisor from where the packet is going to be sent
9378# if the source port is a localport.
9379for i in 1 2; do
9380 for j in 0 1; do
9381 : > $i$j.expected
9382 done
9383done
9384test_packet() {
9385 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
9386 echo "$@"
9387
9388 # First try tracing the packet.
9389 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
9390 if test $lout != drop; then
9391 echo "output(\"$lout\");"
9392 fi > expout
9393 AT_CAPTURE_FILE([trace])
9394 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
9395
9396 # Then actually send a packet, for an end-to-end test.
9397 local packet=$(echo $dst$src | sed 's/://g')${eth}
9398 hv=`vif_to_hv $inport`
9399 # If hypervisor 0 (localport) use the defhv parameter
da88b550 9400 if test $hv = hv0; then
2a38ef45
DA
9401 hv=$defhv
9402 fi
9403 vif=vif$inport
9404 as $hv ovs-appctl netdev-dummy/receive $vif $packet
9405 if test $eout != drop; then
9406 echo $packet >> ${eout#lp}.expected
9407 fi
9408}
9409
9410
9411# lp11 and lp21 are on different hypervisors
9412test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
9413test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
9414
9415# Both VIFs should be able to reach the localport on their own HV
9416test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
9417test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
9418
9419# Packet sent from localport on same hv should reach the vif
9420test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
9421test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
9422
9423# Packet sent from localport on different hv should be dropped
9424test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
9425test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
9426
9427# Now check the packets actually received against the ones expected.
9428for i in 1 2; do
9429 for j in 0 1; do
9430 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
9431 done
9432done
9433
9434OVN_CLEANUP([hv1],[hv2])
9435
9436AT_CLEANUP
1da17a0b 9437
9438AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
9439AT_SKIP_IF([test $HAVE_PYTHON = no])
9440ovn_start
9441
9442net_add n1
9443
9444# create gateways with external network connectivity
9445
9446for i in 1 2; do
9447 sim_add gw$i
9448 as gw$i
9449 ovs-vsctl add-br br-phys
9450 ovn_attach n1 br-phys 192.168.0.$i
9451 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9452done
9453
9454ovn-nbctl ls-add inside
9455ovn-nbctl ls-add outside
9456
9457# create hypervisors with a vif port each to an internal network
9458
9459for i in 1 2; do
9460 sim_add hv$i
9461 as hv$i
9462 ovs-vsctl add-br br-phys
9463 ovn_attach n1 br-phys 192.168.0.1$i
9464 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9465 set interface hv$i-vif1 external-ids:iface-id=inside$i \
9466 options:tx_pcap=hv$i/vif1-tx.pcap \
9467 options:rxq_pcap=hv$i/vif1-rx.pcap \
9468 ofport-request=1
9469
9470 ovn-nbctl lsp-add inside inside$i \
9471 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
9472
9473done
9474
74868f2c 9475OVN_POPULATE_ARP
1da17a0b 9476
9477ovn-nbctl create Logical_Router name=R1
9478
9479# Connect inside to R1
9480ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9481ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9482 type=router options:router-port=inside \
9483 -- lsp-set-addresses rp-inside router
9484
9485# Connect outside to R1 as distributed router gateway port on gw1+gw2
9486ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9487
9488ovn-nbctl --id=@gc0 create Gateway_Chassis \
9489 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9490 --id=@gc1 create Gateway_Chassis \
9491 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9492 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9493
9494ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9495 type=router options:router-port=outside \
9496 -- lsp-set-addresses rp-outside router
9497
9498# Create localnet port in outside
9499ovn-nbctl lsp-add outside ln-outside
9500ovn-nbctl lsp-set-addresses ln-outside unknown
9501ovn-nbctl lsp-set-type ln-outside localnet
9502ovn-nbctl lsp-set-options ln-outside network_name=phys
9503
9504# Allow some time for ovn-northd and ovn-controller to catch up.
9505# XXX This should be more systematic.
8e1d9349 9506ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 9507
9508echo "---------NB dump-----"
9509ovn-nbctl show
9510echo "---------------------"
9511ovn-nbctl list logical_router
9512echo "---------------------"
9513ovn-nbctl list logical_router_port
9514echo "---------------------"
9515
9516echo "---------SB dump-----"
9517ovn-sbctl list datapath_binding
9518echo "---------------------"
9519ovn-sbctl list port_binding
9520echo "---------------------"
9521ovn-sbctl dump-flows
9522echo "---------------------"
9523ovn-sbctl list chassis
9524ovn-sbctl list encap
9525echo "---------------------"
9526echo "------ Gateway_Chassis dump (SBDB) -------"
9527ovn-sbctl list Gateway_Chassis
9528echo "------ Port_Binding chassisredirect -------"
9529ovn-sbctl find Port_Binding type=chassisredirect
9530echo "-------------------------------------------"
9531
3475695e
VA
9532for chassis in gw1 gw2 hv1 hv2; do
9533 as $chassis
9534 echo "------ $chassis dump ----------"
9535 ovs-ofctl show br-int
9536 ovs-ofctl dump-flows br-int
3475695e
VA
9537 echo "--------------------------"
9538done
20be3a72 9539bfd_dump() {
508b7f96 9540 for chassis in gw1 gw2 hv1 hv2; do
9541 as $chassis
9542 echo "------ $chassis dump (BFD)----"
9543 echo "BFD (from $chassis):"
9544 # dump BFD config and status to the other chassis
9545 for chassis2 in gw1 gw2 hv1 hv2; do
9546 if [[ "$chassis" != "$chassis2" ]]; then
9547 echo " -> $chassis2:"
9548 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
9549 fi
9550 done
9551 echo "--------------------------"
9552 done
9553}
9554
9555bfd_dump
1da17a0b 9556
9557hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9558hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9559hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9560hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9561
9562echo $hv1_gw1_ofport
9563echo $hv1_gw2_ofport
9564echo $hv2_gw1_ofport
9565echo $hv2_gw2_ofport
9566
9567echo "--- hv1 ---"
9568as hv1 ovs-ofctl dump-flows br-int table=32
9569
9570echo "--- hv2 ---"
9571as hv2 ovs-ofctl dump-flows br-int table=32
9572
508b7f96 9573gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
9574gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9575
1da17a0b 9576AT_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
9577])
9578
9579AT_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
9580])
9581
508b7f96 9582sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9583
9584# make sure that flows for handling the outside router port reside on gw1
66d89287 9585AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9586]])
66d89287 9587AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9588]])
9589
9590# make sure ARP responder flows for outside router port reside on gw1 too
9591AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
9592]])
9593AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
9594]])
9595
9596
9597
9598# check that the chassis redirect port has been claimed by the gw1 chassis
9599AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9600 [0],[[1
9601]])
9602
9603
9604# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 9605
9606ovn-nbctl --id=@gc0 create Gateway_Chassis \
9607 name=outside_gw1 chassis_name=gw1 priority=10 -- \
9608 --id=@gc1 create Gateway_Chassis \
9609 name=outside_gw2 chassis_name=gw2 priority=20 -- \
9610 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9611
508b7f96 9612
1da17a0b 9613# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 9614ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 9615
508b7f96 9616# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 9617AT_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
9618])
9619
9620AT_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
9621])
9622
508b7f96 9623# check that the chassis redirect port has been reclaimed by the gw2 chassis
9624AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
9625 [0],[[1
9626]])
1da17a0b 9627
3475695e
VA
9628# check BFD enablement on tunnel ports from gw1 #########
9629as gw1
9630for chassis in gw2 hv1 hv2; do
9631 echo "checking gw1 -> $chassis"
9632 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9633 [[enable=true
9634]])
9635done
9636
9637
9638# check BFD enablement on tunnel ports from gw2 ##########
9639as gw2
9640for chassis in gw1 hv1 hv2; do
9641 echo "checking gw2 -> $chassis"
9642 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9643 [[enable=true
9644]])
9645done
9646
9647# check BFD enablement on tunnel ports from hv1 ###########
9648as hv1
9649for chassis in gw1 gw2; do
9650 echo "checking hv1 -> $chassis"
9651 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9652 [[enable=true
9653]])
9654done
9655# make sure BFD is not enabled to hv2, we don't need it
9656AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
2d661a27 9657 [[
3475695e
VA
9658]])
9659
9660
9661# check BFD enablement on tunnel ports from hv2 ##########
9662as hv2
9663for chassis in gw1 gw2; do
9664 echo "checking hv2 -> $chassis"
9665 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9666 [[enable=true
9667]])
9668done
9669# make sure BFD is not enabled to hv1, we don't need it
9670AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
2d661a27 9671 [[
3475695e
VA
9672]])
9673
508b7f96 9674sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9675
9676# make sure that flows for handling the outside router port reside on gw2 now
66d89287 9677AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9678]])
66d89287 9679AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9680]])
9681
9682# disconnect GW2 from the network, GW1 should take over
9683as gw2
9684port=${sandbox}_br-phys
9685as main ovs-vsctl del-port n1 $port
9686sleep 4
9687
9688bfd_dump
9689
9690# make sure that flows for handling the outside router port reside on gw2 now
66d89287 9691AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9692]])
66d89287 9693AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9694]])
9695
9696# check that the chassis redirect port has been reclaimed by the gw1 chassis
9697AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9698 [0],[[1
9699]])
9700
2d661a27
NS
9701ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
9702as gw2
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_rx=2000"
9708])
9709done
9710ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
9711for chassis in gw1 hv1 hv2; do
9712 echo "checking gw2 -> $chassis"
9713 OVS_WAIT_UNTIL([
9714 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9715 test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
9716])
9717done
9718ovn-nbctl remove NB_Global . options "bfd-min-rx"
9719ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
9720for chassis in gw1 hv1 hv2; do
9721 echo "checking gw2 -> $chassis"
9722 OVS_WAIT_UNTIL([
9723 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9724 test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
9725])
9726done
9727
1da17a0b 9728OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
9729
9730AT_CLEANUP
acfc41ff
VAK
9731
9732AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
9733AT_SKIP_IF([test $HAVE_PYTHON = no])
9734ovn_start
9735ovn-nbctl ls-add ls0
9736ovn-nbctl ls-add ls1
9737ovn-nbctl create Logical_Router name=lr0
9738ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
9739
9740ovn-nbctl --id=@gc0 create Gateway_Chassis \
9741 name=outside_gw1 chassis_name=hv2 priority=10 -- \
9742 --id=@gc1 create Gateway_Chassis \
9743 name=outside_gw2 chassis_name=hv3 priority=1 -- \
9744 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9745
9746ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9747 type=router options:router-port=lrp0 addresses="router"
9748ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9749ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9750 type=router options:router-port=lrp1 addresses="router"
9751
9752# Add NAT rules
9753AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
9754
9755net_add n1
9756sim_add hv1
9757as hv1
9758ovs-vsctl add-br br-phys
9759ovn_attach n1 br-phys 192.168.0.1
9760AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9761AT_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])
9762
9763sim_add hv2
9764as hv2
9765ovs-vsctl add-br br-phys
9766ovn_attach n1 br-phys 192.168.0.2
9767AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9768
9769sim_add hv3
9770as hv3
9771ovs-vsctl add-br br-phys
9772ovn_attach n1 br-phys 192.168.0.3
9773AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9774
9775# Create a localnet port.
9776AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9777AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9778AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9779AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
9780
9781# wait for earlier changes to take effect
6c8d3d69 9782AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
acfc41ff
VAK
9783
9784reset_pcap_file() {
9785 local iface=$1
9786 local pcap_file=$2
9787 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9788options:rxq_pcap=dummy-rx.pcap
9789 rm -f ${pcap_file}*.pcap
9790 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9791options:rxq_pcap=${pcap_file}-rx.pcap
9792}
9793
9794as hv1 reset_pcap_file snoopvif hv1/snoopvif
9795as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9796as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9797# add nat-addresses option
6c8d3d69 9798ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
acfc41ff
VAK
9799
9800# Wait for packets to be received through hv2.
9801OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9802trim_zeros() {
9803 sed 's/\(00\)\{1,\}$//'
9804}
9805
2db7bb2c 9806only_broadcast_from_lrp1() {
9807 grep "fffffffffffff00000000001"
9808}
9809
acfc41ff 9810garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 9811echo $garp > expout
9812
9813$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
9814echo "packets on hv1-snoopvif:"
9815cat hv1_snoop_tx
9816AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 9817$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
9818echo "packets on hv2 br-phys tx"
9819cat hv2_br_phys_tx
9820AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 9821$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
9822echo "packets on hv3 br-phys tx"
9823cat hv3_br_phys_tx
9824AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9825
9826
9827# at this point, we invert the priority of the gw chassis between hv2 and hv3
9828
9829ovn-nbctl --wait=hv \
9830 --id=@gc0 create Gateway_Chassis \
9831 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9832 --id=@gc1 create Gateway_Chassis \
9833 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9834 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9835
9836
9837as hv1 reset_pcap_file snoopvif hv1/snoopvif
9838as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9839as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9840
9841# Wait for packets to be received.
9842OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9843trim_zeros() {
9844 sed 's/\(00\)\{1,\}$//'
9845}
9846
2db7bb2c 9847$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 9848AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 9849$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 9850AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 9851$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 9852AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
9853
9854# change localnet port tag.
9855AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9856
9857# wait for earlier changes to take effect
6c8d3d69 9858AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
03b85a58
GL
9859
9860# update nat-addresses option
6c8d3d69
HZ
9861ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9862ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
03b85a58
GL
9863
9864as hv1 reset_pcap_file snoopvif hv1/snoopvif
9865as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9866as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9867
9868# Wait for packets to be received.
9869OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9870trim_zeros() {
9871 sed 's/\(00\)\{1,\}$//'
9872}
9873
9874garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9875echo $garp > expout
9876
9877$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9878AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9879$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9880AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9881$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9882AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9883
acfc41ff
VAK
9884OVN_CLEANUP([hv1],[hv2],[hv3])
9885
9886AT_CLEANUP
79371ff5 9887
9888AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9889AT_SKIP_IF([test $HAVE_PYTHON = no])
9890ovn_start
9891
9892net_add n1
9893
9894# create two gateways with external network connectivity
9895for i in 1 2; do
9896 sim_add gw$i
9897 as gw$i
9898 ovs-vsctl add-br br-phys
9899 ovn_attach n1 br-phys 192.168.0.$i
9900 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9901done
9902
9903ovn-nbctl ls-add inside
9904ovn-nbctl ls-add outside
9905
9906# create one hypervisors with a vif port the internal network
9907sim_add hv1
9908as hv1
9909ovs-vsctl add-br br-phys
9910ovn_attach n1 br-phys 192.168.0.11
9911ovs-vsctl -- add-port br-int hv1-vif1 -- \
9912 set interface hv1-vif1 external-ids:iface-id=inside1 \
9913 options:tx_pcap=hv1/vif1-tx.pcap \
9914 options:rxq_pcap=hv1/vif1-rx.pcap \
9915 ofport-request=1
9916
9917ovn-nbctl lsp-add inside inside1 \
9918 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9919
9920
74868f2c 9921OVN_POPULATE_ARP
79371ff5 9922
9923ovn-nbctl create Logical_Router name=R1
9924
9925# Connect inside to R1
9926ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9927ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9928 type=router options:router-port=inside \
9929 -- lsp-set-addresses rp-inside router
9930
9931# Connect outside to R1 as distributed router gateway port on gw1+gw2
9932ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9933
9934ovn-nbctl --id=@gc0 create Gateway_Chassis \
9935 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9936 --id=@gc1 create Gateway_Chassis \
9937 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9938 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9939
9940ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9941 type=router options:router-port=outside \
9942 -- lsp-set-addresses rp-outside router
9943
9944# Create localnet port in outside
9945ovn-nbctl lsp-add outside ln-outside
9946ovn-nbctl lsp-set-addresses ln-outside unknown
9947ovn-nbctl lsp-set-type ln-outside localnet
9948ovn-nbctl lsp-set-options ln-outside network_name=phys
9949
9950# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 9951ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 9952
9953# currently when ovn-controller is restarted, the old entry is deleted
9954# and a new one is created, which leaves the Gateway_Chassis with
9955# an empty chassis for a while. NOTE: restarting ovn-controller in tests
9956# doesn't have the same effect because "name" is conserved, and the
9957# Chassis entry is not replaced.
9958
3a0c5805 9959> gw1/ovn-controller.log
325b2b1a 9960
79371ff5 9961gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9962ovn-sbctl destroy Chassis $gw2_chassis
9963
9964# Ensure ovn-controller has processed latest sbdb update
9965# ovn-nbctl --wait=hv sync
9966
9967AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9968
9969OVN_CLEANUP([gw1],[gw2],[hv1])
9970
9971AT_CLEANUP
63d91afa 9972
b1a3a6a4
NS
9973AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9974AT_KEYWORDS([ovn-nd_ns for unknown mac])
9975AT_SKIP_IF([test $HAVE_PYTHON = no])
9976ovn_start
9977
9978ovn-nbctl ls-add sw0_ip6
9979ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9980ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9981"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9982
9983ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9984"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9985
9986ovn-nbctl lr-add lr0_ip6
847dc1c2 9987ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
9988ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9989ovn-nbctl lsp-set-type lrp0_ip6-attachment router
bec7c641 9990ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
b1a3a6a4
NS
9991ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9992ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9993
9994ovn-nbctl ls-add public
9995ovn-nbctl lsp-add public ln-public
9996ovn-nbctl lsp-set-addresses ln-public unknown
9997ovn-nbctl lsp-set-type ln-public localnet
9998ovn-nbctl lsp-set-options ln-public network_name=phys
9999
10000ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
100012001:db8:1:0:200:02ff:fe01:0204/64 \
10002-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
10003
250ed434
NS
10004#install static route
10005ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
10006ip_prefix="\:\:/0" nexthop="2001\:db8\:1\:0\:200\:02ff\:fe01\:1305" \
10007-- add Logical_Router lr0_ip6 static_routes @lrt
b1a3a6a4
NS
10008
10009ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
10010rp-ip6_public type=router options:router-port=ip6_public \
10011-- lsp-set-addresses rp-ip6_public router
10012
10013net_add n1
10014sim_add hv1
10015as hv1
10016ovs-vsctl add-br br-phys
10017ovn_attach n1 br-phys 192.168.0.2
10018
10019ovs-vsctl -- add-port br-int hv1-vif1 -- \
10020 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
10021 options:tx_pcap=hv1/vif1-tx.pcap \
10022 options:rxq_pcap=hv1/vif1-rx.pcap \
10023 ofport-request=1
10024ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10025
86c9d79a 10026OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
bec7c641
NS
10027
10028# There should be 2 Neighbor Advertisement flows for the router port
10029# aef0:: ip address in logical switch pipeline with action nd_na_router.
10030AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
10031grep "nd_na_router" | wc -l], [0], [2
10032])
10033
10034# There should be 4 Neighbor Advertisement flows with action nd_na_router
10035# in the router pipeline for the router lr0_ip6.
10036AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
10037wc -l], [0], [4
10038])
10039
86c9d79a
NS
10040cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
10041
10042# There is only one chassis.
10043chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
10044OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
b1a3a6a4
NS
10045
10046trim_zeros() {
10047 sed 's/\(00\)\{1,\}$//'
10048}
10049
250ed434
NS
10050reset_pcap_file() {
10051 local iface=$1
10052 local pcap_file=$2
10053 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10054options:rxq_pcap=dummy-rx.pcap
10055 rm -f ${pcap_file}*.pcap
10056 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10057options:rxq_pcap=${pcap_file}-rx.pcap
10058}
10059
b1a3a6a4
NS
10060# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
10061# addresses. ovn-controller should generate an IPv6 NS request for IPv6
10062# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
10063# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10064# This function sends ipv6 packet
10065test_ipv6() {
250ed434
NS
10066 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10067 local dst_mcast_mac=$6 mcast_node_ip=$7 nd_target=$8
b1a3a6a4
NS
10068
10069 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
10070 packet=${packet}8000000000000000
b1a3a6a4 10071
b1a3a6a4 10072 src_mac=000002010204
250ed434
NS
10073 expected_packet=${dst_mcast_mac}${src_mac}86dd6000000000203aff${src_ip}
10074 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000
10075 expected_packet=${expected_packet}${nd_target}0101${src_mac}
b1a3a6a4
NS
10076
10077 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
250ed434 10078 rm -f ipv6_ns.expected
b1a3a6a4
NS
10079 echo $expected_packet >> ipv6_ns.expected
10080}
10081
10082src_mac=506400000002
10083dst_mac=00000000af01
10084src_ip=aef0000000000000526400fffe000002
250ed434
NS
10085dst_ip=20010db800010000020002fffe010205
10086dst_mcast_mac=3333ff010205
10087mcast_node_ip=ff0200000000000000000001ff010205
10088nd_target=20010db800010000020002fffe010205
b1a3a6a4
NS
10089# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
10090# should be received by the ports attached to br-phys.
250ed434
NS
10091test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
10092$mcast_node_ip $nd_target
10093
10094OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
10095OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
10096
10097$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
10098trim_zeros > 1.packets
10099$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
10100trim_zeros > 2.packets
10101
10102cat ipv6_ns.expected | cut -c -112 > expout
10103AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
10104AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
10105
10106# Skipping the ICMPv6 checksum
10107cat ipv6_ns.expected | cut -c 117- > expout
10108AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
10109AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
10110
10111# Now send a packet with destination ip other than
10112# 2001:db8:1:0:200:02ff:fe01:0204/64 prefix.
10113reset_pcap_file br-phys_n1 hv1/br-phys_n1
10114reset_pcap_file br-phys hv1/br-phys
10115
10116src_mac=506400000002
10117dst_mac=00000000af01
10118src_ip=aef0000000000000526400fffe000002
10119dst_ip=20020ab8000100000200020000020306
10120# multicast mac of the nexthop IP - 2001:db8:1:0:200:02ff:fe01:1305
10121dst_mcast_mac=3333ff011305
10122mcast_node_ip=ff0200000000000000000001ff011305
10123nd_target=20010db800010000020002fffe011305
10124test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
10125$mcast_node_ip $nd_target
b1a3a6a4 10126
86c9d79a
NS
10127OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
10128OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
10129
b1a3a6a4
NS
10130$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
10131trim_zeros > 1.packets
10132$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
10133trim_zeros > 2.packets
10134
10135cat ipv6_ns.expected | cut -c -112 > expout
10136AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
10137AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
10138
10139# Skipping the ICMPv6 checksum
10140cat ipv6_ns.expected | cut -c 117- > expout
10141AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
10142AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
10143
10144OVN_CLEANUP([hv1])
10145
10146AT_CLEANUP
10147
63d91afa
LR
10148AT_SETUP([ovn -- options:requested-chassis for logical port])
10149ovn_start
10150
10151net_add n1
10152
10153ovn-nbctl ls-add ls0
10154ovn-nbctl lsp-add ls0 lsp0
10155
10156# create two hypervisors, each with one vif port
10157sim_add hv1
10158as hv1
10159ovs-vsctl add-br br-phys
10160ovn_attach n1 br-phys 192.168.0.11
99cc5c92
NS
10161ovs-vsctl -- add-port br-int hv1-vif0 -- \
10162set Interface hv1-vif0 ofport-request=1
63d91afa
LR
10163
10164sim_add hv2
10165as hv2
10166ovs-vsctl add-br br-phys
10167ovn_attach n1 br-phys 192.168.0.12
99cc5c92
NS
10168ovs-vsctl -- add-port br-int hv2-vif0 -- \
10169set Interface hv2-vif0 ofport-request=1
63d91afa
LR
10170
10171# Allow only chassis hv1 to bind logical port lsp0.
10172ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
10173
10174# Allow some time for ovn-northd and ovn-controller to catch up.
10175ovn-nbctl --wait=hv --timeout=3 sync
10176
10177# Retrieve hv1 and hv2 chassis UUIDs from southbound database
2aa57f08
HZ
10178ovn-sbctl wait-until chassis hv1
10179ovn-sbctl wait-until chassis hv2
63d91afa
LR
10180hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
10181hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
10182
10183# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
10184echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
10185as hv2
10186ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
10187
10188OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
10189AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
10190
99cc5c92
NS
10191# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
10192AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
10193AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
10194
10195# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
63d91afa
LR
10196echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
10197as hv1
10198ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
10199
10200OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
2aa57f08 10201AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
63d91afa 10202
99cc5c92
NS
10203# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
10204as hv1 ovs-ofctl dump-flows br-int
10205AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
10206AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
10207
10208# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
63d91afa
LR
10209# the requested chassis for lsp0 is changed from hv1 to hv2.
10210echo "verifying that lsp0 binding moves when requested-chassis is changed"
10211
10212ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
10213OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
2aa57f08 10214OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
63d91afa 10215
99cc5c92
NS
10216# (6) Chassis hv2 should add flows and hv1 should not.
10217AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
10218AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
10219
10220AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
10221AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
10222
63d91afa
LR
10223OVN_CLEANUP([hv1],[hv2])
10224
10225AT_CLEANUP
bd32425f
RB
10226
10227AT_SETUP([ovn -- options:requested-chassis with hostname])
10228
10229ovn_start
10230
10231ovn-nbctl ls-add ls0
10232ovn-nbctl lsp-add ls0 lsp0
10233
10234net_add n1
10235sim_add hv1
10236as hv1
10237ovs-vsctl add-br br-phys
10238ovn_attach n1 br-phys 192.168.0.11
99cc5c92 10239ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
bd32425f 10240
362ab40a 10241ovn-sbctl wait-until chassis hv1
bd32425f
RB
10242hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
10243echo "hv1_hostname=${hv1_hostname}"
10244ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
10245as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
10246
10247hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
10248echo "hv1_uuid=${hv1_uuid}"
10249OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
10250AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
99cc5c92
NS
10251AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
10252AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
bd32425f
RB
10253
10254ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
10255OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
10256ovn-nbctl --wait=hv --timeout=3 sync
10257AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
99cc5c92
NS
10258AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
10259AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
bd32425f
RB
10260
10261OVN_CLEANUP([hv1])
10262
10263AT_CLEANUP
4446661a
MM
10264
10265AT_SETUP([ovn -- IPv6 periodic RA])
10266ovn_start
10267
10268# This test sets up two hypervisors.
10269# hv1 and hv2 run ovn-controllers, and
10270# each has a VIF connected to the same
10271# logical switch in OVN. The logical
10272# switch is connected to a logical
10273# router port that is configured to send
10274# periodic router advertisements.
10275#
10276# The reason for having two ovn-controller
10277# hypervisors is to ensure that the
10278# periodic RAs being sent by each ovn-controller
10279# are kept to their local hypervisors. If the
10280# packets are not kept local, then each port
10281# will receive too many RAs.
10282
10283net_add n1
10284sim_add hv1
10285sim_add hv2
10286as hv1
10287ovs-vsctl add-br br-phys
10288ovn_attach n1 br-phys 192.168.0.2
10289as hv2
10290ovs-vsctl add-br br-phys
10291ovn_attach n1 br-phys 192.168.0.3
10292
10293ovn-nbctl lr-add ro
1ea1b0d0 10294ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
4446661a
MM
10295
10296ovn-nbctl ls-add sw
10297ovn-nbctl lsp-add sw sw-ro
10298ovn-nbctl lsp-set-type sw-ro router
10299ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
10300ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
10301ovn-nbctl lsp-add sw sw-p1
10302ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
10303ovn-nbctl lsp-add sw sw-p2
10304ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
10305
10306ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
10307ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
10308ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
10309ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
10310
86c9d79a
NS
10311for i in 1 2 ; do
10312 as hv$i
10313 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10314 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
10315 options:tx_pcap=hv$i/vif1-tx.pcap \
10316 options:rxq_pcap=hv$i/vif1-rx.pcap \
4446661a
MM
10317 ofport-request=1
10318done
10319
86c9d79a
NS
10320OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
10321OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
4446661a
MM
10322
10323reset_pcap_file() {
10324 local iface=$1
10325 local pcap_file=$2
10326 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10327options:rxq_pcap=dummy-rx.pcap
10328 rm -f ${pcap_file}*.pcap
10329 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10330options:rxq_pcap=${pcap_file}-rx.pcap
10331
10332}
10333
10334construct_expected_ra() {
10335 local src_mac=000000000001
10336 local dst_mac=333300000001
10337 local src_addr=fe80000000000000020000fffe000001
10338 local dst_addr=ff020000000000000000000000000001
10339
10340 local mtu=$1
10341 local ra_mo=$2
10342 local ra_prefix_la=$3
10343
10344 local slla=0101${src_mac}
10345 local mtu_opt=""
10346 if test $mtu != 0; then
10347 mtu_opt=05010000${mtu}
10348 fi
10349 shift 3
10350
10351 local prefix=""
10352 while [[ $# -gt 0 ]] ; do
10353 local size=$1
10354 local net=$2
10355 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
10356 shift 2
10357 done
10358
895ceaf7 10359 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
4446661a
MM
10360 local icmp=8600XXXX${ra}
10361
10362 local ip_len=$(expr ${#icmp} / 2)
1ea1b0d0 10363 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
4446661a
MM
10364
10365 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
10366 local eth=${dst_mac}${src_mac}86dd${ip}
10367 local packet=${eth}
10368 echo $packet >> expected
10369}
10370
10371ra_test() {
10372 construct_expected_ra $@
10373
10374 for i in hv1 hv2 ; do
10375 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
10376
10377 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
10378
10379 cat expected | cut -c -112 > expout
10380 AT_CHECK([cat packets | cut -c -112], [0], [expout])
10381
10382 # Skip ICMPv6 checksum.
10383 cat expected | cut -c 117- > expout
10384 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
10385
10386 rm -f packets
10387 as $i reset_pcap_file $i-vif1 $i/vif1
10388 done
10389
10390 rm -f expected
10391}
10392
10393# Baseline test with no MTU
10394ra_test 0 00 c0 40 aef00000000000000000000000000000
10395
10396# Now make sure an MTU option makes it
10397ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
10398ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
10399
10400# Now test for multiple network prefixes
10401ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
10402ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
10403
10404# Test a different address mode now
10405ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
10406ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
10407
10408# And the other address mode
10409ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
10410ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
10411
10412OVN_CLEANUP([hv1],[hv2])
10413AT_CLEANUP
4826add0
LB
10414
10415AT_SETUP([ovn -- ACL reject rule test])
10416AT_KEYWORDS([acl-reject])
10417AT_SKIP_IF([test $HAVE_PYTHON = no])
10418ovn_start
10419
10420# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
10421#
10422# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10423# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
10424# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
10425# unreachable frame generated from ACL rule hit
10426#
10427# INPORT is a lport number, e.g. 11 for vif11.
10428# HV is a hypervisor number
10429# ETH_SRC and ETH_DST are each 12 hex digits.
10430# IPV4_SRC and IPV4_DST are each 8 hex digits.
10431# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10432test_ip_packet() {
10433 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
10434 local exp_ip_chksum=$8 exp_icmp_chksum=$9
10435 shift 9
10436
10437 local ip_ttl=ff
10438 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
10439
10440 local reply_icmp_ttl=ff
10441 local icmp_type_code_response=0301
10442 local icmp_data=00000000
10443 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
10444 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
10445 echo $reply >> vif$inport.expected
10446
10447 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10448}
10449
c319fabc
LB
10450# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
10451#
10452# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
10453# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
10454# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
10455test_ipv6_packet() {
10456 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
10457 shift 7
10458
10459 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
10460 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
10461
10462 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
10463 echo $reply >> vif$inport.expected
10464
10465 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10466}
10467
c20ab6aa
LB
10468# 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
10469#
10470# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10471# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10472# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
10473#
10474# INPORT is an lport number, e.g. 11 for vif11.
10475# HV is an hypervisor number
10476# ETH_SRC and ETH_DST are each 12 hex digits.
10477# IPV4_SRC and IPV4_DST are each 8 hex digits.
10478# TCP_SPORT and TCP_DPORT are 4 hex digits.
10479# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10480test_tcp_syn_packet() {
10481 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
10482 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10483 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10484 shift 12
10485
10486 local ip_ttl=ff
10487 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10488
10489 local tcp_rst_ttl=ff
10490 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
10491 echo $reply >> vif$inport.expected
10492
10493 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10494}
10495
4826add0
LB
10496# Create hypervisors hv[123].
10497# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
10498# Add all of the vifs to a single logical switch sw0.
10499
10500net_add n1
10501ovn-nbctl ls-add sw0
10502for i in 1 2 3; do
10503 sim_add hv$i
10504 as hv$i
10505 ovs-vsctl add-br br-phys
10506 ovn_attach n1 br-phys 192.168.0.$i
10507
10508 for j in 1 2 3; do
10509 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
10510 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
10511
10512 ovs-vsctl -- add-port br-int vif$i$j -- \
10513 set interface vif$i$j \
10514 external-ids:iface-id=sw0-p$i$j \
10515 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
10516 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
10517 ofport-request=$i$j
10518 done
10519done
10520
10521OVN_POPULATE_ARP
10522# allow some time for ovn-northd and ovn-controller to catch up.
10523sleep 1
10524
10525ip_to_hex() {
10526 printf "%02x%02x%02x%02x" "$@"
10527}
10528
10529for i in 1 2 3; do
10530 : > vif${i}1.expected
10531done
10532
10533ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
10534ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
10535ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
732965bc
HZ
10536
10537# Allow some time for ovn-northd and ovn-controller to catch up.
10538ovn-nbctl --timeout=3 --wait=hv sync
4826add0
LB
10539
10540test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
10541test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
10542test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
10543
c319fabc
LB
10544test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
10545
c20ab6aa
LB
10546test_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
10547test_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
10548test_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
10549
4826add0
LB
10550for i in 1 2 3; do
10551 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
10552done
10553
10554OVN_CLEANUP([hv1], [hv2], [hv3])
10555AT_CLEANUP
689829d5
HZ
10556
10557AT_SETUP([ovn -- Port Groups])
10558AT_KEYWORDS([ovnpg])
10559AT_SKIP_IF([test $HAVE_PYTHON = no])
10560ovn_start
10561
10562# Logical network:
10563#
10564# Three logical switches ls1, ls2, ls3.
10565# One logical router lr0 connected to ls[123],
10566# with nine subnets, three per logical switch:
10567#
10568# lrp11 on ls1 for subnet 192.168.11.0/24
10569# lrp12 on ls1 for subnet 192.168.12.0/24
10570# lrp13 on ls1 for subnet 192.168.13.0/24
10571# ...
10572# lrp33 on ls3 for subnet 192.168.33.0/24
10573#
10574# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10575# digits are the subnet and the last digit distinguishes the VIF.
10576#
10577# This test will create two port groups and uses them in ACL.
10578
10579get_lsp_uuid () {
10580 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10581}
10582
10583pg1_ports=
10584pg2_ports=
10585for i in 1 2 3; do
10586 ovn-nbctl ls-add ls$i
10587 for j in 1 2 3; do
10588 for k in 1 2 3; do
10589 ovn-nbctl \
10590 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
10591 -- lsp-set-addresses lp$i$j$k \
10592 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
689829d5
HZ
10593 # logical ports lp[12]?1 belongs to port group pg1
10594 if test $i != 3 && test $k == 1; then
10595 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10596 fi
10597 # logical ports lp[23]?2 belongs to port group pg2
10598 if test $i != 1 && test $k == 2; then
10599 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10600 fi
10601 done
10602 done
10603done
10604
10605ovn-nbctl lr-add lr0
10606for i in 1 2 3; do
10607 for j in 1 2 3; do
10608 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10609 ovn-nbctl \
10610 -- lsp-add ls$i lrp$i$j-attachment \
10611 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10612 options:router-port=lrp$i$j \
10613 addresses='"00:00:00:00:ff:'$i$j'"'
10614 done
10615done
10616
10617ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
10618ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10619
10620# create ACLs on all lswitches to drop traffic from pg2 to pg1
10621ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10622ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10623ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10624
10625# Physical network:
10626#
10627# Three hypervisors hv[123].
10628# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10629# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10630# lp?3[123] all on hv3.
10631
10632# Given the name of a logical port, prints the name of the hypervisor
10633# on which it is located.
10634vif_to_hv() {
10635 case $1 in dnl (
10636 ?11) echo 1 ;; dnl (
10637 ?12 | ?21 | ?22) echo 2 ;; dnl (
10638 ?13 | ?23 | ?3?) echo 3 ;;
10639 esac
10640}
10641
10642# Given the name of a logical port, prints the name of its logical router
10643# port, e.g. "vif_to_lrp 123" yields 12.
10644vif_to_lrp() {
10645 echo ${1%?}
10646}
10647
10648# Given the name of a logical port, prints the name of its logical
10649# switch, e.g. "vif_to_ls 123" yields 1.
10650vif_to_ls() {
10651 echo ${1%??}
10652}
10653
10654net_add n1
10655for i in 1 2 3; do
10656 sim_add hv$i
10657 as hv$i
10658 ovs-vsctl add-br br-phys
10659 ovn_attach n1 br-phys 192.168.0.$i
10660done
10661for i in 1 2 3; do
10662 for j in 1 2 3; do
10663 for k in 1 2 3; do
10664 hv=`vif_to_hv $i$j$k`
10665 as hv$hv ovs-vsctl \
10666 -- add-port br-int vif$i$j$k \
10667 -- set Interface vif$i$j$k \
10668 external-ids:iface-id=lp$i$j$k \
10669 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10670 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10671 ofport-request=$i$j$k
10672 done
10673 done
10674done
10675
10676# Pre-populate the hypervisors' ARP tables so that we don't lose any
10677# packets for ARP resolution (native tunneling doesn't queue packets
10678# for ARP resolution).
10679OVN_POPULATE_ARP
10680
10681# Allow some time for ovn-northd and ovn-controller to catch up.
10682# XXX This should be more systematic.
10683sleep 1
10684
10685# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10686#
10687# This shell function causes a packet to be received on INPORT. The packet's
10688# content has Ethernet destination DST and source SRC (each exactly 12 hex
10689# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
10690# more) list the VIFs on which the packet should be received. INPORT and the
10691# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
10692for i in 1 2 3; do
10693 for j in 1 2 3; do
10694 for k in 1 2 3; do
10695 : > $i$j$k.expected
10696 done
10697 done
10698done
10699test_ip() {
10700 # This packet has bad checksums but logical L3 routing doesn't check.
10701 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10702 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
10703 shift; shift; shift; shift; shift
10704 hv=hv`vif_to_hv $inport`
10705 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
10706 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
10707 in_ls=`vif_to_ls $inport`
10708 in_lrp=`vif_to_lrp $inport`
10709 for outport; do
10710 out_ls=`vif_to_ls $outport`
10711 if test $in_ls = $out_ls; then
10712 # Ports on the same logical switch receive exactly the same packet.
10713 echo $packet
10714 else
10715 # Routing decrements TTL and updates source and dest MAC
10716 # (and checksum).
10717 out_lrp=`vif_to_lrp $outport`
10718 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10719 fi >> $outport.expected
10720 done
10721}
10722
10723as hv1 ovs-vsctl --columns=name,ofport list interface
10724as hv1 ovn-sbctl list port_binding
10725as hv1 ovn-sbctl list datapath_binding
10726as hv1 ovn-sbctl list port_group
10727as hv1 ovn-sbctl list address_set
10728as hv1 ovn-sbctl dump-flows
10729as hv1 ovs-ofctl dump-flows br-int
10730
10731# Send IP packets between all pairs of source and destination ports,
10732# packets matches ACL (pg2 to pg1) should be dropped
10733ip_to_hex() {
10734 printf "%02x%02x%02x%02x" "$@"
10735}
10736for is in 1 2 3; do
10737 for js in 1 2 3; do
10738 for ks in 1 2 3; do
10739 bcast=
10740 s=$is$js$ks
10741 smac=f00000000$s
10742 sip=`ip_to_hex 192 168 $is$js $ks`
10743 for id in 1 2 3; do
10744 for jd in 1 2 3; do
10745 for kd in 1 2 3; do
10746 d=$id$jd$kd
10747 dip=`ip_to_hex 192 168 $id$jd $kd`
10748 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10749 if test $d != $s; then unicast=$d; else unicast=; fi
10750
10751 # packets matches ACL should be dropped
10752 if test $id != 3 && test $kd == 1; then
10753 if test $is != 1 && test $ks == 2; then
10754 unicast=
10755 fi
10756 fi
10757 test_ip $s $smac $dmac $sip $dip $unicast #1
10758 done
10759 done
10760 done
10761 done
10762 done
10763done
10764
10765# Allow some time for packet forwarding.
10766# XXX This can be improved.
10767sleep 1
10768
10769# Now check the packets actually received against the ones expected.
10770for i in 1 2 3; do
10771 for j in 1 2 3; do
10772 for k in 1 2 3; do
10773 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10774 [$i$j$k.expected])
10775 done
10776 done
10777done
10778
10779# Gracefully terminate daemons
10780OVN_CLEANUP([hv1], [hv2], [hv3])
10781AT_CLEANUP
1beb60af
HZ
10782
10783AT_SETUP([ovn -- ACLs on Port Groups])
10784AT_KEYWORDS([ovnpg_acl])
10785AT_SKIP_IF([test $HAVE_PYTHON = no])
10786ovn_start
10787
10788# Logical network:
10789#
10790# Three logical switches ls1, ls2, ls3.
10791# One logical router lr0 connected to ls[123],
10792# with nine subnets, three per logical switch:
10793#
10794# lrp11 on ls1 for subnet 192.168.11.0/24
10795# lrp12 on ls1 for subnet 192.168.12.0/24
10796# lrp13 on ls1 for subnet 192.168.13.0/24
10797# ...
10798# lrp33 on ls3 for subnet 192.168.33.0/24
10799#
10800# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10801# digits are the subnet and the last digit distinguishes the VIF.
10802#
10803# This test will create two port groups and ACLs will be applied on them.
10804
10805get_lsp_uuid () {
10806 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10807}
10808
10809pg1_ports=
10810pg2_ports=
10811for i in 1 2 3; do
10812 ovn-nbctl ls-add ls$i
10813 for j in 1 2 3; do
10814 for k in 1 2 3; do
10815 ovn-nbctl \
10816 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
10817 -- lsp-set-addresses lp$i$j$k \
10818 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
1beb60af
HZ
10819 # logical ports lp[12]?1 belongs to port group pg1
10820 if test $i != 3 && test $k == 1; then
10821 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10822 fi
10823 # logical ports lp[23]?2 belongs to port group pg2
10824 if test $i != 1 && test $k == 2; then
10825 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10826 fi
10827 done
10828 done
10829done
10830
10831ovn-nbctl lr-add lr0
10832for i in 1 2 3; do
10833 for j in 1 2 3; do
10834 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10835 ovn-nbctl \
10836 -- lsp-add ls$i lrp$i$j-attachment \
10837 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10838 options:router-port=lrp$i$j \
10839 addresses='"00:00:00:00:ff:'$i$j'"'
10840 done
10841done
10842
d87e0897 10843ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
1beb60af
HZ
10844ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10845
10846# create ACLs on pg1 to drop traffic from pg2 to pg1
d87e0897
HZ
10847ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
10848ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
cdc9a84a 10849 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
1beb60af
HZ
10850
10851# Physical network:
10852#
10853# Three hypervisors hv[123].
10854# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10855# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10856# lp?3[123] all on hv3.
10857
10858# Given the name of a logical port, prints the name of the hypervisor
10859# on which it is located.
10860vif_to_hv() {
10861 case $1 in dnl (
10862 ?11) echo 1 ;; dnl (
10863 ?12 | ?21 | ?22) echo 2 ;; dnl (
10864 ?13 | ?23 | ?3?) echo 3 ;;
10865 esac
10866}
10867
10868# Given the name of a logical port, prints the name of its logical router
10869# port, e.g. "vif_to_lrp 123" yields 12.
10870vif_to_lrp() {
10871 echo ${1%?}
10872}
10873
10874# Given the name of a logical port, prints the name of its logical
10875# switch, e.g. "vif_to_ls 123" yields 1.
10876vif_to_ls() {
10877 echo ${1%??}
10878}
10879
10880net_add n1
10881for i in 1 2 3; do
10882 sim_add hv$i
10883 as hv$i
10884 ovs-vsctl add-br br-phys
10885 ovn_attach n1 br-phys 192.168.0.$i
10886done
10887for i in 1 2 3; do
10888 for j in 1 2 3; do
10889 for k in 1 2 3; do
10890 hv=`vif_to_hv $i$j$k`
10891 as hv$hv ovs-vsctl \
10892 -- add-port br-int vif$i$j$k \
10893 -- set Interface vif$i$j$k \
10894 external-ids:iface-id=lp$i$j$k \
10895 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10896 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10897 ofport-request=$i$j$k
10898 done
10899 done
10900done
10901
10902# Pre-populate the hypervisors' ARP tables so that we don't lose any
10903# packets for ARP resolution (native tunneling doesn't queue packets
10904# for ARP resolution).
10905OVN_POPULATE_ARP
10906
10907# Allow some time for ovn-northd and ovn-controller to catch up.
10908# XXX This should be more systematic.
10909sleep 1
10910
cdc9a84a
HZ
10911lsp_to_mac() {
10912 echo f0:00:00:00:0${1:0:1}:${1:1:2}
10913}
10914
10915lrp_to_mac() {
10916 echo 00:00:00:00:ff:$1
10917}
10918
10919# test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
1beb60af 10920#
cdc9a84a
HZ
10921# This shell function causes a ICMP packet to be received on INPORT.
10922# The OUTPORTs (zero or more) list the VIFs on which the packet should
10923# be received. INPORT and the OUTPORTs are specified as logical switch
10924# port numbers, e.g. 123 for vif123.
1beb60af
HZ
10925for i in 1 2 3; do
10926 for j in 1 2 3; do
10927 for k in 1 2 3; do
10928 : > $i$j$k.expected
10929 done
10930 done
10931done
cdc9a84a
HZ
10932
10933test_icmp() {
10934 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
10935 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
10936 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
10937 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
10938 icmp4.code==0"
10939 shift; shift; shift; shift; shift; shift
1beb60af 10940 hv=hv`vif_to_hv $inport`
cdc9a84a 10941 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
1beb60af
HZ
10942 in_ls=`vif_to_ls $inport`
10943 in_lrp=`vif_to_lrp $inport`
10944 for outport; do
10945 out_ls=`vif_to_ls $outport`
10946 if test $in_ls = $out_ls; then
10947 # Ports on the same logical switch receive exactly the same packet.
cdc9a84a 10948 echo $packet | ovstest test-ovn expr-to-packets
1beb60af
HZ
10949 else
10950 # Routing decrements TTL and updates source and dest MAC
10951 # (and checksum).
10952 out_lrp=`vif_to_lrp $outport`
cdc9a84a
HZ
10953 exp_smac=`lrp_to_mac $out_lrp`
10954 exp_dmac=`lsp_to_mac $outport`
10955 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
10956 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
10957 icmp4.type==$icmp_type && icmp4.code==0"
10958 echo $exp_packet | ovstest test-ovn expr-to-packets
10959
1beb60af
HZ
10960 fi >> $outport.expected
10961 done
10962}
10963
10964as hv1 ovs-vsctl --columns=name,ofport list interface
10965as hv1 ovn-sbctl list port_binding
10966as hv1 ovn-sbctl list datapath_binding
10967as hv1 ovn-sbctl list port_group
10968as hv1 ovn-sbctl list address_set
10969as hv1 ovn-sbctl dump-flows
10970as hv1 ovs-ofctl dump-flows br-int
10971
10972# Send IP packets between all pairs of source and destination ports,
10973# packets matches ACL1 but not ACL2 should be dropped
10974ip_to_hex() {
10975 printf "%02x%02x%02x%02x" "$@"
10976}
10977for is in 1 2 3; do
10978 for js in 1 2 3; do
10979 for ks in 1 2 3; do
10980 bcast=
10981 s=$is$js$ks
cdc9a84a
HZ
10982 slsp_mac=`lsp_to_mac $s`
10983 slrp_mac=`lrp_to_mac $is$js`
10984 sip=192.168.$is$js.$ks
1beb60af
HZ
10985 for id in 1 2 3; do
10986 for jd in 1 2 3; do
10987 for kd in 1 2 3; do
10988 d=$id$jd$kd
cdc9a84a
HZ
10989 dlsp_mac=`lsp_to_mac $d`
10990 dlrp_mac=`lrp_to_mac $id$jd`
10991 dip=192.168.$id$jd.$kd
10992 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
1beb60af
HZ
10993 if test $d != $s; then unicast=$d; else unicast=; fi
10994
10995 # packets matches ACL1 but not ACL2 should be dropped
10996 if test $id != 3 && test $kd == 1; then
10997 if test $is == 1 || test $ks != 2; then
10998 unicast=
10999 fi
11000 fi
cdc9a84a
HZ
11001 # icmp request (type = 8)
11002 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
11003
11004 # if packets are not dropped, test the return traffic (icmp echo)
11005 # to make sure stateful works, too.
11006 if test x$unicast != x; then
11007 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
11008 # icmp echo (type = 0)
11009 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
11010 fi
1beb60af
HZ
11011 done
11012 done
11013 done
11014 done
11015 done
11016done
11017
11018# Allow some time for packet forwarding.
11019# XXX This can be improved.
11020sleep 1
11021
11022# Now check the packets actually received against the ones expected.
11023for i in 1 2 3; do
11024 for j in 1 2 3; do
11025 for k in 1 2 3; do
11026 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11027 [$i$j$k.expected])
11028 done
11029 done
11030done
11031
11032# Gracefully terminate daemons
11033OVN_CLEANUP([hv1], [hv2], [hv3])
11034AT_CLEANUP
55b25947 11035
2342c266
JS
11036AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
11037ovn_start
11038
11039ovn-nbctl ls-add ls1
11040
11041ovn-nbctl lsp-add ls1 lp1
11042ovn-nbctl lsp-add ls1 lp2
11043ovn-nbctl lsp-add ls1 lp3
11044
11045ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
11046ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
11047ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
11048
11049ovn-nbctl create Port_Group name=pg1
11050ovn-nbctl create Port_Group name=pg2
11051
11052ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
11053ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
11054ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
11055ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
11056
11057ovn-nbctl --wait=sb sync
11058
11059dnl Check if port group address sets were populated with ports' addresses
11060AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11061 [0], [[["10.0.0.1", "10.0.0.2"]]
11062])
11063AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
11064 [0], [[["10.0.0.2", "10.0.0.3"]]
11065])
11066AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11067 [0], [[["2001:db8::1", "2001:db8::2"]]
11068])
11069AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
11070 [0], [[["2001:db8::2", "2001:db8::3"]]
11071])
11072
11073ovn-nbctl --wait=sb lsp-set-addresses lp1 \
11074 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
11075
11076dnl Check if updated address got propagated to the port group address sets
11077AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11078 [0], [[["10.0.0.11", "10.0.0.2"]]
11079])
11080AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11081 [0], [[["2001:db8::11", "2001:db8::2"]]
11082])
11083
11084AT_CLEANUP
11085
984c7d5e
JS
11086AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
11087ovn_start
11088
11089ovn-nbctl ls-add ls1
11090ovn-nbctl ls-add ls2
11091ovn-nbctl ls-add ls3
11092
11093ovn-nbctl set Logical_Switch ls1 \
11094 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
11095ovn-nbctl set Logical_Switch ls2 \
11096 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
11097ovn-nbctl set Logical_Switch ls3 \
11098 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
11099
11100ovn-nbctl lsp-add ls1 lp1
11101ovn-nbctl lsp-add ls2 lp2
11102ovn-nbctl lsp-add ls3 lp3
11103
11104ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
11105ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
11106ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
11107
11108ovn-nbctl create Port_Group name=pg1
11109ovn-nbctl create Port_Group name=pg2
11110
11111ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
11112ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
11113ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
11114ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
11115
11116ovn-nbctl --wait=sb sync
11117
11118dnl Check if port group address sets were populated with ports' addresses
11119AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11120 [0], [[["10.1.0.2", "10.2.0.2"]]
11121])
11122AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
11123 [0], [[["10.2.0.2", "10.3.0.2"]]
11124])
11125AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11126 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
11127])
11128AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
11129 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
11130])
11131
11132ovn-nbctl set Logical_Switch ls1 \
11133 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
11134
11135dnl Check if updated address got propagated to the port group address sets
11136AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
451624fe 11137 [0], [[["10.11.0.2", "10.2.0.2"]]
984c7d5e
JS
11138])
11139AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
451624fe 11140 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
984c7d5e
JS
11141])
11142
11143AT_CLEANUP
11144
55b25947
NS
11145AT_SETUP([ovn -- ACL conjunction])
11146ovn_start
11147
11148ovn-nbctl ls-add ls1
11149
11150ovn-nbctl lsp-add ls1 ls1-lp1 \
11151-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
11152
11153ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
11154
11155ovn-nbctl lsp-add ls1 ls1-lp2 \
11156-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
11157
11158ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
11159
11160net_add n1
11161sim_add hv1
11162
11163as hv1
11164ovs-vsctl add-br br-phys
11165ovn_attach n1 br-phys 192.168.0.1
11166ovs-vsctl -- add-port br-int hv1-vif1 -- \
11167 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
11168 options:tx_pcap=hv1/vif1-tx.pcap \
11169 options:rxq_pcap=hv1/vif1-rx.pcap \
11170 ofport-request=1
11171
11172ovs-vsctl -- add-port br-int hv1-vif2 -- \
11173 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
11174 options:tx_pcap=hv1/vif2-tx.pcap \
11175 options:rxq_pcap=hv1/vif2-rx.pcap \
11176 ofport-request=2
11177
11178ovn-nbctl create Address_Set name=set1 \
11179addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
11180ovn-nbctl create Address_Set name=set2 \
11181addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
11182ovn-nbctl acl-add ls1 to-lport 1002 \
11183'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
11184ovn-nbctl acl-add ls1 to-lport 1001 \
11185'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
11186
11187# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11188#
11189# This shell function causes an ip packet to be received on INPORT.
11190# The packet's content has Ethernet destination DST and source SRC
11191# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
11192# The OUTPORTs (zero or more) list the VIFs on which the packet should
11193# be received. INPORT and the OUTPORTs are specified as logical switch
11194# port numbers, e.g. 11 for vif11.
11195test_ip() {
11196 # This packet has bad checksums but logical L3 routing doesn't check.
11197 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11198 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
11199${dst_ip}0035111100080000
11200 shift; shift; shift; shift; shift
11201 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
11202 for outport; do
11203 echo $packet >> $outport.expected
11204 done
11205}
11206
11207ip_to_hex() {
11208 printf "%02x%02x%02x%02x" "$@"
11209}
11210
11211reset_pcap_file() {
11212 local iface=$1
11213 local pcap_file=$2
11214 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11215options:rxq_pcap=dummy-rx.pcap
11216 rm -f ${pcap_file}*.pcap
11217 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11218options:rxq_pcap=${pcap_file}-rx.pcap
11219}
11220
11221
11222sip=`ip_to_hex 10 0 0 4`
11223dip=`ip_to_hex 10 0 0 6`
11224
11225test_ip 1 f00000000001 f00000000002 $sip $dip 2
11226
11227cat 2.expected > expout
11228$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
11229AT_CHECK([cat 2.packets], [0], [expout])
11230
11231# There should be total of 12 flows present with conjunction action and 2 flows
11232# with conj match. Eg.
11233# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
11234# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
11235# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
11236# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
11237# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
11238# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
11239# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
11240# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
11241# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
11242# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
11243# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
11244# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
11245# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
11246# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
11247
11248OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
11249grep conjunction | wc -l`])
11250OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
11251grep conj_id | wc -l`])
11252
11253as hv1 ovs-ofctl dump-flows br-int
11254
11255# Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
11256ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
11257ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
11258
11259reset_pcap_file hv1-vif2 hv1/vif2
11260
11261rm -f 2.packets
11262
11263sip=`ip_to_hex 10 0 0 4`
11264dip=`ip_to_hex 10 0 0 7`
11265
11266test_ip 1 f00000000001 f00000000002 $sip $dip
11267$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
11268AT_CHECK([cat 2.packets], [0], [])
11269
11270AT_CLEANUP
0e2751ed
LB
11271
11272AT_SETUP([ovn -- TTL exceeded])
11273AT_KEYWORDS([ttl-exceeded])
11274AT_SKIP_IF([test $HAVE_PYTHON = no])
11275ovn_start
11276
11277# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
11278#
11279# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
11280# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
11281# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
11282# generated by OVN logical router
11283#
11284# INPORT is a lport number, e.g. 11 for vif11.
11285# HV is a hypervisor number
11286# ETH_SRC and ETH_DST are each 12 hex digits.
11287# IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
11288# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
11289test_ip_packet() {
11290 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
11291 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
11292 shift 10
11293
11294 local ip_ttl=01
11295 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
11296
11297 local reply_icmp_ttl=fe
11298 local icmp_type_code_response=0b00
11299 local icmp_data=00000000
11300 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
11301 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
11302 echo $reply >> vif$inport.expected
11303
11304 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11305}
11306
e6a84e1e
LB
11307# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
11308#
11309# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
11310# packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
11311# IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
11312# packet sent by OVN logical router
11313test_ip6_packet() {
11314 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
11315 shift 8
11316
11317 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
11318 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
11319
11320 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
11321 echo $reply >> vif$inport.expected
11322
11323 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11324}
11325
0e2751ed
LB
11326ip_to_hex() {
11327 printf "%02x%02x%02x%02x" "$@"
11328}
11329
11330for i in 1 2; do
11331 net_add n$i
11332 ovn-nbctl ls-add sw$i
11333
11334 sim_add hv$i
11335 as hv$i
11336 ovs-vsctl add-br br-phys
11337 ovn_attach n$i br-phys 192.168.$i.1
11338
11339 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
e6a84e1e 11340 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
11341
11342 ovs-vsctl -- add-port br-int vif$i -- \
11343 set interface vif$i \
11344 external-ids:iface-id=sw$i-p${i}0 \
11345 options:tx_pcap=hv$i/vif$i-tx.pcap \
11346 options:rxq_pcap=hv$i/vif$i-rx.pcap \
11347 ofport-request=$i
11348done
11349
11350ovn-nbctl lr-add lr0
11351for i in 1 2; do
e6a84e1e 11352 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
11353 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
11354 -- set Logical_Switch_Port lrp$i-attachment type=router \
e6a84e1e 11355 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
0e2751ed
LB
11356done
11357
11358OVN_POPULATE_ARP
11359# allow some time for ovn-northd and ovn-controller to catch up.
11360ovn-nbctl --wait=hv sync
11361
11362test_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 11363test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
0e2751ed
LB
11364OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
11365
11366OVN_CLEANUP([hv1], [hv2])
11367AT_CLEANUP
86558ac2
LB
11368
11369AT_SETUP([ovn -- router port unreachable])
11370AT_KEYWORDS([router-port-unreachable])
11371AT_SKIP_IF([test $HAVE_PYTHON = no])
11372ovn_start
11373
11374# 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
11375#
11376# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
11377# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
11378# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
11379# EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
11380#
11381# INPORT is a lport number, e.g. 11 for vif11.
11382# HV is a hypervisor number
11383# ETH_SRC and ETH_DST are each 12 hex digits.
11384# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
11385# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
11386test_ip_packet() {
11387 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
11388 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
11389 shift 11
11390
11391 local ip_ttl=ff
11392 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
11393
11394 local reply_icmp_ttl=fe
11395 local icmp_data=00000000
11396 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
11397 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
11398 echo $reply >> vif$inport.expected
11399
11400 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11401}
11402
159932c9
LB
11403# 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
11404#
11405# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
11406# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
11407# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
11408#
11409# INPORT is an lport number, e.g. 11 for vif11.
11410# HV is an hypervisor number
11411# ETH_SRC and ETH_DST are each 12 hex digits.
11412# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
11413# TCP_SPORT and TCP_DPORT are 4 hex digits.
11414# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
11415test_tcp_syn_packet() {
11416 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
11417 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
11418 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
11419 shift 12
11420
11421 local ip_ttl=ff
11422 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
11423
11424 local tcp_rst_ttl=fe
11425 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
11426 echo $reply >> vif$inport.expected
11427
11428 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11429}
11430
98af55fc
LB
11431# test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
11432#
11433# Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
11434# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
11435# EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
11436test_tcp6_packet() {
11437 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
11438 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
11439 local exp_tcp_rst_chksum=${10}
11440 shift 10
11441
11442 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
11443 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
11444
11445 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
11446 echo $reply >> vif$inport.expected
11447
11448 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11449}
11450
4c25c3b8
LB
11451# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
11452#
11453# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
11454# packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
11455# EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
11456test_ip6_packet() {
11457 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
11458 local exp_icmp_code=${10} exp_icmp_chksum=${11}
11459 shift 11
11460
11461 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
11462 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
11463
11464 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
11465 echo $reply >> vif$inport.expected
11466
11467 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11468}
11469
86558ac2
LB
11470ip_to_hex() {
11471 printf "%02x%02x%02x%02x" "$@"
11472}
11473
11474for i in 1 2; do
11475 net_add n$i
11476 ovn-nbctl ls-add sw$i
11477
11478 sim_add hv$i
11479 as hv$i
11480 ovs-vsctl add-br br-phys
11481 ovn_attach n$i br-phys 192.168.$i.1
11482
11483 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
4c25c3b8 11484 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
11485
11486 ovs-vsctl -- add-port br-int vif$i -- \
11487 set interface vif$i \
11488 external-ids:iface-id=sw$i-p${i}0 \
11489 options:tx_pcap=hv$i/vif$i-tx.pcap \
11490 options:rxq_pcap=hv$i/vif$i-rx.pcap \
11491 ofport-request=$i
11492done
11493
11494ovn-nbctl lr-add lr0
11495for i in 1 2; do
4c25c3b8 11496 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
11497 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
11498 -- set Logical_Switch_Port lrp$i-attachment type=router \
4c25c3b8 11499 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
86558ac2
LB
11500done
11501
11502OVN_POPULATE_ARP
11503# allow some time for ovn-northd and ovn-controller to catch up.
11504ovn-nbctl --wait=hv sync
11505
11506test_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 11507test_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 11508test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
86558ac2
LB
11509OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
11510
159932c9 11511test_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 11512test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
98af55fc 11513test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
159932c9
LB
11514OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
11515
86558ac2
LB
11516OVN_CLEANUP([hv1], [hv2])
11517AT_CLEANUP
96ea0ecb
MM
11518
11519AT_SETUP([ovn -- ovn-controller exit])
11520AT_SKIP_IF([test $HAVE_PYTHON = no])
11521ovn_start
11522# Logical network:
11523# One Logical Router: ro, with two logical switches sw1 and sw2.
11524# sw1 is for subnet 10.0.0.0/8
11525# sw2 is for subnet 20.0.0.0/8
11526# sw1 has a single port bound on hv1
11527# sw2 has a single port bound on hv2
11528
11529ovn-nbctl lr-add ro
11530ovn-nbctl ls-add sw1
11531ovn-nbctl ls-add sw2
11532
11533sw1_ro_mac=00:00:10:00:00:01
11534sw1_ro_ip=10.0.0.1
11535sw2_ro_mac=00:00:20:00:00:01
11536sw2_ro_ip=20.0.0.1
11537sw1_p1_mac=00:00:10:00:00:02
11538sw1_p1_ip=10.0.0.2
11539sw2_p1_mac=00:00:20:00:00:02
11540sw2_p1_ip=20.0.0.2
11541
11542ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11543ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11544ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11545 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11546ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11547 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11548
11549ovn-nbctl lsp-add sw1 sw1-p1 \
11550-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11551
11552ovn-nbctl lsp-add sw2 sw2-p1 \
11553-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11554
11555net_add n1
11556
11557sim_add hv1
11558as hv1
11559ovs-vsctl add-br br-phys
11560ovn_attach n1 br-phys 192.168.0.1
11561ovs-vsctl -- add-port br-int hv1-vif1 -- \
11562 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11563 options:tx_pcap=hv1/vif1-tx.pcap \
11564 options:rxq_pcap=hv1/vif1-rx.pcap \
11565 ofport-request=1
11566
11567sim_add hv2
11568as hv2
11569ovs-vsctl add-br br-phys
11570ovn_attach n1 br-phys 192.168.0.2
11571ovs-vsctl -- add-port br-int hv2-vif1 -- \
11572 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11573 options:tx_pcap=hv2/vif1-tx.pcap \
11574 options:rxq_pcap=hv2/vif1-rx.pcap \
11575 ofport-request=1
11576
11577OVN_POPULATE_ARP
11578
11579sleep 1
11580
11581packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11582 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11583 udp && udp.src==53 && udp.dst==4369"
11584
11585# Start by Sending the packet and make sure it makes it there as expected
11586as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11587
11588# Expected packet has TTL decreased by 1
11589expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11590 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11591 udp && udp.src==53 && udp.dst==4369"
11592echo $expected | ovstest test-ovn expr-to-packets > expected
11593
11594OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11595
11596# Stop ovn-controller on hv2
11597as hv2 ovs-appctl -t ovn-controller exit
11598
11599# Now send the packet again. This time, it should not arrive.
11600as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11601
11602OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11603
11604# Start ovn-controller again just so OVN_CLEANUP doesn't complain
11605as hv2 start_daemon ovn-controller
11606
11607OVN_CLEANUP([hv1],[hv2])
11608AT_CLEANUP
11609
11610AT_SETUP([ovn -- ovn-controller restart])
11611AT_SKIP_IF([test $HAVE_PYTHON = no])
11612ovn_start
11613
11614# Logical network:
11615# One Logical Router: ro, with two logical switches sw1 and sw2.
11616# sw1 is for subnet 10.0.0.0/8
11617# sw2 is for subnet 20.0.0.0/8
11618# sw1 has a single port bound on hv1
11619# sw2 has a single port bound on hv2
11620
11621ovn-nbctl lr-add ro
11622ovn-nbctl ls-add sw1
11623ovn-nbctl ls-add sw2
11624
11625sw1_ro_mac=00:00:10:00:00:01
11626sw1_ro_ip=10.0.0.1
11627sw2_ro_mac=00:00:20:00:00:01
11628sw2_ro_ip=20.0.0.1
11629sw1_p1_mac=00:00:10:00:00:02
11630sw1_p1_ip=10.0.0.2
11631sw2_p1_mac=00:00:20:00:00:02
11632sw2_p1_ip=20.0.0.2
11633
11634ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11635ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11636ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11637 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11638ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11639 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11640
11641ovn-nbctl lsp-add sw1 sw1-p1 \
11642-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11643
11644ovn-nbctl lsp-add sw2 sw2-p1 \
11645-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11646
11647net_add n1
11648
11649sim_add hv1
11650as hv1
11651ovs-vsctl add-br br-phys
11652ovn_attach n1 br-phys 192.168.0.1
11653ovs-vsctl -- add-port br-int hv1-vif1 -- \
11654 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11655 options:tx_pcap=hv1/vif1-tx.pcap \
11656 options:rxq_pcap=hv1/vif1-rx.pcap \
11657 ofport-request=1
11658
11659sim_add hv2
11660as hv2
11661ovs-vsctl add-br br-phys
11662ovn_attach n1 br-phys 192.168.0.2
11663ovs-vsctl -- add-port br-int hv2-vif1 -- \
11664 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11665 options:tx_pcap=hv2/vif1-tx.pcap \
11666 options:rxq_pcap=hv2/vif1-rx.pcap \
11667 ofport-request=1
11668
11669OVN_POPULATE_ARP
11670
11671sleep 1
11672
11673packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11674 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11675 udp && udp.src==53 && udp.dst==4369"
11676
11677# Start by Sending the packet and make sure it makes it there as expected
11678as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11679
11680# Expected packet has TTL decreased by 1
11681expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11682 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11683 udp && udp.src==53 && udp.dst==4369"
11684echo $expected | ovstest test-ovn expr-to-packets > expected
11685
11686OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11687
11688# Stop ovn-controller on hv2 with --restart flag
11689as hv2 ovs-appctl -t ovn-controller exit --restart
11690
11691# Now send the packet again. This time, it should still arrive
11692as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11693
11694cat expected expected > expected2
11695
11696OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
11697
11698# Start ovn-controller again just so OVN_CLEANUP doesn't complain
11699as hv2 start_daemon ovn-controller
11700
11701OVN_CLEANUP([hv1],[hv2])
11702
11703AT_CLEANUP
863fb61f
MM
11704
11705AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
11706ovn_start
11707
11708# Set up a switch with some switch ports of varying address types
11709ovn-nbctl ls-add sw1
11710ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
11711
11712ovn-nbctl lsp-add sw1 sw1-p1
11713ovn-nbctl lsp-add sw1 sw1-p2
11714ovn-nbctl lsp-add sw1 sw1-p3
11715ovn-nbctl lsp-add sw1 sw1-p4
11716
11717ovn-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"
11718ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
11719ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
11720ovn-nbctl lsp-set-addresses sw1-p4 "router"
11721ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
11722
11723ovn-nbctl list logical_switch_port
11724
11725# Now try to add duplicate addresses on a new port. These should all fail
11726ovn-nbctl lsp-add sw1 sw1-p5
11727AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
11728[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
11729])
11730AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
11731[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
11732])
11733AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
11734[ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
11735])
11736AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
11737[ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
11738])
11739AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
11740[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
11741])
11742AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
11743[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
11744])
11745
11746# Now try re-setting sw1-p1. This should succeed
11747AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
11748
11749# Now create a new switch and try setting IP addresses the same as the
11750# first switch. This should succeed.
11751ovn-nbctl ls-add sw2
11752ovn-nbctl lsp-add sw2 sw2-p1
11753
11754AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
11755AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
11756AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
11757AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
11758
11759AT_CLEANUP
d7abfe39
LB
11760
11761AT_SETUP([ovn -- IP packet buffering])
11762AT_KEYWORDS([ip-buffering])
11763AT_SKIP_IF([test $HAVE_PYTHON = no])
11764ovn_start
11765
11766# Logical network:
11767# One LR lr0 that has switches sw0 (192.168.1.0/24) and
11768# sw1 (172.16.1.0/24) connected to it.
11769#
11770# Physical network:
11771# Tw0 hypervisors hv[12].
11772# hv1 hosts vif sw0-p0.
11773# hv1 hosts vif sw1-p0.
11774
11775send_icmp_packet() {
11776 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
11777 shift 8
11778
11779 local ip_ttl=ff
11780 local ip_len=001c
11781 local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
11782 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
11783}
11784
11785send_icmp6_packet() {
11786 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
11787 shift 8
11788
11789 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
11790 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
11791
11792 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
11793}
11794
11795get_arp_req() {
11796 local eth_src=$1 spa=$2 tpa=$3
11797 local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
11798 echo $request
11799}
11800
11801send_arp_reply() {
11802 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
11803 local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
11804 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
11805}
11806
11807send_na() {
11808 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
11809 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
11810 local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
11811
11812 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
11813}
11814
11815get_nd() {
11816 local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
11817 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
11818 request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
11819
11820 echo $request
11821}
11822
11823net_add n1
11824
11825sim_add hv1
11826as hv1
11827ovs-vsctl add-br br-phys
11828ovn_attach n1 br-phys 192.168.0.1
11829ovs-vsctl -- add-port br-int hv1-vif1 -- \
11830 set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
11831 options:tx_pcap=hv1/vif1-tx.pcap \
11832 options:rxq_pcap=hv1/vif1-rx.pcap \
11833 ofport-request=1
11834
11835sim_add hv2
11836as hv2
11837ovs-vsctl add-br br-phys
11838ovn_attach n1 br-phys 192.168.0.2
11839ovs-vsctl -- add-port br-int hv2-vif1 -- \
11840 set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
11841 options:tx_pcap=hv2/vif1-tx.pcap \
11842 options:rxq_pcap=hv2/vif1-rx.pcap \
11843 ofport-request=1
11844
11845ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
11846ovn-nbctl ls-add sw0
11847ovn-nbctl ls-add sw1
11848
11849ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001::1/64
11850ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
11851 type=router options:router-port=sw0 \
11852 -- lsp-set-addresses rp-sw0 router
11853
11854ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002::1/64
11855ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
11856 type=router options:router-port=sw1 \
11857 -- lsp-set-addresses rp-sw1 router
11858
11859ovn-nbctl lsp-add sw0 sw0-p0 \
11860 -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
11861
11862ovn-nbctl lsp-add sw1 sw1-p0 \
11863 -- lsp-set-addresses sw1-p0 unknown
11864
11865OVN_POPULATE_ARP
11866ovn-nbctl --wait=hv sync
11867
11868ip_to_hex() {
11869 printf "%02x%02x%02x%02x" "$@"
11870}
11871
11872src_mac=f00000010203
11873src_ip=$(ip_to_hex 192 168 1 2)
11874src_ip6=20010000000000000000000000000002
11875
11876router_mac0=000001010203
11877router_mac1=000002010203
11878router_ip=$(ip_to_hex 172 16 1 1)
11879router_ip6=20020000000000000000000000000001
11880
11881dst_mac=001122334455
11882dst_ip=$(ip_to_hex 172 16 1 10)
11883dst_ip6=20020000000000000000000000000010
11884
11885data=0800bee4391a0001
11886
11887send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
11888send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
11889echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
11890echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
11891
11892OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11893
11894nd_ip=ff0200000000000000000001ff000010
11895ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
11896
11897send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
11898echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
11899echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
11900send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
11901
11902OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11903
11904OVN_CLEANUP([hv1],[hv2])
11905AT_CLEANUP
81e92852
DA
11906
11907AT_SETUP([ovn -- neighbor update on same HV])
11908AT_SKIP_IF([test $HAVE_PYTHON = no])
11909ovn_start
11910
11911# Logical network:
11912# A public switch (pub) with a localnet port connected to two LRs (lr0 and lr1)
11913# each with a distributed gateway port.
11914# Two VMs: lp0 on sw0 connected to lr0
11915# lp1 on sw1 connected to lr1
11916#
11917# This test adds a floating IP to each VM so when they are bound to the same
11918# hypervisor, it checks that the GARP sent by ovn-controller causes the
11919# MAC_Binding entries to be updated properly on each logical router.
11920# It will also capture packets on the physical interface to make sure that the
11921# GARPs have been sent out to the external network as well.
11922
11923# Create logical switches
11924ovn-nbctl ls-add sw0
11925ovn-nbctl ls-add sw1
11926ovn-nbctl ls-add pub
11927
11928# Created localnet port on public switch
11929ovn-nbctl lsp-add pub ln-pub
11930ovn-nbctl lsp-set-type ln-pub localnet
11931ovn-nbctl lsp-set-addresses ln-pub unknown
11932ovn-nbctl lsp-set-options ln-pub network_name=phys
11933
11934# Create logical routers and connect them to public switch
11935ovn-nbctl create Logical_Router name=lr0
11936ovn-nbctl create Logical_Router name=lr1
11937
11938ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
11939ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
11940 type=router options:router-port=lr0-pub options:nat-addresses="router" addresses="router"
11941ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
11942ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
11943 type=router options:router-port=lr1-pub options:nat-addresses="router" addresses="router"
11944
11945ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
11946ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
11947
11948# Connect sw0 and sw1 to lr0 and lr1
11949ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
11950ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
11951 options:router-port=lr0-sw0 addresses="router"
11952ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
11953ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
11954 options:router-port=lr1-sw1 addresses="router"
11955
11956
11957# Add SNAT rules
11958ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
11959ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
11960
11961net_add n1
11962sim_add hv1
11963as hv1
11964ovs-vsctl add-br br-phys
11965ovn_attach n1 br-phys 172.24.4.1
11966ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
11967
11968ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
11969ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
11970
11971ovn-nbctl lsp-add sw0 lp0
11972ovn-nbctl lsp-add sw1 lp1
11973ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
11974ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
11975
11976OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp0` = xup])
11977OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
11978
11979# Create two floating IPs, one for each VIF
11980ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
11981ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
11982
11983# Check that the MAC_Binding entries have been properly created
11984OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr0-pub" ip="172.24.4.200" | wc -l` -gt 0])
11985OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr1-pub" ip="172.24.4.100" | wc -l` -gt 0])
11986
11987# Check that the GARPs went also to the external physical network
11988# Wait until at least 4 packets have arrived and copy them to a separate file as
11989# more GARPs are expected in the capture in order to avoid race conditions.
11990OVS_WAIT_UNTIL([test `$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | wc -l` -gt 4])
11991$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | head -n4 > hv1/br-phys-tx4.pcap
11992
11993# GARP for lp0 172.24.4.100 on lr0-pub MAC (f0:00:00:00:00:01)
11994echo "fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464" > expout
11995# GARP for 172.24.4.220 on lr0-pub (f0:00:00:00:00:01)
11996echo "fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc" >> expout
11997# GARP for lp1 172.24.4.200 on lr1-pub MAC (f0:00:00:00:01:01)
11998echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8" >> expout
11999# GARP for 172.24.4.221 on lr1-pub (f0:00:00:00:01:01)
12000echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd" >> expout
12001AT_CHECK([sort hv1/br-phys-tx4.pcap], [0], [expout])
12002#OVN_CHECK_PACKETS([hv1/br-phys-tx4.pcap], [br-phys.expected])
12003
12004OVN_CLEANUP([hv1])
12005AT_CLEANUP