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