]> git.proxmox.com Git - mirror_ovs.git/blame - tests/ovn.at
OVN: use trigger_event action to report 'empty_lb_rule' events
[mirror_ovs.git] / tests / ovn.at
CommitLineData
49d7c759
BP
1# OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2#
3# This compares packets read from PCAP, in pcap format, to those read
4# from EXPECTED, which is a text file containing packets as hex
5# strings, one per line. If PCAP contains fewer packets than
6# EXPECTED, it waits up to 10 seconds for more packets to appear.
7#
8# The implementation is an m4 macro that is mostly implemented in
9# terms of a shell function. This reduces the size of the generated
10# testsuite file since the shell function is only emitted once even
11# when this macro is invoked many times.
12m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
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)
cbf49545
MJ
1107reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain_name="ovn.org",wpad="https://example.org",bootfile_name="https://127.0.0.1/boot.ipxe",path_prefix="/tftpboot");
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_name = "ovn.org", wpad = "https://example.org", bootfile_name = "https://127.0.0.1/boot.ipxe", path_prefix = "/tftpboot");
318799a2 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.43.1b.68.74.74.70.73.3a.2f.2f.31.32.37.2e.30.2e.30.2e.31.2f.62.6f.6f.74.2e.69.70.78.65.d2.09.2f.74.66.74.70.62.6f.6f.74,pause)
2a7be04e
LAG
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,tftp_server_address={10.0.0.4,10.0.0.5});
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, tftp_server_address = {10.0.0.4, 10.0.0.5});
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.96.08.0a.00.00.04.0a.00.00.05,pause)
d5a76da4
BP
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.
cbf49545
MJ
1128reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain_name=1.2.3.4);
1129 DHCPv4 option domain_name 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);
36ffc466
MM
1263 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.05.01.00.00.00.00.05.aa.03.04.40.80.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.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
1264 has prereqs ip6
52ed5fcc 1265reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
36ffc466
MM
1266 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.05.01.00.00.00.00.05.aa.03.04.40.80.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.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
1267 has prereqs ip6
52ed5fcc
NS
1268reg1[0] = put_nd_ra_opts(addr_mode = "slaac", 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", slla = ae:01:02:03:04:10);
1271 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1272reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1273 Syntax error at `dhcpv6_stateless' expecting constant.
1274reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1275 Invalid value for "prefix" option
1276reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1277 Invalid value for "addr_mode" option
1278reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1279 IPv6 ND RA option mtu requires numeric value.
1280reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1281 Invalid value for "mtu" option
1282
bc3d6a63
LB
1283# icmp4
1284icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1285 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)
1286 has prereqs ip4
1287
1288icmp4 { };
1289 formats as icmp4 { drop; };
1290 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1291 has prereqs ip4
1292
086470cd
NS
1293# icmp4 with icmp4.frag_mtu
1294icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
1295 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.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1296 has prereqs ip4
1297
5e35f78a
NS
1298# icmp4_error
1299icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1300 encodes as controller(userdata=00.00.00.0e.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)
1301 has prereqs ip4
1302
1303icmp4_error { };
1304 formats as icmp4_error { drop; };
1305 encodes as controller(userdata=00.00.00.0e.00.00.00.00)
1306 has prereqs ip4
1307
1308# icmp4_error with icmp4.frag_mtu
1309icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
1310 encodes as controller(userdata=00.00.00.0e.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1311 has prereqs ip4
1312
086470cd
NS
1313icmp4.frag_mtu = 1500;
1314 encodes as controller(userdata=00.00.00.0d.00.00.00.00.05.dc,pause)
1315
3e7fa1e3
LB
1316# icmp6
1317icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1318 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)
1319 has prereqs ip6
1320
1321icmp6 { };
1322 formats as icmp6 { drop; };
1323 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1324 has prereqs ip6
1325
22b65e4d
LB
1326# tcp_reset
1327tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1328 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)
1329 has prereqs tcp
1330
1331tcp_reset { };
1332 formats as tcp_reset { drop; };
1333 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1334 has prereqs tcp
1335
5e0d2837
LB
1336# trigger_event
1337trigger_event(event = "empty_lb_backends", vip = "10.0.0.1:80", protocol = "tcp", load_balancer = "12345678-abcd-9876-fedc-11119f8e7d6c");
1338 encodes as controller(userdata=00.00.00.0f.00.00.00.00.00.00.00.00.00.01.00.0b.31.30.2e.30.2e.30.2e.31.3a.38.30.00.02.00.03.74.63.70.00.03.00.24.31.32.33.34.35.36.37.38.2d.61.62.63.64.2d.39.38.37.36.2d.66.65.64.63.2d.31.31.31.31.39.66.38.65.37.64.36.63)
1339
1340# Testing invalid vip results in extra error messages from socket-util.c
1341trigger_event(event = "empty_lb_backends", vip = "10.0.0.1:80", protocol = "sctp", load_balancer = "12345678-abcd-9876-fedc-11119f8e7d6c");
1342 Load balancer protocol 'sctp' is not 'tcp' or 'udp'
1343trigger_event(event = "empty_lb_backends", vip = "10.0.0.1:80", protocol = "tcp", load_balancer = "bacon");
1344 Load balancer 'bacon' is not a UUID
1345
5f822129 1346# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
1347ip4.src = ip6.src[0..31];
1348 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1349 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1350ip4.src <-> ip6.src[0..31];
1351 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[]
1352 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1353
e3fcc19d
NS
1354# check_pkt_larger
1355reg0[0] = check_pkt_larger(1500);
1356 encodes as check_pkt_larger(1500)->NXM_NX_XXREG0[96]
1357
1358reg0 = check_pkt_larger(1500);
1359 Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
1360
1361reg0 = check_pkt_larger(foo);
1362 Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
1363
1364reg0[0] = check_pkt_larger(foo);
1365 Syntax error at `foo' expecting `;'.
1366
d5a76da4
BP
1367# Miscellaneous negative tests.
1368;
1369 Syntax error at `;'.
1370xyzzy;
1371 Syntax error at `xyzzy' expecting action.
1372next; 123;
1373 Syntax error at `123'.
1374next; xyzzy;
1375 Syntax error at `xyzzy' expecting action.
1376next
9aef3c1b 1377 Syntax error at end of input expecting `;'.
3b7cb7e1 1378]])
d5a76da4
BP
1379sed '/^[[ ]]/d' test-cases.txt > input.txt
1380cp test-cases.txt expout
3b7cb7e1
BP
1381AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1382AT_CLEANUP
f295c17b
BP
1383
1384AT_BANNER([OVN end-to-end tests])
1385
9975d7be
BP
1386# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1387AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1388AT_KEYWORDS([ovnarp])
f295c17b
BP
1389AT_SKIP_IF([test $HAVE_PYTHON = no])
1390ovn_start
1391
1392# Create hypervisors hv[123].
9975d7be 1393# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1394# Add all of the vifs to a single logical switch lsw0.
1395# Turn on port security on all the vifs except vif[123]1.
1396# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1397# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1398ovn-nbctl ls-add lsw0
f295c17b
BP
1399net_add n1
1400for i in 1 2 3; do
1401 sim_add hv$i
1402 as hv$i
1403 ovs-vsctl add-br br-phys
1404 ovn_attach n1 br-phys 192.168.0.$i
1405
1406 for j in 1 2 3; do
1407 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 1408 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1409 if test $j = 1; then
31ed1192 1410 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1411 else
7dc88496
NS
1412 if test $j = 3; then
1413 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1414 else
1415 ip_addrs="192.168.0.$i$j"
1416 fi
31ed1192
JP
1417 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1418 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1419 fi
1420 done
1421done
1422ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1423ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1424ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1425ovn-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\"
1426ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b 1427
3d2848ba
HZ
1428get_lsp_uuid () {
1429 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1430}
1431
1432ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1433ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1434
f295c17b
BP
1435# Pre-populate the hypervisors' ARP tables so that we don't lose any
1436# packets for ARP resolution (native tunneling doesn't queue packets
1437# for ARP resolution).
74868f2c 1438OVN_POPULATE_ARP
f295c17b
BP
1439
1440# Allow some time for ovn-northd and ovn-controller to catch up.
1441# XXX This should be more systematic.
1442sleep 1
611099dc 1443
fc6f9978
HZ
1444# Make sure there is no attempt to adding duplicated flows by ovn-controller
1445AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1446AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1447AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1448
57d143eb
HZ
1449# Given the name of a logical port, prints the name of the hypervisor
1450# on which it is located.
1451vif_to_hv() {
1452 echo hv${1%?}
1453}
1454
f295c17b
BP
1455# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1456#
1457# This shell function causes a packet to be received on INPORT. The packet's
1458# content has Ethernet destination DST and source SRC (each exactly 12 hex
1459# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1460# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1461# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1462for i in 1 2 3; do
1463 for j in 1 2 3; do
1464 : > $i$j.expected
1465 done
1466done
1467test_packet() {
1468 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1469 hv=`vif_to_hv $inport`
f295c17b
BP
1470 vif=vif$inport
1471 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1472 for outport; do
e4543cfe 1473 echo $packet >> $outport.expected
f295c17b
BP
1474 done
1475}
1476
57d143eb
HZ
1477# test_arp INPORT SHA SPA TPA [REPLY_HA]
1478#
1479# Causes a packet to be received on INPORT. The packet is an ARP
1480# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1481# it should be the hardware address of the target to expect to receive in an
1482# ARP reply; otherwise no reply is expected.
1483#
31ed1192 1484# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1485# SHA and REPLY_HA are each 12 hex digits.
1486# SPA and TPA are each 8 hex digits.
1487test_arp() {
1488 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1489 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1490 hv=`vif_to_hv $inport`
1491 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1492
92f9822b 1493 if test X$reply_ha = X; then
57d143eb
HZ
1494 # Expect to receive the broadcast ARP on the other logical switch ports
1495 # if no reply is expected.
1496 local i j
1497 for i in 1 2 3; do
1498 for j in 1 2 3; do
1499 if test $i$j != $inport; then
1500 echo $request >> $i$j.expected
1501 fi
1502 done
1503 done
1504 else
1505 # Expect to receive the reply, if any.
1506 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1507 echo $reply >> $inport.expected
1508 fi
1509}
1510
1511ip_to_hex() {
1512 printf "%02x%02x%02x%02x" "$@"
1513}
1514
f295c17b
BP
1515# Send packets between all pairs of source and destination ports:
1516#
31ed1192
JP
1517# 1. Unicast packets are delivered to exactly one logical switch port
1518# (except that packets destined to their input ports are dropped).
f295c17b 1519#
31ed1192
JP
1520# 2. Broadcast and multicast are delivered to all logical switch ports
1521# except the input port.
f295c17b 1522#
ea46a4e9 1523# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1524# MAC address.
1525#
ea46a4e9 1526# 4. The switch drops all packets with a VLAN tag.
f295c17b 1527#
ea46a4e9 1528# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1529# affects behavior when port security is turned off, since otherwise port
1530# security would drop the packet anyway.)
1531#
ea46a4e9 1532# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1533# switch ports with "unknown" among their MAC addresses (and port
1534# security disabled).
f295c17b 1535#
ea46a4e9 1536# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1537#
ea46a4e9 1538# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1539#
9fcb6a18
BP
1540# 9. OVN generates responses to ARP requests for known IPs, except for
1541# requests from a port for the port's own IP.
57d143eb
HZ
1542#
1543# 10. No response to ARP requests for unknown IPs.
4acd1e87 1544
f295c17b
BP
1545for is in 1 2 3; do
1546 for js in 1 2 3; do
1547 s=$is$js
1548 bcast=
4d5c43d5
JP
1549 unknown=
1550 bacl2=
1551 bacl3=
f295c17b
BP
1552 for id in 1 2 3; do
1553 for jd in 1 2 3; do
1554 d=$id$jd
1555
1556 if test $d != $s; then unicast=$d; else unicast=; fi
1557 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1558
1559 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1560 impersonate=$d
1561 else
1562 impersonate=
1563 fi
f295c17b
BP
1564 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1565
4d5c43d5
JP
1566 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1567 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1568 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1569 # Source of 11, 21, or 31 and dest of 33 should be dropped
1570 # due to the 4th ACL that uses address_set(set1).
1571 acl4=
1572 else
1573 acl4=$d
1574 fi
3d2848ba
HZ
1575 if test $d = $s || test $d = 22 || test $d = 33; then
1576 # dest of 22 and 33 should be dropped
1577 # due to the 5th ACL that uses port_group(pg1).
1578 acl5=
1579 else
1580 acl5=$d
1581 fi
f295c17b
BP
1582 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1583 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1584 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1585 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
3d2848ba 1586 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
f295c17b
BP
1587
1588 test_packet $s f000000000$d f00000000055 810000091234 #4
1589 test_packet $s f000000000$d 0100000000$s $s$d #5
1590
4d5c43d5
JP
1591 if test $d != $s && test $jd = 1; then
1592 unknown="$unknown $d"
1593 fi
f295c17b
BP
1594 bcast="$bcast $unicast"
1595 bacl2="$bacl2 $acl2"
1596 bacl3="$bacl3 $acl3"
57d143eb 1597
db02f370 1598 sip=`ip_to_hex 192 168 0 $is$js`
57d143eb
HZ
1599 tip=`ip_to_hex 192 168 0 $id$jd`
1600 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1601 if test $d != $s; then
1602 reply_ha=f000000000$d
1603 else
1604 reply_ha=
1605 fi
1606 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1607 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1608
1609 if test $jd = 3; then
31ed1192 1610 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1611 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1612 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1613 fi
f295c17b
BP
1614 done
1615 done
1616
4d5c43d5 1617 # Broadcast and multicast.
f295c17b
BP
1618 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1619 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1620 if test $js = 1; then
f295c17b
BP
1621 bcast_impersonate=$bcast
1622 else
4d5c43d5
JP
1623 bcast_impersonate=
1624 fi
f295c17b
BP
1625 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1626
1627 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1628
1629 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1630 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1631 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1632 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1633 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1634 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1635 done
1636done
1637
7dc88496
NS
1638# set address for lp13 with invalid characters.
1639# lp13 should be configured with only 192.168.0.13.
31ed1192 1640ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1641
1642# Allow some time for ovn-northd and ovn-controller to catch up.
1643# XXX This should be more systematic.
1644sleep 1
1645
7dc88496
NS
1646sip=`ip_to_hex 192 168 0 11`
1647tip=`ip_to_hex 192 168 0 13`
1648test_arp 11 f00000000011 $sip $tip f00000000013
1649
1650tip=`ip_to_hex 192 169 0 13`
1651#arp request for 192.169.0.13 should be flooded
1652test_arp 11 f00000000011 $sip $tip
1653
91125642 1654# dump information and flows with counters
bb0c41d3
RM
1655ovn-sbctl dump-flows -- list multicast_group
1656
1657echo "------ hv1 dump ------"
1658as hv1 ovs-vsctl show
1659as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1660
1661echo "------ hv2 dump ------"
1662as hv2 ovs-vsctl show
1663as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1664
1665echo "------ hv3 dump ------"
1666as hv3 ovs-vsctl show
1667as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1668
f295c17b
BP
1669# Now check the packets actually received against the ones expected.
1670for i in 1 2 3; do
1671 for j in 1 2 3; do
49d7c759 1672 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1673 done
1674done
fcde56f5 1675
7a8f15e0 1676OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1677
f295c17b 1678AT_CLEANUP
eb6b08eb 1679
1f4a175e 1680# 2 hypervisors, one logical switch, 2 logical ports per hypervisor
1681# logical ports bound to chassis encap-ip.
1682AT_SETUP([ovn -- 2 HVs, 1 LS, 2 lports/HV])
1683AT_KEYWORDS([ovnarp])
1684AT_SKIP_IF([test $HAVE_PYTHON = no])
1685ovn_start
1686
1687# Create hypervisors hv[12].
1688# Add vif1[12] to hv1, vif2[12] to hv2
1689ovn-nbctl ls-add lsw0
1690net_add n1
1691for i in 1 2; do
1692 sim_add hv$i
1693 as hv$i
1694 ovs-vsctl add-br br-phys
1695 ovn_attach n1 br-phys 192.168.0.$i
1696
1697 for j in 1 2; do
1698 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
1699 ovn-nbctl lsp-add lsw0 lp$i$j
1700 ip_addrs="192.168.0.$i$j"
1701 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
abf11558 1702 ovn-nbctl --wait=hv lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1f4a175e 1703 done
1704done
1705
1706get_lsp_uuid () {
1707 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1708}
1709
1710# XXX-Check how to pass lp$i1 in AT_CHECK_UNQUOTED, for now just do it
1711# explictly
1712
1713# For Chassis hv1
1714AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp11], [0], [dnl
1715encap : [[]]
1716])
1717AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp12], [0], [dnl
1718encap : [[]]
1719])
1720
1721# For Chassis hv2
1722AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp21], [0], [dnl
1723encap : [[]]
1724])
1725AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp22], [0], [dnl
1726encap : [[]]
1727])
1728
1729# Bind the ports to the encap-ip
1730for i in 1 2; do
1731 for j in 1 2; do
1732 as hv$i
1733 ovs-vsctl set Interface vif$i$j external-ids:encap-ip=192.168.0.$i
1734 done
1735done
1736
1737sleep 1
1738
1739# dump port bindings; since we have vxlan and geneve tunnels, we expect the
1740# ports to be bound to geneve tunnels.
1741
1742# For Chassis 1
1743encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv1 type=geneve ip=192.168.0.1`
1744
1745AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp11], [0], [dnl
1746encap : ${encap_rec}
1747])
1748
1749AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp12], [0], [dnl
1750encap : ${encap_rec}
1751])
1752
1753# For Chassis 2
1754encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv2 type=geneve ip=192.168.0.2`
1755
1756AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp21], [0], [dnl
1757encap : ${encap_rec}
1758])
1759
1760AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp22], [0], [dnl
1761encap : ${encap_rec}
1762])
1763
1764# Pre-populate the hypervisors' ARP tables so that we don't lose any
1765# packets for ARP resolution (native tunneling doesn't queue packets
1766# for ARP resolution).
1767OVN_POPULATE_ARP
1768
1769# Allow some time for ovn-northd and ovn-controller to catch up.
1770# XXX This should be more systematic.
1771sleep 1
1772
1773# Make sure there is no attempt to adding duplicated flows by ovn-controller
1774AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1775AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1776AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1777
1778# Given the name of a logical port, prints the name of the hypervisor
1779# on which it is located.
1780vif_to_hv() {
1781 echo hv${1%?}
1782}
1783
1784# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1785#
1786# This shell function causes a packet to be received on INPORT. The packet's
1787# content has Ethernet destination DST and source SRC (each exactly 12 hex
1788# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1789# more) list the VIFs on which the packet should be received. INPORT and the
1790# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1791for i in 1 2; do
1792 for j in 1 2; do
1793 : > $i$j.expected
1794 done
1795done
1796test_packet() {
1797 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1798 hv=`vif_to_hv $inport`
1799 vif=vif$inport
1800 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1801 for outport; do
1802 echo $packet >> $outport.expected
1803 done
1804}
1805
1806ip_to_hex() {
1807 printf "%02x%02x%02x%02x" "$@"
1808}
1809
1810# Send packets between all pairs of source and destination ports:
1811#
1812# 1. Unicast packets are delivered to exactly one logical switch port
1813# (except that packets destined to their input ports are dropped).
1814
1815for is in 1 2; do
1816 for js in 1 2; do
1817 s=$is$js
1818 bcast=
1819 unknown=
1820 bacl2=
1821 bacl3=
1822 for id in 1 2 3; do
1823 for jd in 1 2 3; do
1824 d=$id$jd
1825
1826 if test $d != $s; then unicast=$d; else unicast=; fi
1827 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1828 done
1829 done
1830
1831 done
1832done
1833
1834# dump information and flows with counters
1835ovn-sbctl dump-flows -- list multicast_group
1836
1837echo "------ hv1 dump ------"
1838as hv1 ovs-vsctl show
1839as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1840
1841echo "------ hv2 dump ------"
1842as hv2 ovs-vsctl show
1843as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1844
1845echo "------ hv3 dump ------"
1846as hv3 ovs-vsctl show
1847as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1848
1849# Now check the packets actually received against the ones expected.
1850for i in 1 2; do
1851 for j in 1 2; do
1852 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1853 done
1854done
1855
1856OVN_CLEANUP([hv1],[hv2])
1857
1858AT_CLEANUP
1859
4acd1e87
BP
1860AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1861AT_SKIP_IF([test $HAVE_PYTHON = no])
1862ovn_start
1863
1864# Create a logical switch and some logical ports.
1865# Turn on port security on all lports except ls1.
1866# Make ls1 a destination for unknown MACs.
1867# Add some ACLs for Ethertypes 1234, 1235, 1236.
1868ovn-nbctl ls-add lsw0
1869ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1870for i in 1 2 3; do
1871 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1872done
1873ovn-nbctl --wait=sb sync
1874for i in 1 2 3; do
4acd1e87
BP
1875 ovn-sbctl lsp-bind lp$i hv0
1876 if test $i = 1; then
abb37b6b 1877 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1878 else
abb37b6b
FF
1879 if test $i = 3; then
1880 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1881 else
1882 ip_addrs="192.168.0.$i"
1883 fi
a8e2addc
LR
1884 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1885 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
4acd1e87
BP
1886 fi
1887done
1888ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1889ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1890ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1891ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1892ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1893
1894ovn-nbctl --wait=sb sync
1895on_exit 'kill `cat ovn-trace.pid`'
1896ovn-trace --detach --pidfile --no-chdir
1897
1898# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1899#
1900# This shell function causes a packet to be received on INPORT. The packet's
1901# content has Ethernet destination DST and source SRC (each exactly 12 hex
1902# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1903# more) list the VIFs on which the packet should be received. INPORT and the
1904# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1905test_packet() {
1906 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1907 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1908 while :; do
abb37b6b
FF
1909 case $1 in # (
1910 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1911 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1912 *) break ;;
1913 esac
4acd1e87
BP
1914 done
1915 for outport; do
abb37b6b 1916 echo "output(\"lp$outport\");"
4acd1e87
BP
1917 done > expout
1918
1919 AT_CAPTURE_FILE([trace])
1920 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1921}
1922
1923# test_arp INPORT SHA SPA TPA [REPLY_HA]
1924#
1925# Causes a packet to be received on INPORT. The packet is an ARP
1926# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1927# it should be the hardware address of the target to expect to receive in an
1928# ARP reply; otherwise no reply is expected.
1929#
1930# INPORT is an logical switch port number, e.g. 11 for vif11.
1931# SHA and REPLY_HA are each 12 hex digits.
1932# SPA and TPA are each 8 hex digits.
1933test_arp() {
1934 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1935
1936 local request="inport == \"lp$inport\"
1937 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1938 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1939 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1940
1941 if test -z "$reply_ha"; then
1942 reply=
abb37b6b
FF
1943 local i
1944 for i in 1 2 3; do
1945 if test $i != $inport; then
1946 reply="${reply}output(\"lp$i\");
4acd1e87 1947"
abb37b6b
FF
1948 fi
1949 done
4acd1e87
BP
1950 else
1951 reply="\
1952eth.dst = $sha;
1953eth.src = $reply_ha;
1954arp.op = 2;
1955arp.tha = $sha;
1956arp.sha = $reply_ha;
1957arp.tpa = $spa;
1958arp.spa = $tpa;
1959output(\"lp$inport\");
1960"
1961 fi
1962
1963 AT_CAPTURE_FILE([trace])
1964 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1965}
1966
1967# Send packets between all pairs of source and destination ports:
1968#
1969# 1. Unicast packets are delivered to exactly one logical switch port
1970# (except that packets destined to their input ports are dropped).
1971#
1972# 2. Broadcast and multicast are delivered to all logical switch ports
1973# except the input port.
1974#
1975# 3. When port security is turned on, the switch drops packets from the wrong
1976# MAC address.
1977#
1978# 4. The switch drops all packets with a VLAN tag.
1979#
1980# 5. The switch drops all packets with a multicast source address. (This only
1981# affects behavior when port security is turned off, since otherwise port
1982# security would drop the packet anyway.)
1983#
1984# 6. The switch delivers packets with an unknown destination to logical
1985# switch ports with "unknown" among their MAC addresses (and port
1986# security disabled).
1987#
1988# 7. The switch drops unicast packets that violate an ACL.
1989#
1990# 8. The switch drops multicast and broadcast packets that violate an ACL.
1991#
9fcb6a18
BP
1992# 9. OVN generates responses to ARP requests for known IPs, except for
1993# requests from a port for the port's own IP.
4acd1e87
BP
1994#
1995# 10. No response to ARP requests for unknown IPs.
1996
1997for s in 1 2 3; do
1998 bcast=
1999 unknown=
2000 bacl2=
2001 bacl3=
2002 for d in 1 2 3; do
abb37b6b
FF
2003 echo
2004 echo "lp$s -> lp$d"
2005 if test $d != $s; then unicast=$d; else unicast=; fi
2006 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
2007
2008 if test $d != $s && test $s = 1; then
2009 impersonate=$d
2010 else
2011 impersonate=
2012 fi
2013 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
2014
2015 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
2016 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
2017 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
2018 # Source of 1 or 2 and dest of 3 should be dropped
2019 # due to the 4th ACL that uses address_set(set1).
2020 acl4=
2021 else
2022 acl4=$d
2023 fi
2024
2025 #7, acl1 to acl4:
2026 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
2027 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
2028 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
2029 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
2030
2031 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
2032 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
2033
2034 if test $d != $s && test $d = 1; then
2035 unknown="$unknown $d"
2036 fi
2037 bcast="$bcast $unicast"
2038 bacl2="$bacl2 $acl2"
2039 bacl3="$bacl3 $acl3"
2040
2041 sip=192.168.0.$s
2042 tip=192.168.0.$d
2043 tip_unknown=11.11.11.11
9fcb6a18
BP
2044 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
2045 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
2046 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
2047
2048 if test $d = 3; then
2049 # lp3 has an additional ip 192.169.0.[123]3.
2050 tip=192.169.0.$d
9fcb6a18 2051 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 2052 fi
4acd1e87
BP
2053 done
2054
2055 # Broadcast and multicast.
2056 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
2057 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
2058 if test $s = 1; then
abb37b6b 2059 bcast_impersonate=$bcast
4acd1e87 2060 else
abb37b6b 2061 bcast_impersonate=
4acd1e87
BP
2062 fi
2063 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
2064
2065 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
2066
2067 #8, acl1 to acl3:
2068 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
2069 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
2070 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
2071
2072 #8, acl1 to acl3:
2073 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
2074 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
2075 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
2076done
2077
2078AT_CLEANUP
2079
7277bc83
RB
2080# 2 hypervisors, 4 logical ports per HV
2081# 2 locally attached networks (one flat, one vlan tagged over same device)
2082# 2 ports per HV on each network
e90aeb57 2083AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
2084AT_SKIP_IF([test $HAVE_PYTHON = no])
2085ovn_start
2086
ea46a4e9
JP
2087# In this test cases we create 3 switches, all connected to same
2088# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
2089# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
2090# of VIF port name indicates the hypervisor it is bound to, e.g.
2091# lp23 means VIF 3 on hv2.
2092#
ea46a4e9 2093# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
2094# - ls1:
2095# - untagged
ea46a4e9 2096# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
2097#
2098# - ls2:
2099# - tagged with VLAN 101
ea46a4e9 2100# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
2101# - ls3:
2102# - untagged
ea46a4e9 2103# - ports: lp15, lp25
0ee7f7f1 2104#
ea46a4e9 2105# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
2106# physical network.
2107
2108for i in 1 2 3; do
ea46a4e9
JP
2109 ls_name=ls$i
2110 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
2111 ln_port_name=ln$i
2112 if test $i -eq 2; then
ea46a4e9 2113 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 2114 else
ea46a4e9 2115 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 2116 fi
31ed1192
JP
2117 ovn-nbctl lsp-set-addresses $ln_port_name unknown
2118 ovn-nbctl lsp-set-type $ln_port_name localnet
2119 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 2120done
d79fc5f4 2121
69b72264
BP
2122# lsp_to_ls LSP
2123#
2124# Prints the name of the logical switch that contains LSP.
2125lsp_to_ls () {
2126 case $1 in dnl (
5a0e4aec
BP
2127 lp?[[12]]) echo ls1 ;; dnl (
2128 lp?[[34]]) echo ls2 ;; dnl (
2129 lp?5) echo ls3 ;; dnl (
2130 *) AT_FAIL_IF([:]) ;;
69b72264
BP
2131 esac
2132}
2133
d79fc5f4
RB
2134net_add n1
2135for i in 1 2; do
2136 sim_add hv$i
2137 as hv$i
2138 ovs-vsctl add-br br-phys
2139 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
2140 ovn_attach n1 br-phys 192.168.0.$i
2141
0ee7f7f1 2142 for j in 1 2 3 4 5; do
d79fc5f4
RB
2143 ovs-vsctl add-port br-int vif$i$j -- \
2144 set Interface vif$i$j external-ids:iface-id=lp$i$j \
2145 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
2146 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
2147 ofport-request=$i$j
2148
31ed1192 2149 lsp_name=lp$i$j
5a0e4aec 2150 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 2151
ea46a4e9 2152 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
2153 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
2154 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 2155
31ed1192 2156 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
2157 done
2158done
69b72264
BP
2159ovn-nbctl --wait=sb sync
2160ovn-sbctl dump-flows
d79fc5f4 2161
74868f2c 2162OVN_POPULATE_ARP
d79fc5f4
RB
2163
2164# XXX This is now the 3rd copy of these functions in this file ...
2165
2166# Given the name of a logical port, prints the name of the hypervisor
2167# on which it is located.
2168vif_to_hv() {
2169 echo hv${1%?}
2170}
2171#
69b72264 2172# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
2173#
2174# This shell function causes a packet to be received on INPORT. The packet's
2175# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
2176# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
2177# logical switch port numbers, e.g. 11 for vif11.
2178#
2179# EOUT is the end-to-end output port, that is, where the packet will end up
2180# after possibly bouncing through one or more localnet ports. LOUT is the
2181# logical output port, which might be a localnet port, as seen by ovn-trace
2182# (which doesn't know what localnet ports are connected to and therefore can't
2183# figure out the end-to-end answer).
d79fc5f4 2184for i in 1 2; do
0ee7f7f1 2185 for j in 1 2 3 4 5; do
d79fc5f4
RB
2186 : > $i$j.expected
2187 done
2188done
2189test_packet() {
69b72264
BP
2190 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
2191 echo "$@"
2192
2193 # First try tracing the packet.
2194 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
2195 if test $lout != drop; then
2196 echo "output(\"$lout\");"
2197 fi > expout
2198 AT_CAPTURE_FILE([trace])
2199 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
2200
2201 # Then actually send a packet, for an end-to-end test.
2202 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
2203 hv=`vif_to_hv $inport`
2204 vif=vif$inport
2205 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
2206 if test $eout != drop; then
2207 echo $packet >> ${eout#lp}.expected
2208 fi
d79fc5f4
RB
2209}
2210
7277bc83
RB
2211# lp11 and lp21 are on the same network (phys, untagged)
2212# and on different hypervisors
69b72264
BP
2213test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
2214test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 2215
7277bc83
RB
2216# lp11 and lp12 are on the same network (phys, untagged)
2217# and on the same hypervisor
69b72264
BP
2218test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
2219test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
2220
2221# lp13 and lp23 are on the same network (phys, VLAN 101)
2222# and on different hypervisors
69b72264
BP
2223test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
2224test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
2225
2226# lp13 and lp14 are on the same network (phys, VLAN 101)
2227# and on the same hypervisor
69b72264
BP
2228test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
2229test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 2230
0ee7f7f1 2231# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 2232# same hypervisor, and on different switches
69b72264
BP
2233test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2234test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
2235
2236# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 2237# different hypervisors, and on different switches
69b72264
BP
2238test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2239test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 2240
d79fc5f4 2241# Ports that should not be able to communicate
69b72264
BP
2242test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2243test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2244test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2245test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2246test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2247test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2248test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2249test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 2250
d79fc5f4
RB
2251# Dump a bunch of info helpful for debugging if there's a failure.
2252
2253echo "------ OVN dump ------"
2254ovn-nbctl show
2255ovn-sbctl show
2256
2257echo "------ hv1 dump ------"
2258as hv1 ovs-vsctl show
2259as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2260
2261echo "------ hv2 dump ------"
2262as hv2 ovs-vsctl show
2263as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2264
2265# Now check the packets actually received against the ones expected.
2266for i in 1 2; do
0ee7f7f1 2267 for j in 1 2 3 4 5; do
49d7c759 2268 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
2269 done
2270done
2271
7a8f15e0 2272OVN_CLEANUP([hv1],[hv2])
d9c8c57c 2273
d79fc5f4
RB
2274AT_CLEANUP
2275
91125642
FF
2276AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2277AT_KEYWORDS([vtep])
eb6b08eb
JP
2278AT_SKIP_IF([test $HAVE_PYTHON = no])
2279ovn_start
2280
2281# Configure the Northbound database
ea46a4e9 2282ovn-nbctl ls-add lsw0
eb6b08eb 2283
31ed1192
JP
2284ovn-nbctl lsp-add lsw0 lp1
2285ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 2286
31ed1192
JP
2287ovn-nbctl lsp-add lsw0 lp2
2288ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 2289
31ed1192
JP
2290ovn-nbctl lsp-add lsw0 lp-vtep
2291ovn-nbctl lsp-set-type lp-vtep vtep
2292ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2293ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 2294
77adbb62
DB
2295# lpr, lr and lrp1 are used for the ARP request handling test only.
2296ovn-nbctl lsp-add lsw0 lpr
2297ovn-nbctl lr-add lr
2298ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2299ovn-nbctl set Logical_Switch_Port lpr type=router \
2300 options:router-port=lrp1 \
2301 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2302
2303
eb6b08eb
JP
2304net_add n1 # Network to connect hv1, hv2, and vtep
2305net_add n2 # Network to connect vtep and hv3
2306
2307# Create hypervisor hv1 connected to n1
2308sim_add hv1
2309as hv1
2310ovs-vsctl add-br br-phys
2311ovn_attach n1 br-phys 192.168.0.1
2312ovs-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
2313
2314# Create hypervisor hv2 connected to n1
2315sim_add hv2
2316as hv2
2317ovs-vsctl add-br br-phys
2318ovn_attach n1 br-phys 192.168.0.2
2319ovs-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
2320
2321
2322# Start the vtep emulator with a leg in both networks
2323sim_add vtep
2324as vtep
2325
2326ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2327ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2328
2329ovs-vsctl add-br br-phys
2330net_attach n1 br-phys
2331
2332mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2333arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2334ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2335ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2336
2337ovs-vsctl add-br br-vtep
2338net_attach n2 br-vtep
2339
2340vtep-ctl add-ps br-vtep
2341vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2342vtep-ctl add-ls lsw0
2343
2344start_daemon ovs-vtep br-vtep
2345start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2346
8cdc4312 2347OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 2348
475f0a2c
DB
2349OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2350 grep -- source`"])
2351# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
2352sleep 1
2353
2354# Add hv3 on the other side of the vtep
2355sim_add hv3
2356as hv3
2357ovs-vsctl add-br br-phys
2358net_attach n2 br-phys
2359
2360ovs-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
2361
2362# Pre-populate the hypervisors' ARP tables so that we don't lose any
2363# packets for ARP resolution (native tunneling doesn't queue packets
2364# for ARP resolution).
74868f2c 2365OVN_POPULATE_ARP
eb6b08eb
JP
2366
2367# Allow some time for ovn-northd and ovn-controller to catch up.
2368# XXX This should be more systematic.
2369sleep 1
6977df72 2370
eb6b08eb
JP
2371# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2372#
2373# This shell function causes a packet to be received on INPORT. The packet's
2374# content has Ethernet destination DST and source SRC (each exactly 12 hex
2375# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2376# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2377# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
2378for i in 1 2 3; do
2379 : > $i.expected
2380done
2381test_packet() {
2382 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2383 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2384 hv=hv$inport
2385 vif=vif$inport
2386 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2387 for outport; do
e4543cfe 2388 echo $packet >> $outport.expected
eb6b08eb
JP
2389 done
2390}
2391
2392# Send packets between all pairs of source and destination ports:
2393#
31ed1192
JP
2394# 1. Unicast packets are delivered to exactly one logical switch port
2395# (except that packets destined to their input ports are dropped).
eb6b08eb 2396#
31ed1192
JP
2397# 2. Broadcast and multicast are delivered to all logical switch ports
2398# except the input port.
eb6b08eb 2399#
ea46a4e9 2400# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
2401# switch ports with "unknown" among their MAC addresses (and port
2402# security disabled).
eb6b08eb
JP
2403for s in 1 2 3; do
2404 bcast=
2405 unknown=
2406 for d in 1 2 3; do
2407 if test $d != $s; then unicast=$d; else unicast=; fi
2408 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2409
2410 # The vtep (vif3) is the only one configured for "unknown"
2411 if test $d != $s && test $d = 3; then
2412 unknown="$unknown $d"
2413 fi
2414 bcast="$bcast $unicast"
2415 done
2416
2417 # Broadcast and multicast.
46ed1382
DB
2418 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2419 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
2420
2421 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2422done
2423
77adbb62
DB
2424# ARP request should not be responded to by logical switch router
2425# type arp responder on HV1 and HV2 and should reach directly to
2426# vif1 and vif2
2427ip_to_hex() {
2428 printf "%02x%02x%02x%02x" "$@"
2429}
2430sha=f00000000003
2431spa=`ip_to_hex 192 168 1 2`
2432tpa=`ip_to_hex 192 168 1 1`
2433request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2434as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2435echo $request >> 1.expected
2436echo $request >> 2.expected
2437
bb0c41d3
RM
2438# dump information with counters
2439echo "------ OVN dump ------"
2440ovn-nbctl show
2441ovn-sbctl show
2442
77adbb62
DB
2443echo "---------SB dump-----"
2444ovn-sbctl list datapath_binding
2445echo "---------------------"
2446ovn-sbctl list port_binding
2447echo "---------------------"
2448ovn-sbctl dump-flows
2449
bb0c41d3
RM
2450echo "------ hv1 dump ------"
2451as hv1 ovs-vsctl show
6195e2e7 2452as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2453as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2454
2455echo "------ hv2 dump ------"
2456as hv2 ovs-vsctl show
6195e2e7 2457as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2458as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2459
2460echo "------ hv3 dump ------"
2461as hv3 ovs-vsctl show
6754e92d
FF
2462# note: hv3 has no logical port bind, thus it should not have br-int
2463AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2464[ovs-ofctl: br-int is not a bridge or a socket
2465])
bb0c41d3 2466
eb6b08eb
JP
2467# Now check the packets actually received against the ones expected.
2468for i in 1 2 3; do
49d7c759 2469 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 2470done
fcde56f5
LR
2471
2472# Gracefully terminate daemons
7a8f15e0
LR
2473OVN_CLEANUP([hv1],[hv2],[vtep])
2474OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 2475
eb6b08eb 2476AT_CLEANUP
9975d7be 2477
184bc3ca
RB
2478# Similar test to "hardware GW"
2479AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2480AT_SKIP_IF([test $HAVE_PYTHON = no])
2481ovn_start
2482
2483# Configure the Northbound database
2484ovn-nbctl ls-add lsw0
2485
2486ovn-nbctl lsp-add lsw0 lp1
2487ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2488
2489ovn-nbctl lsp-add lsw0 lp2
2490ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2491
2492ovn-nbctl lsp-add lsw0 lp-gw
2493ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 2494ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
2495ovn-nbctl lsp-set-addresses lp-gw unknown
2496
2497net_add n1 # Network to connect hv1, hv2, and gw
2498net_add n2 # Network to connect gw and hv3
2499
2500# Create hypervisor hv1 connected to n1
2501sim_add hv1
2502as hv1
2503ovs-vsctl add-br br-phys
2504ovn_attach n1 br-phys 192.168.0.1
2505ovs-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
2506
2507# Create hypervisor hv2 connected to n1
2508sim_add hv2
2509as hv2
2510ovs-vsctl add-br br-phys
2511ovn_attach n1 br-phys 192.168.0.2
2512ovs-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
2513
2514# Create hypervisor hv_gw connected to n1 and n2
2515# connect br-phys bridge to n1; connect hv-gw bridge to n2
2516sim_add hv_gw
2517as hv_gw
2518ovs-vsctl add-br br-phys
2519ovn_attach n1 br-phys 192.168.0.3
2520ovs-vsctl add-br br-phys2
2521net_attach n2 br-phys2
2522ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2523
184bc3ca
RB
2524# Add hv3 on the other side of the GW
2525sim_add hv3
2526as hv3
2527ovs-vsctl add-br br-phys
2528net_attach n2 br-phys
2529ovs-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
2530
2531
2532# Pre-populate the hypervisors' ARP tables so that we don't lose any
2533# packets for ARP resolution (native tunneling doesn't queue packets
2534# for ARP resolution).
74868f2c 2535OVN_POPULATE_ARP
184bc3ca
RB
2536
2537# Allow some time for ovn-northd and ovn-controller to catch up.
2538# XXX This should be more systematic.
2539sleep 1
2540
2541# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2542#
2543# This shell function causes a packet to be received on INPORT. The packet's
2544# content has Ethernet destination DST and source SRC (each exactly 12 hex
2545# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2546# more) list the VIFs on which the packet should be received. INPORT and the
2547# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
2548for i in 1 2 3; do
2549 : > $i.expected
2550done
2551test_packet() {
2552 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2553 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2554 hv=hv$inport
2555 vif=vif$inport
2556 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2557 for outport; do
e4543cfe 2558 echo $packet >> $outport.expected
184bc3ca
RB
2559 done
2560}
2561
2562# Send packets between all pairs of source and destination ports:
2563#
2564# 1. Unicast packets are delivered to exactly one lport (except that packets
2565# destined to their input ports are dropped).
2566#
2567# 2. Broadcast and multicast are delivered to all lports except the input port.
2568#
2569# 3. The lswitch delivers packets with an unknown destination to lports with
2570# "unknown" among their MAC addresses (and port security disabled).
2571for s in 1 2 3 ; do
2572 bcast=
2573 unknown=
2574 for d in 1 2 3 ; do
2575 if test $d != $s; then unicast=$d; else unicast=; fi
2576 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2577
2578 # The vtep (vif3) is the only one configured for "unknown"
2579 if test $d != $s && test $d = 3; then
2580 unknown="$unknown $d"
2581 fi
2582 bcast="$bcast $unicast"
2583 done
2584
2585 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2586 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2587 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2588done
2589
184bc3ca
RB
2590echo "------ ovn-nbctl show ------"
2591ovn-nbctl show
2592echo "------ ovn-sbctl show ------"
2593ovn-sbctl show
2594
2595echo "------ hv1 ------"
2596as hv1 ovs-vsctl show
2597echo "------ hv1 br-int ------"
2598as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2599echo "------ hv1 br-phys ------"
2600as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2601
2602echo "------ hv2 ------"
2603as hv2 ovs-vsctl show
2604echo "------ hv2 br-int ------"
2605as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2606echo "------ hv2 br-phys ------"
2607as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2608
2609echo "------ hv_gw ------"
2610as hv_gw ovs-vsctl show
2611echo "------ hv_gw br-phys ------"
2612as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2613echo "------ hv_gw br-phys2 ------"
2614as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2615
2616echo "------ hv3 ------"
2617as hv3 ovs-vsctl show
2618echo "------ hv3 br-phys ------"
2619as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2620
2621# Now check the packets actually received against the ones expected.
2622for i in 1 2 3; do
49d7c759 2623 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2624done
2625AT_CLEANUP
2626
9975d7be
BP
2627# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2628AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2629AT_SKIP_IF([test $HAVE_PYTHON = no])
2630ovn_start
2631
2632# Logical network:
2633#
2634# Three logical switches ls1, ls2, ls3.
86e98048
BP
2635# One logical router lr0 connected to ls[123],
2636# with nine subnets, three per logical switch:
2637#
2638# lrp11 on ls1 for subnet 192.168.11.0/24
2639# lrp12 on ls1 for subnet 192.168.12.0/24
2640# lrp13 on ls1 for subnet 192.168.13.0/24
2641# ...
2642# lrp33 on ls3 for subnet 192.168.33.0/24
2643#
2644# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2645# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2646for i in 1 2 3; do
ea46a4e9 2647 ovn-nbctl ls-add ls$i
9975d7be 2648 for j in 1 2 3; do
86e98048 2649 for k in 1 2 3; do
31ed1192
JP
2650 # Add "unknown" to MAC addresses for lp?11, so packets for
2651 # MAC-IP bindings discovered via ARP later have somewhere to go.
2652 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2653
2654 ovn-nbctl \
2655 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
2656 -- lsp-set-addresses lp$i$j$k \
2657 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
86e98048
BP
2658 done
2659 done
2660done
2661
fa2a27b2 2662ovn-nbctl lr-add lr0
86e98048
BP
2663for i in 1 2 3; do
2664 for j in 1 2 3; do
bf44c2cd 2665 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2666 ovn-nbctl \
31ed1192 2667 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2668 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2669 options:router-port=lrp$i$j \
86e98048 2670 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2671 done
2672done
2673
80f408f4 2674ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2675 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2676
9975d7be
BP
2677# Physical network:
2678#
2679# Three hypervisors hv[123].
86e98048
BP
2680# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2681# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2682# lp?3[123] all on hv3.
2683
9975d7be
BP
2684
2685# Given the name of a logical port, prints the name of the hypervisor
2686# on which it is located.
2687vif_to_hv() {
2688 case $1 in dnl (
86e98048
BP
2689 ?11) echo 1 ;; dnl (
2690 ?12 | ?21 | ?22) echo 2 ;; dnl (
2691 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2692 esac
2693}
2694
86e98048
BP
2695# Given the name of a logical port, prints the name of its logical router
2696# port, e.g. "vif_to_lrp 123" yields 12.
2697vif_to_lrp() {
2698 echo ${1%?}
2699}
2700
2701# Given the name of a logical port, prints the name of its logical
2702# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2703vif_to_ls() {
86e98048 2704 echo ${1%??}
e3393e3f
BP
2705}
2706
9975d7be
BP
2707net_add n1
2708for i in 1 2 3; do
2709 sim_add hv$i
2710 as hv$i
2711 ovs-vsctl add-br br-phys
2712 ovn_attach n1 br-phys 192.168.0.$i
2713done
2714for i in 1 2 3; do
2715 for j in 1 2 3; do
86e98048 2716 for k in 1 2 3; do
269ecccc
JP
2717 hv=`vif_to_hv $i$j$k`
2718 as hv$hv ovs-vsctl \
2719 -- add-port br-int vif$i$j$k \
2720 -- set Interface vif$i$j$k \
2721 external-ids:iface-id=lp$i$j$k \
2722 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2723 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2724 ofport-request=$i$j$k
86e98048 2725 done
9975d7be
BP
2726 done
2727done
2728
2729# Pre-populate the hypervisors' ARP tables so that we don't lose any
2730# packets for ARP resolution (native tunneling doesn't queue packets
2731# for ARP resolution).
74868f2c 2732OVN_POPULATE_ARP
9975d7be
BP
2733
2734# Allow some time for ovn-northd and ovn-controller to catch up.
2735# XXX This should be more systematic.
2736sleep 1
2737
e3393e3f 2738# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2739#
2740# This shell function causes a packet to be received on INPORT. The packet's
2741# content has Ethernet destination DST and source SRC (each exactly 12 hex
2742# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2743# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2744# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2745for i in 1 2 3; do
2746 for j in 1 2 3; do
86e98048
BP
2747 for k in 1 2 3; do
2748 : > $i$j$k.expected
269ecccc 2749 done
9975d7be
BP
2750 done
2751done
e3393e3f 2752test_ip() {
9975d7be
BP
2753 # This packet has bad checksums but logical L3 routing doesn't check.
2754 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2755 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2756 shift; shift; shift; shift; shift
2757 hv=hv`vif_to_hv $inport`
2758 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2759 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2760 in_ls=`vif_to_ls $inport`
2761 in_lrp=`vif_to_lrp $inport`
9975d7be 2762 for outport; do
269ecccc 2763 out_ls=`vif_to_ls $outport`
86e98048 2764 if test $in_ls = $out_ls; then
9975d7be
BP
2765 # Ports on the same logical switch receive exactly the same packet.
2766 echo $packet
2767 else
2768 # Routing decrements TTL and updates source and dest MAC
2769 # (and checksum).
269ecccc 2770 out_lrp=`vif_to_lrp $outport`
86e98048 2771 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2772 fi >> $outport.expected
9975d7be
BP
2773 done
2774}
2775
d7abfe39
LB
2776# test_arp INPORT SHA SPA TPA [REPLY_HA]
2777#
2778# Causes a packet to be received on INPORT. The packet is an ARP
2779# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2780# it should be the hardware address of the target to expect to receive in an
2781# ARP reply; otherwise no reply is expected.
2782#
2783# INPORT is an logical switch port number, e.g. 11 for vif11.
2784# SHA and REPLY_HA are each 12 hex digits.
2785# SPA and TPA are each 8 hex digits.
2786test_arp() {
2787 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2788 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2789 hv=hv`vif_to_hv $inport`
2790 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2791 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2792
2793 # Expect to receive the broadcast ARP on the other logical switch ports if
2794 # IP address is not configured to the switch patch port.
2795 local i=`vif_to_ls $inport`
2796 local j k
2797 for j in 1 2 3; do
2798 for k in 1 2 3; do
2799 # 192.168.33.254 is configured to the switch patch port for lrp33,
2800 # so no ARP flooding expected for it.
2801 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2802 echo $request >> $i$j$k.expected
2803 fi
2804 done
2805 done
2806
2807 # Expect to receive the reply, if any.
2808 if test X$reply_ha != X; then
2809 lrp=`vif_to_lrp $inport`
2810 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2811 echo $reply >> $inport.expected
2812 fi
2813}
2814
e3393e3f 2815as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2816as hv1 ovn-sbctl list port_binding
2817as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2818as hv1 ovn-sbctl dump-flows
2819as hv1 ovs-ofctl dump-flows br-int
2820
e3393e3f 2821# Send IP packets between all pairs of source and destination ports:
9975d7be 2822#
31ed1192
JP
2823# 1. Unicast IP packets are delivered to exactly one logical switch port
2824# (except that packets destined to their input ports are dropped).
9975d7be 2825#
31ed1192
JP
2826# 2. Broadcast IP packets are delivered to all logical switch ports
2827# except the input port.
86e98048
BP
2828ip_to_hex() {
2829 printf "%02x%02x%02x%02x" "$@"
2830}
9975d7be 2831for is in 1 2 3; do
269ecccc
JP
2832 for js in 1 2 3; do
2833 for ks in 1 2 3; do
2834 bcast=
2835 s=$is$js$ks
2836 smac=f00000000$s
2837 sip=`ip_to_hex 192 168 $is$js $ks`
2838 for id in 1 2 3; do
2839 for jd in 1 2 3; do
2840 for kd in 1 2 3; do
2841 d=$id$jd$kd
2842 dip=`ip_to_hex 192 168 $id$jd $kd`
2843 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2844 if test $d != $s; then unicast=$d; else unicast=; fi
2845
2846 test_ip $s $smac $dmac $sip $dip $unicast #1
2847
2848 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2849 done
2850 done
9975d7be 2851 done
269ecccc
JP
2852 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2853 done
2854 done
e3393e3f
BP
2855done
2856
d7abfe39
LB
2857: > mac_bindings.expected
2858
0bac7164
BP
2859# 3. Send an IP packet from every logical port to every other subnet,
2860# to an IP address that does not have a static IP-MAC binding.
2861# This should generate a broadcast ARP request for the destination
2862# IP address in the destination subnet.
d7abfe39 2863# Moreover generate an ARP reply for each of the IP addresses ARPed
0bac7164 2864for is in 1 2 3; do
269ecccc
JP
2865 for js in 1 2 3; do
2866 for ks in 1 2 3; do
2867 s=$is$js$ks
2868 smac=f00000000$s
2869 sip=`ip_to_hex 192 168 $is$js $ks`
2870 for id in 1 2 3; do
2871 for jd in 1 2 3; do
2872 if test $is$js = $id$jd; then
2873 continue
2874 fi
2875
2876 # Send the packet.
2877 dmac=00000000ff$is$js
2878 # Calculate a 4th octet for the destination that is
2879 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2880 # that have static MAC bindings, and fits in the range
2881 # 0-255.
2882 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2883 dip=`ip_to_hex 192 168 $id$jd $o4`
2884 test_ip $s $smac $dmac $sip $dip
2885
2886 # Every LP on the destination subnet's lswitch should
2887 # receive the ARP request.
2888 lrmac=00000000ff$id$jd
2889 lrip=`ip_to_hex 192 168 $id$jd 254`
2890 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2891 for jd2 in 1 2 3; do
2892 for kd in 1 2 3; do
e4543cfe 2893 echo $arp >> $id$jd2$kd.expected
0bac7164 2894 done
269ecccc 2895 done
1c24b2f4
LB
2896
2897 hmac=8000000000$o4
2898 rmac=00000000ff$id$jd
2899 echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
d7abfe39
LB
2900
2901 host_mac=8000000000$o4
2902 lrmac=00000000ff$id$jd
2903
2904 arp_reply=${lrmac}${host_mac}08060001080006040002${host_mac}${dip}${lrmac}${lrip}
2905
2906 hv=hv`vif_to_hv ${id}${jd}1`
2907 as $hv ovs-appctl netdev-dummy/receive vif${id}${jd}1 $arp_reply
2908
2909 host_ip_pretty=192.168.$id$jd.$o4
2910 host_mac_pretty=80:00:00:00:00:$o4
2911 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
0bac7164 2912 done
269ecccc 2913 done
0bac7164 2914 done
269ecccc 2915 done
0bac7164
BP
2916done
2917
e3393e3f
BP
2918# Test router replies to ARP requests from all source ports:
2919#
0bac7164 2920# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2921#
0bac7164 2922# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2923# in its subnet.
2924#
054008ad 2925# 6. No reply to query for IP address other than router IP.
e3393e3f 2926#
054008ad 2927# 7. No reply to query from another subnet.
e3393e3f 2928for i in 1 2 3; do
269ecccc
JP
2929 for j in 1 2 3; do
2930 for k in 1 2 3; do
2931 smac=f00000000$i$j$k # Source MAC
2932 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2933 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2934 rmac=00000000ff$i$j # Router MAC
2935 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
054008ad
HZ
2936 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2937
2938 test_arp $i$j$k $smac $sip $rip $rmac #4
2939 test_arp $i$j$k $smac $otherip $rip $rmac #5
2940 test_arp $i$j$k $smac $sip $otherip #6
2941
2942 # When rip is 192.168.33.254, ARP request from externalip won't be
2943 # filtered, because 192.168.33.254 is configured to switch peer port
2944 # for lrp33.
2945 lrp33_rsp=
2946 if test $i = 3 && test $j = 3; then
2947 lrp33_rsp=$rmac
2948 fi
2949 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2950
b0684540
HZ
2951 # MAC binding should be learned from ARP request.
2952 host_mac_pretty=f0:00:00:00:0$i:$j$k
2953
2954 host_ip_pretty=192.168.$i$j.$k
2955 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2956
2957 # mac_binding is learned and overwritten so only the last one remains.
2958 if test $k = 3; then
2959 # lrp33 will not learn from ARP request, because 192.168.33.254 is
2960 # configured to switch peer port for lrp33.
2961 if test $i != 3 || test $j != 3; then
2962 host_ip_pretty=192.168.$i$j.55
2963 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2964 fi
2965 fi
2966
0bac7164 2967 done
269ecccc 2968 done
0bac7164
BP
2969done
2970
0bac7164 2971
9975d7be
BP
2972# Allow some time for packet forwarding.
2973# XXX This can be improved.
2974sleep 1
2975
d7abfe39 2976# 8. Send an IP packet from every logical port to every other subnet. These
0bac7164
BP
2977# are the same packets already sent as #3, but now the destinations' IP-MAC
2978# bindings have been discovered via ARP, so instead of provoking an ARP
2979# request, these packets now get routed to their destinations (which don't
2980# have static MAC bindings, so they go to the port we've designated as
2981# accepting "unknown" MACs.)
2982for is in 1 2 3; do
269ecccc
JP
2983 for js in 1 2 3; do
2984 for ks in 1 2 3; do
2985 s=$is$js$ks
2986 smac=f00000000$s
2987 sip=`ip_to_hex 192 168 $is$js $ks`
2988 for id in 1 2 3; do
2989 for jd in 1 2 3; do
2990 if test $is$js = $id$jd; then
2991 continue
2992 fi
2993
2994 # Send the packet.
2995 dmac=00000000ff$is$js
2996 # Calculate a 4th octet for the destination that is
2997 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2998 # that have static MAC bindings, and fits in the range
2999 # 0-255.
3000 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
3001 dip=`ip_to_hex 192 168 $id$jd $o4`
3002 test_ip $s $smac $dmac $sip $dip
3003
3004 # Expect the packet egress.
3005 host_mac=8000000000$o4
3006 outport=${id}11
3007 out_lrp=$id$jd
e4543cfe 3008 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 3009 done
269ecccc 3010 done
0bac7164 3011 done
269ecccc 3012 done
0bac7164
BP
3013done
3014
0bac7164
BP
3015ovn-sbctl -f csv -d bare --no-heading \
3016 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
3017
9975d7be
BP
3018# Now check the packets actually received against the ones expected.
3019for i in 1 2 3; do
3020 for j in 1 2 3; do
86e98048 3021 for k in 1 2 3; do
abb37b6b
FF
3022 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
3023 [$i$j$k.expected])
86e98048 3024 done
9975d7be
BP
3025 done
3026done
fcde56f5 3027
0bac7164
BP
3028# Check the MAC bindings against those expected.
3029AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
3030])
3031
fcde56f5 3032# Gracefully terminate daemons
7a8f15e0 3033OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 3034
9975d7be 3035AT_CLEANUP
685f4dfe 3036
b0684540
HZ
3037AT_SETUP([ovn -- IP relocation using GARP request])
3038AT_SKIP_IF([test $HAVE_PYTHON = no])
3039ovn_start
3040
3041# Logical network:
3042#
3043# Two logical switches ls1, ls2.
3044# One logical router lr0 connected to ls[12],
3045# with 2 subnets, 1 per logical switch:
3046#
3047# lrp1 on ls1 for subnet 192.168.1.1/24
3048# lrp2 on ls2 for subnet 192.168.2.1/24
3049#
3050# 4 VIFs, 2 per LS lp[12][12], first digit being LS.
3051# VIFs' fixed IP addresses are 192.168.[12].1[12].
3052#
3053# There is a secondary IP 192.168.1.100 that is unknown in NB and learned
3054# through ARP only, and it can move between lp11 and lp12.
3055#
3056ovn-nbctl lr-add lr0
3057for i in 1 2 ; do
3058 ovn-nbctl ls-add ls$i
3059 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
3060 ovn-nbctl \
3061 -- lsp-add ls$i lrp$i-attachment \
3062 -- set Logical_Switch_Port lrp$i-attachment type=router \
3063 options:router-port=lrp$i \
3064 addresses=router
3065 for j in 1 2; do
3066 ovn-nbctl \
3067 -- lsp-add ls$i lp$i$j \
3068 -- lsp-set-addresses lp$i$j \
3069 "f0:00:00:00:00:$i$j 192.168.$i.1$j"
3070 done
3071done
3072
3073# Physical network:
3074# 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
3075
3076# Given the name of a logical port, prints the name of the hypervisor
3077# on which it is located, e.g. "vif_to_hv 12" yields 2.
3078vif_to_hv() {
3079 echo ${1#?}
3080}
3081
3082# Given the name of a logical port, prints the name of its logical router
3083# port, e.g. "vif_to_lrp 12" yields 1.
3084vif_to_lrp() {
3085 echo ${1%?}
3086}
3087
3088# Given the name of a logical port, prints the name of its logical
3089# switch, e.g. "vif_to_ls 12" yields 1.
3090vif_to_ls() {
3091 echo ${1%?}
3092}
3093
3094net_add n1
3095for i in 1 2; do
3096 sim_add hv$i
3097 as hv$i
3098 ovs-vsctl add-br br-phys
3099 ovn_attach n1 br-phys 192.168.0.$i
3100done
3101for i in 1 2; do
3102 for j in 1 2; do
3103 hv=`vif_to_hv $i$j`
3104 as hv$hv ovs-vsctl \
3105 -- add-port br-int vif$i$j \
3106 -- set Interface vif$i$j \
3107 external-ids:iface-id=lp$i$j \
3108 options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
3109 options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
3110 ofport-request=$i$j
3111 done
3112done
3113
3114# Pre-populate the hypervisors' ARP tables so that we don't lose any
3115# packets for ARP resolution (native tunneling doesn't queue packets
3116# for ARP resolution).
3117OVN_POPULATE_ARP
3118
3119# Allow some time for ovn-northd and ovn-controller to catch up.
3120# XXX This should be more systematic.
3121sleep 1
3122
3123# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3124#
3125# This shell function causes a packet to be received on INPORT. The packet's
3126# content has Ethernet destination DST and source SRC (each exactly 12 hex
3127# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
3128# more) list the VIFs on which the packet should be received. INPORT and the
3129# OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
3130for i in 1 2; do
3131 for j in 1 2; do
3132 : > $i$j.expected
3133 done
3134done
3135test_ip() {
3136 # This packet has bad checksums but logical L3 routing doesn't check.
3137 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3138 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3139 shift; shift; shift; shift; shift
3140 hv=hv`vif_to_hv $inport`
3141 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3142 in_ls=`vif_to_ls $inport`
3143 in_lrp=`vif_to_lrp $inport`
3144 for outport; do
3145 out_ls=`vif_to_ls $outport`
3146 if test $in_ls = $out_ls; then
3147 # Ports on the same logical switch receive exactly the same packet.
3148 echo $packet
3149 else
3150 # Routing decrements TTL and updates source and dest MAC
3151 # (and checksum).
3152 out_lrp=`vif_to_lrp $outport`
3153 echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
3154 fi >> $outport.expected
3155 done
3156}
3157
3158# test_arp INPORT SHA SPA TPA [REPLY_HA]
3159#
3160# Causes a packet to be received on INPORT. The packet is an ARP
3161# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3162# it should be the hardware address of the target to expect to receive in an
3163# ARP reply; otherwise no reply is expected.
3164#
3165# INPORT is an logical switch port number, e.g. 11 for vif11.
3166# SHA and REPLY_HA are each 12 hex digits.
3167# SPA and TPA are each 8 hex digits.
3168test_arp() {
3169 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
3170 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3171 hv=hv`vif_to_hv $inport`
3172 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3173
3174 # Expect to receive the broadcast ARP on the other logical switch ports if
3175 # IP address is not configured to the switch patch port.
3176 local i=`vif_to_ls $inport`
3177 local j
3178 for j in 1 2; do
3179 if test $i$j != $inport; then
3180 echo $request >> $i$j$k.expected
3181 fi
3182 done
3183
3184 # Expect to receive the reply, if any.
3185 if test X$reply_ha != X; then
3186 lrp=`vif_to_lrp $inport`
3187 local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3188 echo $reply >> $inport.expected
3189 fi
3190}
3191
3192ip_to_hex() {
3193 printf "%02x%02x%02x%02x" "$@"
3194}
3195
3196# lp11 send GARP request to announce ownership of 192.168.1.100.
3197
3198sha=f00000000011
3199spa=`ip_to_hex 192 168 1 100`
3200tpa=$spa
3201test_arp 11 $sha $spa $tpa
3202OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
3203ovn-nbctl --wait=hv sync
3204
3205# Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
3206
3207smac=f00000000021
3208dmac=00000000ff02
3209sip=`ip_to_hex 192 168 2 11`
3210dip=`ip_to_hex 192 168 1 100`
3211test_ip 21 $smac $dmac $sip $dip 11
3212
3213# lp12 send GARP request to announce ownership of 192.168.1.100.
3214
3215sha=f00000000012
3216test_arp 12 $sha $spa $tpa
3217OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
3218ovn-nbctl --wait=hv sync
1c24b2f4
LB
3219# give to the hv the time to send queued ip packets
3220sleep 1
b0684540
HZ
3221
3222# Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
3223
3224test_ip 21 $smac $dmac $sip $dip 12
3225
3226# Now check the packets actually received against the ones expected.
3227for i in 1 2; do
3228 for j in 1 2; do
3229 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
3230 [$i$j.expected])
3231 done
3232done
3233
3234# Gracefully terminate daemons
3235OVN_CLEANUP([hv1], [hv2])
3236
3237AT_CLEANUP
3238
685f4dfe
NS
3239# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
3240AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
3241AT_SKIP_IF([test $HAVE_PYTHON = no])
3242ovn_start
3243
3244# Create hypervisors hv[123].
3245# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
3246# Add all of the vifs to a single logical switch lsw0.
3247# Turn off port security on vifs vif[123]1
3248# Turn on l2 port security on vifs vif[123]2
3249# Turn of l2 and l3 port security on vifs vif[123]3
3250# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 3251ovn-nbctl ls-add lsw0
685f4dfe
NS
3252net_add n1
3253for i in 1 2 3; do
3254 sim_add hv$i
3255 as hv$i
3256 ovs-vsctl add-br br-phys
3257 ovn_attach n1 br-phys 192.168.0.$i
3258
3259 for j in 1 2 3; do
3260 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 3261 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 3262 if test $j = 1; then
31ed1192 3263 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 3264 elif test $j = 2; then
31ed1192
JP
3265 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
3266 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
3267 else
3268 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
3269 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3270 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
3271 fi
3272 done
3273done
3274
685f4dfe
NS
3275# Pre-populate the hypervisors' ARP tables so that we don't lose any
3276# packets for ARP resolution (native tunneling doesn't queue packets
3277# for ARP resolution).
74868f2c 3278OVN_POPULATE_ARP
685f4dfe
NS
3279
3280# Allow some time for ovn-northd and ovn-controller to catch up.
3281# XXX This should be more systematic.
3282sleep 1
685f4dfe
NS
3283
3284# Given the name of a logical port, prints the name of the hypervisor
3285# on which it is located.
3286vif_to_hv() {
3287 echo hv${1%?}
3288}
3289
685f4dfe
NS
3290for i in 1 2 3; do
3291 for j in 1 2 3; do
3292 : > $i$j.expected
3293 done
3294done
3295
3296# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3297#
3298# This shell function causes an ip packet to be received on INPORT.
3299# The packet's content has Ethernet destination DST and source SRC
3300# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
3301# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
3302# be received. INPORT and the OUTPORTs are specified as logical switch
3303# port numbers, e.g. 11 for vif11.
685f4dfe
NS
3304test_ip() {
3305 # This packet has bad checksums but logical L3 routing doesn't check.
3306 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 3307 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
3308 shift; shift; shift; shift; shift
3309 hv=`vif_to_hv $inport`
3310 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3311 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3312 for outport; do
e4543cfe 3313 echo $packet >> $outport.expected
685f4dfe
NS
3314 done
3315}
3316
3317# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
3318#
3319# Causes a packet to be received on INPORT. The packet is an ARP
3320# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3321# it should be the hardware address of the target to expect to receive in an
3322# ARP reply; otherwise no reply is expected.
3323#
31ed1192 3324# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
3325# SHA and REPLY_HA are each 12 hex digits.
3326# SPA and TPA are each 8 hex digits.
3327test_arp() {
3328 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
3329 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3330 hv=`vif_to_hv $inport`
3331 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3332 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
3333 if test $drop != 1; then
e137131a 3334 if test X$reply_ha = X; then
685f4dfe
NS
3335 # Expect to receive the broadcast ARP on the other logical switch ports
3336 # if no reply is expected.
3337 local i j
3338 for i in 1 2 3; do
3339 for j in 1 2 3; do
3340 if test $i$j != $inport; then
3341 echo $request >> $i$j.expected
3342 fi
3343 done
3344 done
3345 else
3346 # Expect to receive the reply, if any.
3347 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3348 echo $reply >> $inport.expected
3349 fi
3350 fi
3351}
3352
3353# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3354# This function is similar to test_ip() except that it sends
3355# ipv6 packet
3356test_ipv6() {
3357 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3358 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
3359 shift; shift; shift; shift; shift
3360 hv=`vif_to_hv $inport`
3361 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3362 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3363 for outport; do
e4543cfe 3364 echo $packet >> $outport.expected
685f4dfe
NS
3365 done
3366}
3367
9e687b23
DL
3368# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
3369# This function is similar to test_ipv6() except it specifies the ICMPv6 type
3370# of the test packet
3371test_icmpv6() {
3372 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
3373 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
3374 shift; shift; shift; shift; shift; shift
3375 hv=`vif_to_hv $inport`
3376 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3377 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3378 for outport; do
e4543cfe 3379 echo $packet >> $outport.expected
9e687b23
DL
3380 done
3381}
3382
685f4dfe
NS
3383ip_to_hex() {
3384 printf "%02x%02x%02x%02x" "$@"
3385}
3386
3387# no port security
3388sip=`ip_to_hex 192 168 0 12`
3389tip=`ip_to_hex 192 168 0 13`
3390# the arp packet should be allowed even if lp[123]1 is
3391# not configured with mac f00000000023 and ip 192.168.0.12
3392for i in 1 2 3; do
3393 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
3394 for j in 1 2 3; do
3395 if test $i != $j; then
3396 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
3397 fi
3398 done
3399done
3400
3401# l2 port security
3402sip=`ip_to_hex 192 168 0 12`
3403tip=`ip_to_hex 192 168 0 13`
3404
3405# arp packet should be allowed since lp22 is configured with
3406# mac f00000000022
3407test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
3408
3409# arp packet should not be allowed since lp32 is not configured with
3410# mac f00000000021
3411test_arp 32 f00000000021 f00000000021 $sip $tip 1
3412
3413# arp packet with sha set to f00000000021 should not be allowed
3414# for lp12
3415test_arp 12 f00000000012 f00000000021 $sip $tip 1
3416
3417# ip packets should be allowed and received since lp[123]2 do not
3418# have l3 port security
3419sip=`ip_to_hex 192 168 0 55`
3420tip=`ip_to_hex 192 168 0 66`
3421for i in 1 2 3; do
3422 for j in 1 2 3; do
3423 if test $i != $j; then
3424 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3425 fi
3426 done
3427done
3428
3429# ipv6 packets should be received by lp[123]2
3430# lp[123]1 can send ipv6 traffic as there is no port security
3431sip=fe800000000000000000000000000000
3432tip=ff020000000000000000000000000000
3433
3434for i in 1 2 3; do
3435 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3436done
3437
3438
3439# l2 and l3 port security
3440sip=`ip_to_hex 192 168 0 13`
3441tip=`ip_to_hex 192 168 0 22`
3442# arp packet should be allowed since lp13 is configured with
3443# f00000000013 and 192.168.0.13
3444test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3445
3446# the arp packet should be dropped because lp23 is not configured
3447# with mac f00000000022
3448sip=`ip_to_hex 192 168 0 13`
3449tip=`ip_to_hex 192 168 0 22`
3450test_arp 23 f00000000022 f00000000022 $sip $tip 1
3451
3452# the arp packet should be dropped because lp33 is not configured
3453# with ip 192.168.0.55
3454spa=`ip_to_hex 192 168 0 55`
3455tpa=`ip_to_hex 192 168 0 22`
3456test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3457
3458# ip packets should not be received by lp[123]3 since
3459# l3 port security is enabled
3460sip=`ip_to_hex 192 168 0 55`
3461tip=`ip_to_hex 192 168 0 66`
3462for i in 1 2 3; do
3463 for j in 1 2 3; do
3464 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3465 done
3466done
3467
3468# ipv6 packets should be dropped for lp[123]3 since
3469# it is configured with only ipv4 address
3470sip=fe800000000000000000000000000000
3471tip=ff020000000000000000000000000000
3472
3473for i in 1 2 3; do
3474 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3475done
3476
3477# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3478# lp[123]1 can send ipv6 traffic as there is no port security
3479for i in 1 2 3; do
3480 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3481done
3482
3483# lp13 has extra port security with mac f0000000113 and ipv6 addr
3484# fe80::ea2a:eaff:fe28:0012
3485
3486# ipv4 packet should be dropped for lp13 with mac f0000000113
3487sip=`ip_to_hex 192 168 0 13`
3488tip=`ip_to_hex 192 168 0 23`
3489test_ip 13 f00000000113 f00000000023 $sip $tip
3490
6d53e8a9
BP
3491# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3492# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
3493# lp11 can send ipv6 traffic as there is no port security
3494sip=ee800000000000000000000000000000
3495for i in 1 2 3; do
6d53e8a9
BP
3496 tip=fe80000000000000ea2aeafffe2800${i}3
3497 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
3498done
3499
3500
3501# ipv6 packet should not be received by lp33 with mac f0000000333
3502# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3503# configured with fe80::ea2a:eaff:fe28:0033
3504# lp11 can send ipv6 traffic as there is no port security
3505
3506sip=ee800000000000000000000000000000
3507tip=fe80000000000000ea2aeafffe280023
3508test_ipv6 11 f00000000011 f00000000333 $sip $tip
3509
6d53e8a9
BP
3510# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3511# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
3512# and should be dropped for any other ip6.src
3513# lp21 can receive ipv6 traffic as there is no port security
3514
3515tip=ee800000000000000000000000000000
3516for i in 1 2 3; do
3517 sip=fe80000000000000ea2aeafffe2800${i}3
3518 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3519
9e687b23 3520 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 3521 sip=00000000000000000000000000000000
9e687b23
DL
3522 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3523 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3524 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3525 # Traffic to non-multicast traffic should be dropped
3526 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3527 # Traffic of other ICMPv6 types should be dropped
3528 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
3529
3530 # should be dropped
3531 sip=ae80000000000000ea2aeafffe2800aa
3532 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3533done
3534
31ed1192
JP
3535# configure lsp13 to send and received IPv4 packets with an address range
3536ovn-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 3537
8ff5a966
NS
3538sleep 2
3539
7d9d86ad
NS
3540sip=`ip_to_hex 10 0 0 13`
3541tip=`ip_to_hex 192 168 0 22`
31ed1192 3542# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
3543test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3544
3545sip=`ip_to_hex 10 0 0 14`
3546tip=`ip_to_hex 192 168 0 23`
31ed1192 3547# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
3548# with dst ip 192.168.0.23 should be allowed
3549test_ip 13 f00000000013 f00000000023 $sip $tip 23
3550
3551sip=`ip_to_hex 192 168 0 33`
3552tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
3553# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3554# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
3555test_ip 33 f00000000033 f00000000013 $sip $tip 13
3556
3557sip=`ip_to_hex 192 168 0 33`
3558tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
3559# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3560# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
3561test_ip 33 f00000000033 f00000000013 $sip $tip 13
3562
3563sip=`ip_to_hex 192 168 0 33`
3564tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
3565# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3566# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
3567test_ip 33 f00000000033 f00000000013 $sip $tip
3568
3569sip=`ip_to_hex 192 168 0 33`
3570tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
3571# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3572# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
3573test_ip 33 f00000000033 f00000000013 $sip $tip 13
3574
3575sip=`ip_to_hex 192 168 0 33`
3576tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
3577# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3578# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
3579test_ip 33 f00000000033 f00000000013 $sip $tip
3580
3581sip=`ip_to_hex 192 168 0 33`
3582tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
3583# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3584# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 3585test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 3586
bb0c41d3
RM
3587#dump information including flow counters
3588ovn-nbctl show
3589ovn-sbctl dump-flows -- list multicast_group
3590
3591echo "------ hv1 dump ------"
3592as hv1 ovs-vsctl show
6195e2e7 3593as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3594as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3595
3596echo "------ hv2 dump ------"
3597as hv2 ovs-vsctl show
6195e2e7 3598as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3599as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3600
3601echo "------ hv3 dump ------"
3602as hv3 ovs-vsctl show
6195e2e7 3603as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3604as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3605
685f4dfe
NS
3606# Now check the packets actually received against the ones expected.
3607for i in 1 2 3; do
3608 for j in 1 2 3; do
49d7c759 3609 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
3610 done
3611done
3612
7a8f15e0 3613OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 3614
685f4dfe 3615AT_CLEANUP
509afdc3
GS
3616
3617AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
3618AT_SKIP_IF([test $HAVE_PYTHON = no])
3619ovn_start
3620
3621# Logical network:
3622# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3623# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3624# R2 has ls2 (172.16.1.0/24) connected to it.
3625
3c1ae70a
JP
3626ls1_lp1_mac="f0:00:00:01:02:03"
3627rp_ls1_mac="00:00:00:01:02:03"
3628rp_ls2_mac="00:00:00:01:02:04"
3629ls2_lp1_mac="f0:00:00:01:02:04"
3630
3631ls1_lp1_ip="192.168.1.2"
3632ls2_lp1_ip="172.16.1.2"
3633
fa2a27b2
JP
3634ovn-nbctl lr-add R1
3635ovn-nbctl lr-add R2
509afdc3 3636
ea46a4e9
JP
3637ovn-nbctl ls-add ls1
3638ovn-nbctl ls-add ls2
509afdc3
GS
3639
3640# Connect ls1 to R1
3c1ae70a 3641ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
509afdc3 3642
31ed1192 3643ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3c1ae70a 3644 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
509afdc3
GS
3645
3646# Connect ls2 to R2
3c1ae70a 3647ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
509afdc3 3648
31ed1192 3649ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3c1ae70a 3650 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
509afdc3
GS
3651
3652# Connect R1 to R2
4685e523
JP
3653ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3654ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 3655
6d9ecfa9
JP
3656ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3657ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
3658
3659# Create logical port ls1-lp1 in ls1
31ed1192 3660ovn-nbctl lsp-add ls1 ls1-lp1 \
3c1ae70a 3661-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
509afdc3
GS
3662
3663# Create logical port ls2-lp1 in ls2
31ed1192 3664ovn-nbctl lsp-add ls2 ls2-lp1 \
3c1ae70a 3665-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
509afdc3
GS
3666
3667# Create two hypervisor and create OVS ports corresponding to logical ports.
3668net_add n1
3669
3670sim_add hv1
3671as hv1
3672ovs-vsctl add-br br-phys
3673ovn_attach n1 br-phys 192.168.0.1
3674ovs-vsctl -- add-port br-int hv1-vif1 -- \
3675 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3676 options:tx_pcap=hv1/vif1-tx.pcap \
3677 options:rxq_pcap=hv1/vif1-rx.pcap \
3678 ofport-request=1
3679
3680sim_add hv2
3681as hv2
3682ovs-vsctl add-br br-phys
3683ovn_attach n1 br-phys 192.168.0.2
3684ovs-vsctl -- add-port br-int hv2-vif1 -- \
3685 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3686 options:tx_pcap=hv2/vif1-tx.pcap \
3687 options:rxq_pcap=hv2/vif1-rx.pcap \
3688 ofport-request=1
3689
3690
3691# Pre-populate the hypervisors' ARP tables so that we don't lose any
3692# packets for ARP resolution (native tunneling doesn't queue packets
3693# for ARP resolution).
74868f2c 3694OVN_POPULATE_ARP
509afdc3
GS
3695
3696# Allow some time for ovn-northd and ovn-controller to catch up.
3697# XXX This should be more systematic.
3698sleep 1
3699
509afdc3 3700# Packet to send.
3c1ae70a
JP
3701packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3702 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3703 udp && udp.src==53 && udp.dst==4369"
3704as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
509afdc3
GS
3705
3706
3707echo "---------NB dump-----"
3708ovn-nbctl show
3709echo "---------------------"
3710ovn-nbctl list logical_router
3711echo "---------------------"
3712ovn-nbctl list logical_router_port
3713echo "---------------------"
3714
3715echo "---------SB dump-----"
3716ovn-sbctl list datapath_binding
3717echo "---------------------"
3718ovn-sbctl list port_binding
3719echo "---------------------"
3720
3721echo "------ hv1 dump ----------"
8dab1022 3722as hv1 ovs-ofctl show br-int
509afdc3
GS
3723as hv1 ovs-ofctl dump-flows br-int
3724echo "------ hv2 dump ----------"
8dab1022 3725as hv2 ovs-ofctl show br-int
509afdc3
GS
3726as hv2 ovs-ofctl dump-flows br-int
3727
3728# Packet to Expect
3c1ae70a
JP
3729# The TTL should be decremented by 2.
3730packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3731 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3732 udp && udp.src==53 && udp.dst==4369"
3733echo $packet | ovstest test-ovn expr-to-packets > expected
509afdc3 3734
49d7c759 3735OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 3736
7ebfcd3d
NS
3737AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3738grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3739])
3740
3741# Disable the ls2-lp1 port.
3742ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3743
3744AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3745grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3746])
3747
3748# Generate the packet destined for ls2-lp1 and it should not be delivered.
3749# Packet to send.
3750packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3751 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3752 udp && udp.src==53 && udp.dst==4369"
3753
3754as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3755# The 2nd packet sent shound not be received.
3756OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3757
7a8f15e0 3758OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
3759
3760AT_CLEANUP
5412db30
J
3761
3762
4685e523
JP
3763AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3764AT_KEYWORDS([router-admin-state])
3765AT_SKIP_IF([test $HAVE_PYTHON = no])
3766ovn_start
3767
3768# Logical network:
3769# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3770# and 172.16.1.0/24) connected to it.
3771
3772ovn-nbctl lr-add R1
3773
3774ovn-nbctl ls-add ls1
3775
3776# Connect ls1 to R1
bf44c2cd 3777ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
3778ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3779 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3780
3781# Create logical port ls1-lp1 in ls1
3782ovn-nbctl lsp-add ls1 ls1-lp1 \
3783 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3784
3785# Create logical port ls1-lp2 in ls1
3786ovn-nbctl lsp-add ls1 ls1-lp2 \
3787 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3788
3789# Create one hypervisor and create OVS ports corresponding to logical ports.
3790net_add n1
3791
3792sim_add hv1
3793as hv1
3794ovs-vsctl add-br br-phys
3795ovn_attach n1 br-phys 192.168.0.1
3796ovs-vsctl -- add-port br-int vif1 -- \
3797 set interface vif1 external-ids:iface-id=ls1-lp1 \
3798 options:tx_pcap=hv1/vif1-tx.pcap \
3799 options:rxq_pcap=hv1/vif1-rx.pcap \
3800 ofport-request=1
3801
3802ovs-vsctl -- add-port br-int vif2 -- \
3803 set interface vif2 external-ids:iface-id=ls1-lp2 \
3804 options:tx_pcap=hv1/vif2-tx.pcap \
3805 options:rxq_pcap=hv1/vif2-rx.pcap \
3806 ofport-request=1
3807
3808
3809# Allow some time for ovn-northd and ovn-controller to catch up.
3810# XXX This should be more systematic.
3811sleep 1
3812
3813# Send ip packets between the two ports.
3814ip_to_hex() {
3815 printf "%02x%02x%02x%02x" "$@"
3816}
4685e523
JP
3817
3818# Packet to send.
3819src_mac="f00000010203"
3820dst_mac="000000010203"
3821src_ip=`ip_to_hex 192 168 1 2`
3822dst_ip=`ip_to_hex 172 16 1 2`
3823packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3824as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3825
3826
3827echo "---------NB dump-----"
3828ovn-nbctl show
3829echo "---------------------"
3830ovn-nbctl list logical_router
3831echo "---------------------"
3832ovn-nbctl list logical_router_port
3833echo "---------------------"
3834
3835echo "---------SB dump-----"
3836ovn-sbctl list datapath_binding
3837echo "---------------------"
3838ovn-sbctl list logical_flow
3839echo "---------------------"
3840
3841echo "------ hv1 dump ----------"
3842as hv1 ovs-ofctl dump-flows br-int
3843
3844
3845#Disable router R1
3846ovn-nbctl set Logical_Router R1 enabled=false
3847
3b8cd0ea
BP
3848# Allow some time for ovn-northd and ovn-controller to catch up.
3849# XXX This should be more systematic.
3850sleep 1
3851
4685e523
JP
3852echo "---------SB dump-----"
3853ovn-sbctl list datapath_binding
3854echo "---------------------"
3855ovn-sbctl list logical_flow
3856echo "---------------------"
3857
3858echo "------ hv1 dump ----------"
3859as hv1 ovs-ofctl dump-flows br-int
3860
3861as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3862
3863# Packet to Expect
3864expect_src_mac="000000010203"
3865expect_dst_mac="f00000010204"
49d7c759 3866echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3867
49d7c759 3868OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523 3869
c4d0e4f2 3870OVN_CLEANUP([hv1])
4685e523
JP
3871
3872AT_CLEANUP
3873
3874
3875AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3876AT_KEYWORDS([router-admin-state])
3877AT_SKIP_IF([test $HAVE_PYTHON = no])
3878ovn_start
3879
3880# Logical network:
3881# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3882# and has switch ls2 (172.16.1.0/24) connected to it.
3883
fa2a27b2 3884ovn-nbctl lr-add R1
5412db30 3885
ea46a4e9
JP
3886ovn-nbctl ls-add ls1
3887ovn-nbctl ls-add ls2
5412db30
J
3888
3889# Connect ls1 to R1
bf44c2cd 3890ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3891ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3892 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3893
3894# Connect ls2 to R1
bf44c2cd 3895ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3896ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3897 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3898
3899# Create logical port ls1-lp1 in ls1
31ed1192
JP
3900ovn-nbctl lsp-add ls1 ls1-lp1 \
3901-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3902
3903# Create logical port ls2-lp1 in ls2
31ed1192
JP
3904ovn-nbctl lsp-add ls2 ls2-lp1 \
3905-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3906
3907# Create one hypervisor and create OVS ports corresponding to logical ports.
3908net_add n1
3909
3910sim_add hv1
3911as hv1
3912ovs-vsctl add-br br-phys
3913ovn_attach n1 br-phys 192.168.0.1
3914ovs-vsctl -- add-port br-int vif1 -- \
3915 set interface vif1 external-ids:iface-id=ls1-lp1 \
3916 options:tx_pcap=hv1/vif1-tx.pcap \
3917 options:rxq_pcap=hv1/vif1-rx.pcap \
3918 ofport-request=1
3919
3920ovs-vsctl -- add-port br-int vif2 -- \
3921 set interface vif2 external-ids:iface-id=ls2-lp1 \
3922 options:tx_pcap=hv1/vif2-tx.pcap \
3923 options:rxq_pcap=hv1/vif2-rx.pcap \
3924 ofport-request=1
3925
3926
3927# Allow some time for ovn-northd and ovn-controller to catch up.
3928# XXX This should be more systematic.
3929sleep 1
3930
3931# Send ip packets between the two ports.
3932ip_to_hex() {
3933 printf "%02x%02x%02x%02x" "$@"
3934}
5412db30
J
3935
3936# Packet to send.
3937src_mac="f00000010203"
3938dst_mac="000000010203"
3939src_ip=`ip_to_hex 192 168 1 2`
3940dst_ip=`ip_to_hex 172 16 1 2`
3941packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3942as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3943
3944
3945echo "---------NB dump-----"
3946ovn-nbctl show
3947echo "---------------------"
3948ovn-nbctl list logical_router
3949echo "---------------------"
3950ovn-nbctl list logical_router_port
3951echo "---------------------"
3952
3953echo "---------SB dump-----"
3954ovn-sbctl list datapath_binding
3955echo "---------------------"
3956ovn-sbctl list logical_flow
3957echo "---------------------"
3958
3959echo "------ hv1 dump ----------"
3960as hv1 ovs-ofctl dump-flows br-int
3961
5412db30
J
3962#Disable router R1
3963ovn-nbctl set Logical_Router R1 enabled=false
3964
3965echo "---------SB dump-----"
3966ovn-sbctl list datapath_binding
3967echo "---------------------"
3968ovn-sbctl list logical_flow
3969echo "---------------------"
3970
3971echo "------ hv1 dump ----------"
3972as hv1 ovs-ofctl dump-flows br-int
3973
a1361a6e
LR
3974# Allow some time for the disabling of logical router R1 to propagate.
3975# XXX This should be more systematic.
3976sleep 1
3977
5412db30
J
3978as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3979
3980# Packet to Expect
3981expect_src_mac="000000010204"
3982expect_dst_mac="f00000010204"
49d7c759 3983echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3984
49d7c759 3985OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3986
7a8f15e0 3987OVN_CLEANUP([hv1])
5412db30
J
3988
3989AT_CLEANUP
3990
28dc3fe9 3991AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3992AT_SKIP_IF([test $HAVE_PYTHON = no])
3993ovn_start
3994
3995# Logical network:
3996# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3997# network. R1 has switchess foo (192.168.1.0/24)
3998# connected to it.
3999# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
4000
fa2a27b2
JP
4001ovn-nbctl lr-add R1
4002ovn-nbctl lr-add R2
28dc3fe9 4003
ea46a4e9
JP
4004ovn-nbctl ls-add foo
4005ovn-nbctl ls-add alice
4006ovn-nbctl ls-add bob
28dc3fe9
SR
4007
4008# Connect foo to R1
bf44c2cd 4009ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 4010ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 4011 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
4012
4013# Connect alice to R2
bf44c2cd 4014ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 4015ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4016 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
4017
4018# Connect bob to R2
bf44c2cd 4019ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 4020ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 4021 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
4022
4023# Connect R1 to R2
4685e523
JP
4024ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
4025ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
4026
4027#install static routes
e48ccf3c
JP
4028ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4029ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
4030ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
4031
4032# Create logical port foo1 in foo
31ed1192
JP
4033ovn-nbctl lsp-add foo foo1 \
4034-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
4035
4036# Create logical port alice1 in alice
31ed1192
JP
4037ovn-nbctl lsp-add alice alice1 \
4038-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
4039
4040# Create logical port bob1 in bob
31ed1192
JP
4041ovn-nbctl lsp-add bob bob1 \
4042-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
4043
4044# Create two hypervisor and create OVS ports corresponding to logical ports.
4045net_add n1
4046
4047sim_add hv1
4048as hv1
4049ovs-vsctl add-br br-phys
4050ovn_attach n1 br-phys 192.168.0.1
4051ovs-vsctl -- add-port br-int hv1-vif1 -- \
4052 set interface hv1-vif1 external-ids:iface-id=foo1 \
4053 options:tx_pcap=hv1/vif1-tx.pcap \
4054 options:rxq_pcap=hv1/vif1-rx.pcap \
4055 ofport-request=1
4056
4057ovs-vsctl -- add-port br-int hv1-vif2 -- \
4058 set interface hv1-vif2 external-ids:iface-id=alice1 \
4059 options:tx_pcap=hv1/vif2-tx.pcap \
4060 options:rxq_pcap=hv1/vif2-rx.pcap \
4061 ofport-request=2
4062
4063sim_add hv2
4064as hv2
4065ovs-vsctl add-br br-phys
4066ovn_attach n1 br-phys 192.168.0.2
4067ovs-vsctl -- add-port br-int hv2-vif1 -- \
4068 set interface hv2-vif1 external-ids:iface-id=bob1 \
4069 options:tx_pcap=hv2/vif1-tx.pcap \
4070 options:rxq_pcap=hv2/vif1-rx.pcap \
4071 ofport-request=1
4072
4073
4074# Pre-populate the hypervisors' ARP tables so that we don't lose any
4075# packets for ARP resolution (native tunneling doesn't queue packets
4076# for ARP resolution).
74868f2c 4077OVN_POPULATE_ARP
28dc3fe9
SR
4078
4079# Allow some time for ovn-northd and ovn-controller to catch up.
4080# XXX This should be more systematic.
4081sleep 1
4082
4083ip_to_hex() {
4084 printf "%02x%02x%02x%02x" "$@"
4085}
28dc3fe9
SR
4086
4087# Send ip packets between foo1 and alice1
4088src_mac="f00000010203"
4089dst_mac="000000010203"
4090src_ip=`ip_to_hex 192 168 1 2`
4091dst_ip=`ip_to_hex 172 16 1 2`
4092packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4093as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4094
4095# Send ip packets between foo1 and bob1
4096src_mac="f00000010203"
4097dst_mac="000000010203"
4098src_ip=`ip_to_hex 192 168 1 2`
4099dst_ip=`ip_to_hex 172 16 2 2`
4100packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4101as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4102
4103echo "---------NB dump-----"
4104ovn-nbctl show
4105echo "---------------------"
4106ovn-nbctl list logical_router
4107echo "---------------------"
4108ovn-nbctl list logical_router_port
4109echo "---------------------"
4110
4111echo "---------SB dump-----"
4112ovn-sbctl list datapath_binding
4113echo "---------------------"
4114ovn-sbctl list port_binding
4115echo "---------------------"
4116
4117echo "------ hv1 dump ----------"
4118as hv1 ovs-ofctl dump-flows br-int
4119echo "------ hv2 dump ----------"
4120as hv2 ovs-ofctl dump-flows br-int
4121
4122# Packet to Expect at bob1
4123src_mac="000000010205"
4124dst_mac="f00000010205"
4125src_ip=`ip_to_hex 192 168 1 2`
4126dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 4127echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 4128
49d7c759 4129OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
4130
4131# Packet to Expect at alice1
4132src_mac="000000010204"
4133dst_mac="f00000010204"
4134src_ip=`ip_to_hex 192 168 1 2`
4135dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 4136echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 4137
49d7c759 4138OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 4139
7a8f15e0 4140OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
4141
4142AT_CLEANUP
5412db30 4143
0ee8aaf6 4144AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 4145AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 4146ovn_start
ea46a4e9 4147ovn-nbctl ls-add lsw0
0ee8aaf6
RR
4148net_add n1
4149sim_add hv
4150as hv
4151ovs-vsctl \
4152 -- add-br br-phys \
4153 -- add-br br-eth0
4154
4155ovn_attach n1 br-phys 192.168.0.1
4156
4157AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
4158AT_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])
4159
4160# Create a vif.
31ed1192
JP
4161AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
4162AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
4163AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
4164
4165# Create a localnet port.
31ed1192
JP
4166AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
4167AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
4168AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
4169AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
4170
4171AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
4172
4173# Wait for packet to be received.
49d7c759
BP
4174echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4175OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6 4176
5b57e12a
GL
4177# Check GARP packet when restart openflow connection.
4178as hv
4179OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4180
4181OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
4182
4183as hv
4184start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
4185
4186# Wait for packet to be received.
4187echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4188OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
4189
0ee8aaf6
RR
4190# Delete the localnet ports.
4191AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 4192AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 4193
7a8f15e0 4194OVN_CLEANUP([hv])
0ee8aaf6
RR
4195
4196AT_CLEANUP
75cf9d2b
GS
4197
4198AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
4199AT_SKIP_IF([test $HAVE_PYTHON = no])
4200ovn_start
4201
4202# Logical network:
4203# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
4204# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4205# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
4206# connected to it.
4207
fa2a27b2
JP
4208ovn-nbctl lr-add R1
4209ovn-nbctl lr-add R2
4210ovn-nbctl lr-add R3
75cf9d2b 4211
ea46a4e9
JP
4212ovn-nbctl ls-add foo
4213ovn-nbctl ls-add alice
4214ovn-nbctl ls-add bob
4215ovn-nbctl ls-add join
75cf9d2b
GS
4216
4217# Connect foo to R1
31114af7 4218ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4219ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 4220 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
4221
4222# Connect alice to R2
31114af7 4223ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4224ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4225 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
4226
4227# Connect bob to R3
31114af7 4228ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 4229ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 4230 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
4231
4232# Connect R1 to join
31114af7 4233ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4234ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4235 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
4236
4237# Connect R2 to join
31114af7 4238ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4239ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4240 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
4241
4242# Connect R3 to join
31114af7 4243ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 4244ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 4245 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
4246
4247#install static routes
e48ccf3c
JP
4248ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4249ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 4250
e48ccf3c
JP
4251ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4252ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 4253
e48ccf3c
JP
4254ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
4255ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
4256
4257# Create logical port foo1 in foo
31ed1192
JP
4258ovn-nbctl lsp-add foo foo1 \
4259-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
4260
4261# Create logical port alice1 in alice
31ed1192
JP
4262ovn-nbctl lsp-add alice alice1 \
4263-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
4264
4265# Create logical port bob1 in bob
31ed1192
JP
4266ovn-nbctl lsp-add bob bob1 \
4267-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
4268
4269# Create two hypervisor and create OVS ports corresponding to logical ports.
4270net_add n1
4271
4272sim_add hv1
4273as hv1
4274ovs-vsctl add-br br-phys
4275ovn_attach n1 br-phys 192.168.0.1
4276ovs-vsctl -- add-port br-int hv1-vif1 -- \
4277 set interface hv1-vif1 external-ids:iface-id=foo1 \
4278 options:tx_pcap=hv1/vif1-tx.pcap \
4279 options:rxq_pcap=hv1/vif1-rx.pcap \
4280 ofport-request=1
4281
4282ovs-vsctl -- add-port br-int hv1-vif2 -- \
4283 set interface hv1-vif2 external-ids:iface-id=alice1 \
4284 options:tx_pcap=hv1/vif2-tx.pcap \
4285 options:rxq_pcap=hv1/vif2-rx.pcap \
4286 ofport-request=2
4287
4288sim_add hv2
4289as hv2
4290ovs-vsctl add-br br-phys
4291ovn_attach n1 br-phys 192.168.0.2
4292ovs-vsctl -- add-port br-int hv2-vif1 -- \
4293 set interface hv2-vif1 external-ids:iface-id=bob1 \
4294 options:tx_pcap=hv2/vif1-tx.pcap \
4295 options:rxq_pcap=hv2/vif1-rx.pcap \
4296 ofport-request=1
4297
4298
4299# Pre-populate the hypervisors' ARP tables so that we don't lose any
4300# packets for ARP resolution (native tunneling doesn't queue packets
4301# for ARP resolution).
74868f2c 4302OVN_POPULATE_ARP
75cf9d2b
GS
4303
4304# Allow some time for ovn-northd and ovn-controller to catch up.
4305# XXX This should be more systematic.
4306sleep 1
4307
4308ip_to_hex() {
4309 printf "%02x%02x%02x%02x" "$@"
4310}
75cf9d2b
GS
4311
4312# Send ip packets between foo1 and alice1
4313src_mac="f00000010203"
4314dst_mac="000001010203"
4315src_ip=`ip_to_hex 192 168 1 2`
4316dst_ip=`ip_to_hex 172 16 1 2`
4317packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4318as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4319as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4320
4321# Send ip packets between foo1 and bob1
4322src_mac="f00000010203"
4323dst_mac="000001010203"
4324src_ip=`ip_to_hex 192 168 1 2`
4325dst_ip=`ip_to_hex 10 32 1 2`
4326packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4327as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4328
4329echo "---------NB dump-----"
4330ovn-nbctl show
4331echo "---------------------"
4332ovn-nbctl list logical_router
4333echo "---------------------"
4334ovn-nbctl list logical_router_port
4335echo "---------------------"
4336
4337echo "---------SB dump-----"
4338ovn-sbctl list datapath_binding
4339echo "---------------------"
4340ovn-sbctl list port_binding
4341echo "---------------------"
4342ovn-sbctl dump-flows
4343echo "---------------------"
4344
4345echo "------ hv1 dump ----------"
4346as hv1 ovs-ofctl show br-int
4347as hv1 ovs-ofctl dump-flows br-int
4348echo "------ hv2 dump ----------"
4349as hv2 ovs-ofctl show br-int
4350as hv2 ovs-ofctl dump-flows br-int
4351echo "----------------------------"
4352
4353# Packet to Expect at bob1
4354src_mac="000003010203"
4355dst_mac="f00000010205"
4356src_ip=`ip_to_hex 192 168 1 2`
4357dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 4358echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 4359
49d7c759 4360OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
4361
4362# Packet to Expect at alice1
4363src_mac="000002010203"
4364dst_mac="f00000010204"
4365src_ip=`ip_to_hex 192 168 1 2`
4366dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 4367echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 4368
49d7c759 4369OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 4370
7a8f15e0 4371OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
4372
4373AT_CLEANUP
c1645003 4374
281977f7 4375AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
4376AT_SKIP_IF([test $HAVE_PYTHON = no])
4377ovn_start
4378
4379ovn-nbctl ls-add ls1
4380
4381ovn-nbctl lsp-add ls1 ls1-lp1 \
4382-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4383
4384ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4385
4386ovn-nbctl lsp-add ls1 ls1-lp2 \
4387-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4388
4389ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4390
4391ovn-nbctl ls-add ls2
4392ovn-nbctl lsp-add ls2 ls2-lp1 \
4393-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4394ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4395ovn-nbctl lsp-add ls2 ls2-lp2 \
4396-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4397ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4398
9060fc9a 4399d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
281977f7 4400options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
9060fc9a 4401\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
281977f7 4402
9060fc9a
MM
4403ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4404ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4405
4406d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
281977f7 4407options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
9060fc9a
MM
4408\"lease_time\"=\"3600\"")"
4409
4410ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
281977f7
NS
4411
4412net_add n1
4413sim_add hv1
4414
4415as hv1
4416ovs-vsctl add-br br-phys
4417ovn_attach n1 br-phys 192.168.0.1
4418ovs-vsctl -- add-port br-int hv1-vif1 -- \
4419 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4420 options:tx_pcap=hv1/vif1-tx.pcap \
4421 options:rxq_pcap=hv1/vif1-rx.pcap \
4422 ofport-request=1
4423
4424ovs-vsctl -- add-port br-int hv1-vif2 -- \
4425 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4426 options:tx_pcap=hv1/vif2-tx.pcap \
4427 options:rxq_pcap=hv1/vif2-rx.pcap \
4428 ofport-request=2
4429
4430ovs-vsctl -- add-port br-int hv1-vif3 -- \
4431 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4432 options:tx_pcap=hv1/vif3-tx.pcap \
4433 options:rxq_pcap=hv1/vif3-rx.pcap \
4434 ofport-request=3
4435
4436ovs-vsctl -- add-port br-int hv1-vif4 -- \
4437 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4438 options:tx_pcap=hv1/vif4-tx.pcap \
4439 options:rxq_pcap=hv1/vif4-rx.pcap \
4440 ofport-request=4
4441
74868f2c 4442OVN_POPULATE_ARP
281977f7
NS
4443
4444sleep 2
4445
4446as hv1 ovs-vsctl show
4447
281977f7 4448# This shell function sends a DHCP request packet
fcc3c93f 4449# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP REQUEST_IP ...
281977f7 4450test_dhcp() {
fcc3c93f
GS
4451 local inport=$1 src_mac=$2 dhcp_type=$3 ciaddr=$4 offer_ip=$5 request_ip=$6 use_ip=$7
4452 shift; shift; shift; shift; shift; shift; shift;
213615b3
NS
4453 if test $use_ip != 0; then
4454 src_ip=$1
4455 dst_ip=$2
4456 shift; shift;
4457 else
4458 src_ip=`ip_to_hex 0 0 0 0`
4459 dst_ip=`ip_to_hex 255 255 255 255`
4460 fi
fcc3c93f
GS
4461 if test $request_ip != 0; then
4462 ip_len=0120
4463 udp_len=010b
4464 else
4465 ip_len=011a
4466 udp_len=0106
4467 fi
4468 local request=ffffffffffff${src_mac}08004510${ip_len}0000000080110000${src_ip}${dst_ip}
281977f7 4469 # udp header and dhcp header
fcc3c93f
GS
4470 request=${request}00440043${udp_len}0000
4471 request=${request}010106006359aa7600000000${ciaddr}000000000000000000000000${src_mac}
281977f7 4472 # client hardware padding
ab187e7e 4473 request=${request}00000000000000000000
281977f7 4474 # server hostname
ab187e7e
BP
4475 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4476 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4477 # boot file name
ab187e7e
BP
4478 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4479 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4480 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4481 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4482 # dhcp magic cookie
ab187e7e 4483 request=${request}63825363
281977f7 4484 # dhcp message type
fcc3c93f
GS
4485 request=${request}3501${dhcp_type}
4486 # dhcp unknown option
4487 request=${request}d70701020304050607
4488 # dhcp pad option
4489 request=${request}00
4490 if test $request_ip != 0; then
4491 # dhcp requested ip
4492 request=${request}3204${request_ip}
4493 fi
4494 # dhcp end option
4495 request=${request}ff
281977f7 4496
697f5993
BP
4497 for port in $inport "$@"; do
4498 : >> $port.expected
4499 done
281977f7 4500 if test $offer_ip != 0; then
fcc3c93f 4501 local srv_mac=$1 srv_ip=$2 dhcp_reply_type=$3 expected_dhcp_opts=$4
281977f7
NS
4502 # total IP length will be the IP length of the request packet
4503 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4504 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4505 udp_len=`expr $ip_len - 20`
04d60f6e
YT
4506 ip_len=$(printf "%x" $ip_len)
4507 udp_len=$(printf "%x" $udp_len)
281977f7
NS
4508 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4509 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4510 # udp header and dhcp header.
4511 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
fcc3c93f
GS
4512 reply=${reply}004300440${udp_len}0000020106006359aa7600000000${ciaddr}
4513 # your ip address; 0 for NAK
4514 if test $dhcp_reply_type = 06; then
4515 reply=${reply}00000000
4516 else
4517 reply=${reply}${offer_ip}
4518 fi
281977f7 4519 # next server ip address, relay agent ip address, client mac address
ab187e7e 4520 reply=${reply}0000000000000000${src_mac}
281977f7 4521 # client hardware padding
ab187e7e 4522 reply=${reply}00000000000000000000
281977f7 4523 # server hostname
ab187e7e
BP
4524 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4525 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4526 # boot file name
ab187e7e
BP
4527 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4528 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4529 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4530 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4531 # dhcp magic cookie
ab187e7e 4532 reply=${reply}63825363
ab187e7e 4533 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
4534 echo $reply >> $inport.expected
4535 else
281977f7 4536 for outport; do
e4543cfe 4537 echo $request >> $outport.expected
281977f7
NS
4538 done
4539 fi
4540 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4541}
4542
4543reset_pcap_file() {
4544 local iface=$1
4545 local pcap_file=$2
4546 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4547options:rxq_pcap=dummy-rx.pcap
4548 rm -f ${pcap_file}*.pcap
4549 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4550options:rxq_pcap=${pcap_file}-rx.pcap
4551}
4552
4553ip_to_hex() {
4554 printf "%02x%02x%02x%02x" "$@"
4555}
4556
4557AT_CAPTURE_FILE([ofctl_monitor0.log])
4558as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4559--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4560
4561echo "---------NB dump-----"
4562ovn-nbctl show
4563echo "---------------------"
4564echo "---------SB dump-----"
4565ovn-sbctl list datapath_binding
4566echo "---------------------"
4567ovn-sbctl list logical_flow
4568echo "---------------------"
4569
4570echo "---------------------"
4571ovn-sbctl dump-flows
4572echo "---------------------"
4573
4574echo "------ hv1 dump ----------"
4575as hv1 ovs-ofctl dump-flows br-int
4576
4577# Send DHCPDISCOVER.
4578offer_ip=`ip_to_hex 10 0 0 4`
4579server_ip=`ip_to_hex 10 0 0 1`
fcc3c93f
GS
4580ciaddr=`ip_to_hex 0 0 0 0`
4581request_ip=0
7c76bf4e 4582expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
fcc3c93f 4583test_dhcp 1 f00000000001 01 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 02 $expected_dhcp_opts
281977f7
NS
4584
4585# NXT_RESUMEs should be 1.
4586OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4587
4588$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4589cat 1.expected | cut -c -48 > expout
4590AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4591# Skipping the IPv4 checksum.
4592cat 1.expected | cut -c 53- > expout
4593AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4594
4595# ovs-ofctl also resumes the packets and this causes other ports to receive
4596# the DHCP request packet. So reset the pcap files so that its easier to test.
4597reset_pcap_file hv1-vif1 hv1/vif1
4598reset_pcap_file hv1-vif2 hv1/vif2
4599rm -f 1.expected
4600rm -f 2.expected
4601
fcc3c93f
GS
4602# Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
4603# address in the Requested IP Address option.
281977f7
NS
4604offer_ip=`ip_to_hex 10 0 0 6`
4605server_ip=`ip_to_hex 10 0 0 1`
fcc3c93f
GS
4606ciaddr=`ip_to_hex 0 0 0 0`
4607request_ip=$offer_ip
7c76bf4e 4608expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
fcc3c93f 4609test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
281977f7
NS
4610
4611# NXT_RESUMEs should be 2.
4612OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4613
4614$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4615cat 2.expected | cut -c -48 > expout
4616AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4617# Skipping the IPv4 checksum.
4618cat 2.expected | cut -c 53- > expout
4619AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4620
4621reset_pcap_file hv1-vif1 hv1/vif1
4622reset_pcap_file hv1-vif2 hv1/vif2
4623rm -f 1.expected
4624rm -f 2.expected
4625
fcc3c93f
GS
4626# Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with a mismatched IP in
4627# the Requested IP Address option, expect a DHCPNAK.
4628offer_ip=`ip_to_hex 10 0 0 6`
4629server_ip=`ip_to_hex 10 0 0 1`
4630ciaddr=`ip_to_hex 0 0 0 0`
4631request_ip=`ip_to_hex 10 0 0 7`
4632expected_dhcp_opts=""
4633test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 06 $expected_dhcp_opts
4634
4635# NXT_RESUMEs should be 3.
4636OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4637
4638$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4639cat 2.expected | cut -c -48 > expout
4640AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4641# Skipping the IPv4 checksum.
4642cat 2.expected | cut -c 53- > expout
4643AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4644
4645reset_pcap_file hv1-vif1 hv1/vif1
4646reset_pcap_file hv1-vif2 hv1/vif2
4647rm -f 1.expected
4648rm -f 2.expected
4649
281977f7
NS
4650# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4651# but should be resumed without the reply.
4652# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4653# one from ovn-controller and the other from "ovs-ofctl resume."
fcc3c93f 4654ciaddr=`ip_to_hex 0 0 0 0`
281977f7 4655offer_ip=0
fcc3c93f
GS
4656request_ip=0
4657test_dhcp 2 f00000000002 08 $ciaddr $offer_ip $request_ip 0 1 1
281977f7 4658
fcc3c93f
GS
4659# NXT_RESUMEs should be 4.
4660OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
281977f7
NS
4661
4662# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 4663OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
4664
4665reset_pcap_file hv1-vif1 hv1/vif1
4666reset_pcap_file hv1-vif2 hv1/vif2
4667rm -f 1.expected
4668rm -f 2.expected
4669
4670# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4671# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4672
fcc3c93f
GS
4673ciaddr=`ip_to_hex 0 0 0 0`
4674test_dhcp 3 f00000000003 01 $ciaddr 0 0 4 0
281977f7
NS
4675
4676# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4677# this lport.
fcc3c93f
GS
4678ciaddr=`ip_to_hex 0 0 0 0`
4679test_dhcp 4 f00000000004 01 $ciaddr 0 0 3 0
281977f7 4680
fcc3c93f
GS
4681# NXT_RESUMEs should be 4.
4682OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
281977f7 4683
fcc3c93f
GS
4684#OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4685#OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 4686
fcc3c93f
GS
4687# Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4688# and ip4.dst set to 10.0.0.1.
213615b3
NS
4689offer_ip=`ip_to_hex 10 0 0 6`
4690server_ip=`ip_to_hex 10 0 0 1`
fcc3c93f
GS
4691ciaddr=$offer_ip
4692request_ip=0
213615b3
NS
4693src_ip=$offer_ip
4694dst_ip=$server_ip
fcc3c93f
GS
4695expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4696test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
213615b3 4697
fcc3c93f
GS
4698# NXT_RESUMEs should be 5.
4699OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
213615b3
NS
4700
4701$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4702cat 2.expected | cut -c -48 > expout
4703AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4704# Skipping the IPv4 checksum.
4705cat 2.expected | cut -c 53- > expout
4706AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4707
4708reset_pcap_file hv1-vif1 hv1/vif1
4709reset_pcap_file hv1-vif2 hv1/vif2
4710rm -f 1.expected
4711rm -f 2.expected
4712
fcc3c93f
GS
4713# Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4714# and ip4.dst set to 255.255.255.255.
213615b3
NS
4715offer_ip=`ip_to_hex 10 0 0 6`
4716server_ip=`ip_to_hex 10 0 0 1`
fcc3c93f
GS
4717ciaddr=$offer_ip
4718request_ip=0
4719src_ip=$offer_ip
4720dst_ip=`ip_to_hex 255 255 255 255`
213615b3 4721expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
fcc3c93f
GS
4722test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
4723
4724# NXT_RESUMEs should be 6.
4725OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4726
4727$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4728cat 2.expected | cut -c -48 > expout
4729AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4730# Skipping the IPv4 checksum.
4731cat 2.expected | cut -c 53- > expout
4732AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4733
4734reset_pcap_file hv1-vif1 hv1/vif1
4735reset_pcap_file hv1-vif2 hv1/vif2
4736rm -f 1.expected
4737rm -f 2.expected
4738
4739# Send DHCPREQUEST in the RENEWING/REBINDING state with a mismatched IP in the
4740# ciaddr, expect a DHCPNAK.
4741offer_ip=`ip_to_hex 10 0 0 6`
4742server_ip=`ip_to_hex 10 0 0 1`
4743ciaddr=`ip_to_hex 10 0 0 7`
4744request_ip=0
213615b3
NS
4745src_ip=$offer_ip
4746dst_ip=`ip_to_hex 255 255 255 255`
fcc3c93f
GS
4747expected_dhcp_opts=""
4748test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
213615b3 4749
fcc3c93f
GS
4750# NXT_RESUMEs should be 7.
4751OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4752
4753$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4754cat 2.expected | cut -c -48 > expout
4755AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4756# Skipping the IPv4 checksum.
4757cat 2.expected | cut -c 53- > expout
4758AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4759
4760reset_pcap_file hv1-vif1 hv1/vif1
4761reset_pcap_file hv1-vif2 hv1/vif2
4762rm -f 1.expected
4763rm -f 2.expected
4764
4765# Send DHCPREQUEST in the RENEWING/REBINDING state without a specifyied ciaddr,
4766# expect a DHCPNAK.
4767offer_ip=`ip_to_hex 10 0 0 6`
4768server_ip=`ip_to_hex 10 0 0 1`
4769ciaddr=`ip_to_hex 0 0 0 0`
4770request_ip=0
4771src_ip=$offer_ip
4772dst_ip=`ip_to_hex 255 255 255 255`
4773expected_dhcp_opts=""
4774test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
4775
4776# NXT_RESUMEs should be 8.
4777OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
213615b3
NS
4778
4779$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4780cat 2.expected | cut -c -48 > expout
4781AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4782# Skipping the IPv4 checksum.
4783cat 2.expected | cut -c 53- > expout
4784AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4785
4786reset_pcap_file hv1-vif1 hv1/vif1
4787reset_pcap_file hv1-vif2 hv1/vif2
4788rm -f 1.expected
4789rm -f 2.expected
4790
4791# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4792# The packet should not be received by ovn-controller.
fcc3c93f 4793ciaddr=`ip_to_hex 0 0 0 0`
213615b3
NS
4794src_ip=`ip_to_hex 10 0 0 6`
4795dst_ip=`ip_to_hex 10 0 0 4`
fcc3c93f 4796test_dhcp 2 f00000000002 03 $ciaddr 0 0 1 $src_ip $dst_ip 1
213615b3 4797
fcc3c93f
GS
4798# NXT_RESUMEs should be 8.
4799OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
213615b3
NS
4800
4801# vif1-tx.pcap should have received the DHCPv4 request packet
4802OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4803
c4d0e4f2 4804OVN_CLEANUP([hv1])
33ac3c83
NS
4805
4806AT_CLEANUP
4807
40df4566 4808AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
4809AT_SKIP_IF([test $HAVE_PYTHON = no])
4810ovn_start
4811
4812ovn-nbctl ls-add ls1
4813ovn-nbctl lsp-add ls1 ls1-lp1 \
4814-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4815
4816ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4817
4818ovn-nbctl lsp-add ls1 ls1-lp2 \
4819-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4820
4821ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4822
40df4566
ZKL
4823ovn-nbctl lsp-add ls1 ls1-lp3 \
4824-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4825
4826ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4827
9060fc9a
MM
4828d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4829options="\"server_id\"=\"00:00:00:10:00:01\"")"
4830
4831ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4832ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4833
4834d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4835options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
33ac3c83 4836
9060fc9a 4837ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
40df4566 4838
33ac3c83
NS
4839ovn-nbctl ls-add ls2
4840ovn-nbctl lsp-add ls2 ls2-lp1 \
4841-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4842ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4843ovn-nbctl lsp-add ls2 ls2-lp2 \
4844-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4845ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4846
4847net_add n1
4848sim_add hv1
4849
4850as hv1
4851ovs-vsctl add-br br-phys
4852ovn_attach n1 br-phys 192.168.0.1
4853ovs-vsctl -- add-port br-int hv1-vif1 -- \
4854 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4855 options:tx_pcap=hv1/vif1-tx.pcap \
4856 options:rxq_pcap=hv1/vif1-rx.pcap \
4857 ofport-request=1
4858
4859ovs-vsctl -- add-port br-int hv1-vif2 -- \
4860 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4861 options:tx_pcap=hv1/vif2-tx.pcap \
4862 options:rxq_pcap=hv1/vif2-rx.pcap \
4863 ofport-request=2
4864
4865ovs-vsctl -- add-port br-int hv1-vif3 -- \
4866 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4867 options:tx_pcap=hv1/vif3-tx.pcap \
4868 options:rxq_pcap=hv1/vif3-rx.pcap \
4869 ofport-request=3
4870
4871ovs-vsctl -- add-port br-int hv1-vif4 -- \
4872 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4873 options:tx_pcap=hv1/vif4-tx.pcap \
4874 options:rxq_pcap=hv1/vif4-rx.pcap \
4875 ofport-request=4
4876
40df4566
ZKL
4877ovs-vsctl -- add-port br-int hv1-vif5 -- \
4878 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4879 options:tx_pcap=hv1/vif5-tx.pcap \
4880 options:rxq_pcap=hv1/vif5-rx.pcap \
4881 ofport-request=5
4882
74868f2c 4883OVN_POPULATE_ARP
33ac3c83
NS
4884
4885sleep 2
4886
4887trim_zeros() {
4888 sed 's/\(00\)\{1,\}$//'
4889}
4890
4891# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4892# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4893# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4894# packet should be received twice (one from ovn-controller and the other
4895# from the "ovs-ofctl monitor br-int resume"
4896test_dhcpv6() {
4897 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
2e5fceb0
NS
4898 if test $msg_code != 0b; then
4899 req_len=2a
4900 else
4901 req_len=1a
4902 fi
4903 local request=ffffffffffff${src_mac}86dd0000000000${req_len}1101${src_lla}
33ac3c83 4904 # dst ip ff02::1:2
ab187e7e 4905 request=${request}ff020000000000000000000000010002
33ac3c83 4906 # udp header and dhcpv6 header
2e5fceb0 4907 request=${request}0222022300${req_len}ffff${msg_code}010203
33ac3c83 4908 # Client identifier
ab187e7e 4909 request=${request}0001000a00030001${src_mac}
2e5fceb0
NS
4910 # Add IA-NA (Identity Association for Non Temporary Address) if msg_code
4911 # is not 11 (information request packet)
4912 if test $msg_code != 0b; then
4913 request=${request}0003000c0102030400000e1000001518
4914 fi
33ac3c83
NS
4915 shift; shift; shift; shift; shift;
4916 if test $offer_ip != 0; then
4917 local server_mac=000000100001
4918 local server_lla=fe80000000000000020000fffe100001
4919 local reply_code=07
4920 if test $msg_code = 01; then
4921 reply_code=02
4922 fi
40df4566
ZKL
4923 local msg_len=54
4924 if test $offer_ip = 1; then
4925 msg_len=28
4926 fi
4927 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4928 # udp header and dhcpv6 header
ab187e7e 4929 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4930 # Client identifier
ab187e7e 4931 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4932 # IA-NA
40df4566 4933 if test $offer_ip != 1; then
ab187e7e 4934 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4935 fi
33ac3c83 4936 # Server identifier
ab187e7e 4937 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4938 echo $reply | trim_zeros >> $inport.expected
4939 else
4940 for outport; do
4941 echo $request | trim_zeros >> $outport.expected
4942 done
4943 fi
4944
4945 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4946}
4947
4948reset_pcap_file() {
4949 local iface=$1
4950 local pcap_file=$2
4951 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4952options:rxq_pcap=dummy-rx.pcap
4953 rm -f ${pcap_file}*.pcap
4954 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4955options:rxq_pcap=${pcap_file}-rx.pcap
4956}
4957
4958AT_CAPTURE_FILE([ofctl_monitor0.log])
4959as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4960--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4961
4962echo "---------NB dump-----"
4963ovn-nbctl show
4964echo "---------------------"
4965echo "---------SB dump-----"
4966ovn-sbctl list datapath_binding
4967echo "---------------------"
4968ovn-sbctl list logical_flow
4969echo "---------------------"
4970
4971echo "---------------------"
4972ovn-sbctl dump-flows
4973echo "---------------------"
4974
4975echo "------ hv1 dump ----------"
4976as hv1 ovs-ofctl dump-flows br-int
4977
4978src_mac=f00000000001
4979src_lla=fe80000000000000f20000fffe000001
4980offer_ip=ae700000000000000000000000000004
4981test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4982
4983# NXT_RESUMEs should be 1.
4984OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4985
4986$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4987# cat 1.expected | trim_zeros > expout
4988cat 1.expected | cut -c -120 > expout
4989AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4990# Skipping the UDP checksum
4991cat 1.expected | cut -c 125- > expout
4992AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4993
4994rm 1.expected
4995
4996# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4997# without any modifications and the packet should be received by ls1-lp1.
4998# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4999# resume and the other from ovs-ofctl monitor resume.
5000
5001reset_pcap_file hv1-vif1 hv1/vif1
5002reset_pcap_file hv1-vif2 hv1/vif2
5003
5004src_mac=f00000000002
5005src_lla=fe80000000000000f20000fffe000002
5006offer_ip=ae700000000000000000000000000005
5007# Set invalid msg_type
5008
5009test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
5010
5011# NXT_RESUMEs should be 2.
5012OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5013
5014# vif2-tx.pcap should not have received the DHCPv6 reply packet
5015rm 2.packets
5016$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
5017AT_CHECK([cat 2.packets], [0], [])
5018
5019# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
5020$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
5021cat 1.expected > expout
5022AT_CHECK([cat 1.packets], [0], [expout])
5023
5024# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
5025# There should be no DHCPv6 reply from ovn-controller and the request packet
5026# should be received by ls2-lp2.
5027
5028src_mac=f00000000003
5029src_lla=fe80000000000000f20000fffe000003
5030test_dhcpv6 3 $src_mac $src_lla 01 0 4
5031
5032# NXT_RESUMEs should be 2 only.
5033OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5034
5035# vif3-tx.pcap should not have received the DHCPv6 reply packet
5036$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
5037AT_CHECK([cat 3.packets], [0], [])
5038
5039# vif4-tx.pcap should have received the DHCPv6 request packet
5040$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
5041cat 4.expected > expout
5042AT_CHECK([cat 4.packets], [0], [expout])
5043
40df4566 5044# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
2e5fceb0 5045# The DHCPv6 reply shouldn't contain offer_ip.
40df4566
ZKL
5046src_mac=f00000000022
5047src_lla=fe80000000000000f20000fffe000022
5048reset_pcap_file hv1-vif5 hv1/vif5
5049test_dhcpv6 5 $src_mac $src_lla 01 1 5
5050
5051# NXT_RESUMEs should be 3.
5052OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5053
5054$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
5055# Skipping the UDP checksum
5056cat 5.expected | cut -c 1-120,125- > expout
2e5fceb0
NS
5057AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
5058
5059# Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
5060# shouldn't contain offer_ip
5061src_mac=f00000000022
5062src_lla=fe80000000000000f20000fffe000022
5063reset_pcap_file hv1-vif5 hv1/vif5
5064rm -f 5.expected
5065test_dhcpv6 5 $src_mac $src_lla 0b 1 5
5066
5067# NXT_RESUMEs should be 4.
5068OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5069
5070$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap |
5071trim_zeros > 5.packets
5072# Skipping the UDP checksum
5073cat 5.expected | cut -c 1-120,125- > expout
40df4566
ZKL
5074AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
5075
c4d0e4f2 5076OVN_CLEANUP([hv1])
281977f7
NS
5077
5078AT_CLEANUP
5079
c1645003 5080AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
5081AT_SKIP_IF([test $HAVE_PYTHON = no])
5082ovn_start
5083
5084# Logical network:
5085# Two LRs - R1 and R2 that are connected to each other via LS "join"
5086# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
5087# connected to it. R2 has alice (172.16.1.0/24) connected to it.
5088# R2 is a gateway router.
5089
5090
5091
5092# Create two hypervisor and create OVS ports corresponding to logical ports.
5093net_add n1
5094
5095sim_add hv1
5096as hv1
5097ovs-vsctl add-br br-phys
5098ovn_attach n1 br-phys 192.168.0.1
5099ovs-vsctl -- add-port br-int hv1-vif1 -- \
5100 set interface hv1-vif1 external-ids:iface-id=foo1 \
5101 options:tx_pcap=hv1/vif1-tx.pcap \
5102 options:rxq_pcap=hv1/vif1-rx.pcap \
5103 ofport-request=1
5104
5105
5106sim_add hv2
5107as hv2
5108ovs-vsctl add-br br-phys
5109ovn_attach n1 br-phys 192.168.0.2
5110ovs-vsctl -- add-port br-int hv2-vif1 -- \
5111 set interface hv2-vif1 external-ids:iface-id=alice1 \
5112 options:tx_pcap=hv2/vif1-tx.pcap \
5113 options:rxq_pcap=hv2/vif1-rx.pcap \
5114 ofport-request=1
5115
5116# Pre-populate the hypervisors' ARP tables so that we don't lose any
5117# packets for ARP resolution (native tunneling doesn't queue packets
5118# for ARP resolution).
74868f2c 5119OVN_POPULATE_ARP
c1645003
GS
5120
5121ovn-nbctl create Logical_Router name=R1
5122ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5123
ea46a4e9
JP
5124ovn-nbctl ls-add foo
5125ovn-nbctl ls-add alice
5126ovn-nbctl ls-add join
c1645003
GS
5127
5128# Connect foo to R1
31114af7 5129ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 5130ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 5131 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
5132
5133# Connect alice to R2
31114af7 5134ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 5135ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 5136 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
5137
5138# Connect R1 to join
31114af7 5139ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 5140ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 5141 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
5142
5143# Connect R2 to join
31114af7 5144ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 5145ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 5146 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
5147
5148
5149#install static routes
5150ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5151ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
5152R1 static_routes @lrt
5153
5154ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5155ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5156R2 static_routes @lrt
5157
5158# Create logical port foo1 in foo
31ed1192
JP
5159ovn-nbctl lsp-add foo foo1 \
5160-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
5161
5162# Create logical port alice1 in alice
31ed1192
JP
5163ovn-nbctl lsp-add alice alice1 \
5164-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
5165
5166
5167# Allow some time for ovn-northd and ovn-controller to catch up.
5168# XXX This should be more systematic.
5169sleep 2
5170
5171ip_to_hex() {
5172 printf "%02x%02x%02x%02x" "$@"
5173}
c1645003
GS
5174
5175# Send ip packets between foo1 and alice1
5176src_mac="f00000010203"
5177dst_mac="000001010203"
5178src_ip=`ip_to_hex 192 168 1 2`
5179dst_ip=`ip_to_hex 172 16 1 2`
5180packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5181
5182echo "---------NB dump-----"
5183ovn-nbctl show
5184echo "---------------------"
5185ovn-nbctl list logical_router
5186echo "---------------------"
5187ovn-nbctl list logical_router_port
5188echo "---------------------"
5189
5190echo "---------SB dump-----"
5191ovn-sbctl list datapath_binding
5192echo "---------------------"
5193ovn-sbctl list port_binding
5194echo "---------------------"
5195ovn-sbctl dump-flows
5196echo "---------------------"
5197ovn-sbctl list chassis
5198ovn-sbctl list encap
5199echo "---------------------"
5200
c1645003
GS
5201# Packet to Expect at alice1
5202src_mac="000002010203"
5203dst_mac="f00000010204"
5204src_ip=`ip_to_hex 192 168 1 2`
5205dst_ip=`ip_to_hex 172 16 1 2`
5206expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
5207
5208
5209as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5210as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
5211
ab39371d
RM
5212echo "------ hv1 dump after packet 1 ----------"
5213as hv1 ovs-ofctl show br-int
5214as hv1 ovs-ofctl dump-flows br-int
5215echo "------ hv2 dump after packet 1 ----------"
5216as hv2 ovs-ofctl show br-int
5217as hv2 ovs-ofctl dump-flows br-int
5218echo "----------------------------"
5219
49d7c759
BP
5220echo $expected > expected
5221OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 5222
34114cf8
GS
5223# Delete the router and re-create it. Things should work as before.
5224ovn-nbctl lr-del R2
5225ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5226# Connect alice to R2
5227ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5228# Connect R2 to join
5229ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
5230
5231ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5232ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5233R2 static_routes @lrt
5234
5235# Wait for ovn-controller to catch up.
5236sleep 1
5237
5238# Send the packet again.
5239as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
5240
5241echo "------ hv1 dump after packet 2 ----------"
5242as hv1 ovs-ofctl show br-int
5243as hv1 ovs-ofctl dump-flows br-int
5244echo "------ hv2 dump after packet 2 ----------"
5245as hv2 ovs-ofctl show br-int
5246as hv2 ovs-ofctl dump-flows br-int
5247echo "----------------------------"
5248
49d7c759
BP
5249echo $expected >> expected
5250OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 5251
7a8f15e0 5252OVN_CLEANUP([hv1],[hv2])
c1645003
GS
5253
5254AT_CLEANUP
bb3c4568
FF
5255
5256AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5257AT_KEYWORDS([router-icmp-reply])
5258AT_SKIP_IF([test $HAVE_PYTHON = no])
5259ovn_start
5260
5261# Logical network:
5262# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5263# and has switch ls2 (172.16.1.0/24) connected to it.
5264
fa2a27b2 5265ovn-nbctl lr-add R1
bb3c4568 5266
ea46a4e9
JP
5267ovn-nbctl ls-add ls1
5268ovn-nbctl ls-add ls2
bb3c4568
FF
5269
5270# Connect ls1 to R1
31114af7 5271ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 5272ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 5273 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
5274
5275# Connect ls2 to R1
31114af7 5276ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 5277ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 5278 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
5279
5280# Create logical port ls1-lp1 in ls1
31ed1192
JP
5281ovn-nbctl lsp-add ls1 ls1-lp1 \
5282-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
5283
5284# Create logical port ls2-lp1 in ls2
31ed1192
JP
5285ovn-nbctl lsp-add ls2 ls2-lp1 \
5286-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
5287
5288# Create one hypervisor and create OVS ports corresponding to logical ports.
5289net_add n1
5290
5291sim_add hv1
5292as hv1
5293ovs-vsctl add-br br-phys
5294ovn_attach n1 br-phys 192.168.0.1
5295ovs-vsctl -- add-port br-int vif1 -- \
5296 set interface vif1 external-ids:iface-id=ls1-lp1 \
5297 options:tx_pcap=hv1/vif1-tx.pcap \
5298 options:rxq_pcap=hv1/vif1-rx.pcap \
5299 ofport-request=1
5300
5301ovs-vsctl -- add-port br-int vif2 -- \
5302 set interface vif2 external-ids:iface-id=ls2-lp1 \
5303 options:tx_pcap=hv1/vif2-tx.pcap \
5304 options:rxq_pcap=hv1/vif2-rx.pcap \
5305 ofport-request=1
5306
5307
5308# Allow some time for ovn-northd and ovn-controller to catch up.
5309# XXX This should be more systematic.
5310sleep 1
5311
5312
5313ip_to_hex() {
5314 printf "%02x%02x%02x%02x" "$@"
5315}
bb3c4568
FF
5316for i in 1 2; do
5317 : > vif$i.expected
5318done
5319# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
5320#
5321# Causes a packet to be received on INPORT. The packet is an ICMPv4
5322# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
5323# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
5324# provided, then it should be the ip and icmp checksums of the packet
5325# responded; otherwise, no reply is expected.
5326# In the absence of an ip checksum calculation helpers, this relies
5327# on the caller to provide the checksums for the ip and icmp headers.
5328# XXX This should be more systematic.
5329#
5330# INPORT is an lport number, e.g. 11 for vif11.
5331# ETH_SRC and ETH_DST are each 12 hex digits.
5332# IPV4_SRC and IPV4_DST are each 8 hex digits.
5333# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
5334# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
5335test_ipv4_icmp_request() {
5336 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
5337 local exp_ip_chksum=$8 exp_icmp_chksum=$9
5338 shift; shift; shift; shift; shift; shift; shift
5339 shift; shift
5340
5341 # Use ttl to exercise section 4.2.2.9 of RFC1812
5342 local ip_ttl=01
5343 local icmp_id=5fbf
5344 local icmp_seq=0001
5345 local icmp_data=$(seq 1 56 | xargs printf "%02x")
5346 local icmp_type_code_request=0800
5347 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5348 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
5349
5350 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
5351 if test X$exp_icmp_chksum != X; then
5352 # Expect to receive the reply, if any. In same port where packet was sent.
5353 # Note: src and dst fields are expected to be reversed.
5354 local icmp_type_code_response=0000
5355 local reply_icmp_ttl=fe
5356 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5357 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
5358 echo $reply >> vif$inport.expected
5359 fi
5360}
5361
5362# Send ping packet to router's ip addresses, from each of the 2 logical ports.
5363rtr_l1_ip=$(ip_to_hex 192 168 1 1)
5364rtr_l2_ip=$(ip_to_hex 172 16 1 1)
5365l1_ip=$(ip_to_hex 192 168 1 2)
5366l2_ip=$(ip_to_hex 172 16 1 2)
5367
5368# Ping router ip address that is on same subnet as the logical port
5369test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
5370test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
5371
5372# Ping router ip address that is on the other side of the logical ports
5373test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
5374test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
5375
a64bb573 5376
bb3c4568
FF
5377echo "---------NB dump-----"
5378ovn-nbctl show
5379echo "---------------------"
5380ovn-nbctl list logical_router
5381echo "---------------------"
5382ovn-nbctl list logical_router_port
5383echo "---------------------"
5384
5385echo "---------SB dump-----"
5386ovn-sbctl list datapath_binding
5387echo "---------------------"
5388ovn-sbctl list logical_flow
5389echo "---------------------"
5390
5391echo "------ hv1 dump ----------"
5392as hv1 ovs-ofctl dump-flows br-int
5393
5394# Now check the packets actually received against the ones expected.
5395for inport in 1 2; do
49d7c759 5396 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
5397done
5398
7a8f15e0 5399OVN_CLEANUP([hv1])
a64bb573
MM
5400AT_CLEANUP
5401
5402AT_SETUP([ovn -- policy-based routing: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5403AT_KEYWORDS([policy-based-routing])
5404AT_SKIP_IF([test $HAVE_PYTHON = no])
5405ovn_start
5406
5407# Logical network:
5408# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5409# and has switch ls2 (172.16.1.0/24) connected to it.
5410
5411ovn-nbctl lr-add R1
5412
5413ovn-nbctl ls-add ls1
5414ovn-nbctl ls-add ls2
5415ovn-nbctl ls-add ls3
5416
5417# Connect ls1 to R1
5418ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
5419ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5420 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5421
5422# Connect ls2 to R1
5423ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
5424ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5425 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5426
5427# Connect ls3 to R1
5428ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 20.20.1.1/24
5429ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
5430 type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
5431
5432# Create logical port ls1-lp1 in ls1
5433ovn-nbctl lsp-add ls1 ls1-lp1 \
5434-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
5435
5436# Create logical port ls2-lp1 in ls2
5437ovn-nbctl lsp-add ls2 ls2-lp1 \
5438-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
5439
5440# Create logical port ls3-lp1 in ls3
5441ovn-nbctl lsp-add ls3 ls3-lp1 \
5442-- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 20.20.1.2"
5443
5444# Create one hypervisor and create OVS ports corresponding to logical ports.
5445net_add n1
5446
5447sim_add pbr-hv
5448as pbr-hv
5449ovs-vsctl add-br br-phys
5450ovn_attach n1 br-phys 192.168.0.1
5451
5452ovs-vsctl -- add-port br-int vif1 -- \
5453 set interface vif1 external-ids:iface-id=ls1-lp1 \
5454 options:tx_pcap=pbr-hv/vif1-tx.pcap \
5455 options:rxq_pcap=pbr-hv/vif1-rx.pcap \
5456 ofport-request=1
5457
5458ovs-vsctl -- add-port br-int vif2 -- \
5459 set interface vif2 external-ids:iface-id=ls2-lp1 \
5460 options:tx_pcap=pbr-hv/vif2-tx.pcap \
5461 options:rxq_pcap=pbr-hv/vif2-rx.pcap \
5462 ofport-request=1
5463
5464ovs-vsctl -- add-port br-int vif3 -- \
5465 set interface vif3 external-ids:iface-id=ls3-lp1 \
5466 options:tx_pcap=pbr-hv/vif3-tx.pcap \
5467 options:rxq_pcap=pbr-hv/vif3-rx.pcap \
5468 ofport-request=1
5469
5470# Allow some time for ovn-northd and ovn-controller to catch up.
5471# XXX This should be more systematic.
5472sleep 1
5473
5474ls1_ro_mac=00:00:00:01:02:f1
5475ls1_ro_ip=192.168.1.1
5476
5477ls2_ro_mac=00:00:00:01:02:f2
5478ls2_ro_ip=172.16.1.1
5479
5480ls3_ro_mac=00:00:00:01:02:f3
5481
5482ls1_p1_mac=00:00:00:01:02:03
5483ls1_p1_ip=192.168.1.2
5484
5485ls2_p1_mac=00:00:00:01:02:04
5486ls2_p1_ip=172.16.1.2
5487
5488ls3_p1_mac=00:00:00:01:02:05
5489
5490# Create a drop policy
5491ovn-nbctl lr-policy-add R1 10 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" drop
5492
5493# Check logical flow
5494AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
54951
5496])
5497
5498# Send packet.
5499packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5500 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5501 udp && udp.src==53 && udp.dst==4369"
5502
5503as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5504
5505# Check if packet hit the drop policy
5506AT_CHECK([ovs-ofctl dump-flows br-int | \
5507 grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24 actions=drop" | \
5508 grep "priority=10" | \
5509 grep "n_packets=1" | wc -l], [0], [dnl
55101
5511])
5512
5513# Expected to drop the packet.
5514$PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
5515rcvd_packet=`cat vif2.packets`
5516AT_FAIL_IF([rcvd_packet = ""])
5517
5518# Override drop policy with allow
5519ovn-nbctl lr-policy-add R1 20 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" allow
5520
5521# Check logical flow
5522AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
55232
5524])
5525
5526# Send packet.
5527packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5528 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5529 udp && udp.src==53 && udp.dst==4369"
5530as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5531
5532# Check if packet hit the allow policy
5533AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5534 grep "192.168.1.0" | \
5535 grep "priority=20" | wc -l], [0], [dnl
55361
5537])
5538
5539# Expected packet has TTL decreased by 1
5540expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
5541 ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5542 udp && udp.src==53 && udp.dst==4369"
5543echo $expected | ovstest test-ovn expr-to-packets > expected
5544
5545OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
5546
5547# Override allow policy with reroute
5548ovn-nbctl lr-policy-add R1 30 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" reroute 20.20.1.2
5549
5550# Check logical flow
5551AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5552 grep "192.168.1.0" | \
5553 grep "priority=30" | wc -l], [0], [dnl
55541
5555])
5556
5557# Send packet.
5558packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5559 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5560 udp && udp.src==53 && udp.dst==4369"
5561as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5562
5563echo "southbound flows"
5564
5565ovn-sbctl dump-flows | grep lr_in_policy
5566echo "ovs flows"
5567ovs-ofctl dump-flows br-int
5568# Check if packet hit the allow policy
5569AT_CHECK([ovs-ofctl dump-flows br-int | \
5570 grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24" | \
5571 grep "priority=30" | \
5572 grep "n_packets=1" | wc -l], [0], [dnl
55731
5574])
5575echo "packet hit reroute policy"
5576
5577# Expected packet has TTL decreased by 1
5578expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
5579 ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5580 udp && udp.src==53 && udp.dst==4369"
5581echo $expected | ovstest test-ovn expr-to-packets > 3.expected
5582
5583OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
5584
5585OVN_CLEANUP([pbr-hv])
5586AT_CLEANUP
5587
5588AT_SETUP([ovn -- policy-based routing IPv6: 1 HVs, 3 LSs, 1 lport/LS, 1 LR])
5589AT_KEYWORDS([policy-based-routing])
5590AT_SKIP_IF([test $HAVE_PYTHON = no])
5591ovn_start
5592
5593# Logical network:
5594# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5595# and has switch ls2 (172.16.1.0/24) connected to it.
5596
5597ovn-nbctl lr-add R1
5598
5599ovn-nbctl ls-add ls1
5600ovn-nbctl ls-add ls2
5601ovn-nbctl ls-add ls3
5602
5603# Connect ls1 to R1
5604ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 2001::1/64
5605ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5606 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5607
5608# Connect ls2 to R1
5609ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 2002::1/64
5610ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5611 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5612
5613# Connect ls3 to R1
5614ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 2003::1/64
5615ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
5616 type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
5617
5618# Create logical port ls1-lp1 in ls1
5619ovn-nbctl lsp-add ls1 ls1-lp1 \
5620-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 2001::2"
5621
5622# Create logical port ls2-lp1 in ls2
5623ovn-nbctl lsp-add ls2 ls2-lp1 \
5624-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 2002::2"
5625
5626# Create logical port ls3-lp1 in ls3
5627ovn-nbctl lsp-add ls3 ls3-lp1 \
5628-- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 2003::2"
5629
5630# Create one hypervisor and create OVS ports corresponding to logical ports.
5631net_add n1
5632
5633sim_add pbr-hv
5634as pbr-hv
5635ovs-vsctl add-br br-phys
5636ovn_attach n1 br-phys 192.168.0.1
5637
5638ovs-vsctl -- add-port br-int vif1 -- \
5639 set interface vif1 external-ids:iface-id=ls1-lp1 \
5640 options:tx_pcap=pbr-hv/vif1-tx.pcap \
5641 options:rxq_pcap=pbr-hv/vif1-rx.pcap \
5642 ofport-request=1
5643
5644ovs-vsctl -- add-port br-int vif2 -- \
5645 set interface vif2 external-ids:iface-id=ls2-lp1 \
5646 options:tx_pcap=pbr-hv/vif2-tx.pcap \
5647 options:rxq_pcap=pbr-hv/vif2-rx.pcap \
5648 ofport-request=1
5649
5650ovs-vsctl -- add-port br-int vif3 -- \
5651 set interface vif3 external-ids:iface-id=ls3-lp1 \
5652 options:tx_pcap=pbr-hv/vif3-tx.pcap \
5653 options:rxq_pcap=pbr-hv/vif3-rx.pcap \
5654 ofport-request=1
5655
5656# Allow some time for ovn-northd and ovn-controller to catch up.
5657# XXX This should be more systematic.
5658sleep 1
5659
5660ls1_ro_mac=00:00:00:01:02:f1
5661ls1_ro_ip=2001::1
5662
5663ls2_ro_mac=00:00:00:01:02:f2
5664ls2_ro_ip=2002::1
5665
5666ls3_ro_mac=00:00:00:01:02:f3
5667
5668ls1_p1_mac=00:00:00:01:02:03
5669ls1_p1_ip=2001::2
5670
5671ls2_p1_mac=00:00:00:01:02:04
5672ls2_p1_ip=2002::2
5673
5674ls3_p1_mac=00:00:00:01:02:05
5675
5676# Create a drop policy
5677ovn-nbctl lr-policy-add R1 10 "ip6.src==2001::/64 && ip6.dst==2002::/64" drop
5678
5679# Check logical flow
5680AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
56811
5682])
5683
5684# Send packet.
5685packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5686 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5687 udp && udp.src==53 && udp.dst==4369"
5688
5689as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5690
5691# Check if packet hit the drop policy
5692AT_CHECK([ovs-ofctl dump-flows br-int | \
5693 grep "ipv6_src=2001::/64,ipv6_dst=2002::/64 actions=drop" | \
5694 grep "priority=10" | \
5695 grep "n_packets=1" | wc -l], [0], [dnl
56961
5697])
5698
5699# Expected to drop the packet.
5700$PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
5701rcvd_packet=`cat vif2.packets`
5702AT_FAIL_IF([rcvd_packet = ""])
5703
5704# Override drop policy with allow
5705ovn-nbctl lr-policy-add R1 20 "ip6.src==2001::/64 && ip6.dst==2002::/64" allow
5706
5707# Check logical flow
5708AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
57092
5710])
5711
5712# Send packet.
5713packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5714 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5715 udp && udp.src==53 && udp.dst==4369"
5716as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5717
5718# Check if packet hit the allow policy
5719AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5720 grep "2001" | \
5721 grep "priority=20" | wc -l], [0], [dnl
57221
5723])
5724
5725# Expected packet has TTL decreased by 1
5726expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
5727 ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5728 udp && udp.src==53 && udp.dst==4369"
5729echo $expected | ovstest test-ovn expr-to-packets > expected
5730
5731OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
5732
5733# Override allow policy with reroute
5734ovn-nbctl lr-policy-add R1 30 "ip6.src==2001::/64 && ip6.dst==2002::/64" reroute 2003::2
5735
5736# Check logical flow
5737AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5738 grep "2001" | \
5739 grep "priority=30" | wc -l], [0], [dnl
57401
5741])
5742
5743# Send packet.
5744packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5745 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5746 udp && udp.src==53 && udp.dst==4369"
5747as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5748
5749echo "southbound flows"
5750
5751ovn-sbctl dump-flows | grep lr_in_policy
5752echo "ovs flows"
5753ovs-ofctl dump-flows br-int
5754# Check if packet hit the allow policy
5755AT_CHECK([ovs-ofctl dump-flows br-int | \
5756 grep "ipv6_src=2001::/64,ipv6_dst=2002::/64" | \
5757 grep "priority=30" | \
5758 grep "n_packets=1" | wc -l], [0], [dnl
57591
5760])
5761echo "packet hit reroute policy"
5762
5763# Expected packet has TTL decreased by 1
5764expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
5765 ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5766 udp && udp.src==53 && udp.dst==4369"
5767echo $expected | ovstest test-ovn expr-to-packets > 3.expected
5768
5769OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
bb3c4568 5770
a64bb573 5771OVN_CLEANUP([pbr-hv])
bb3c4568 5772AT_CLEANUP
94f79fcb
RB
5773
5774# 1 hypervisor, 1 port
5775# make sure that the port state is properly set to up and back down
5776# when created and deleted.
5777AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
5778ovn_start
5779
5780ovn-nbctl ls-add ls1
5781ovn-nbctl lsp-add ls1 lp1
5782ovn-nbctl lsp-set-addresses lp1 unknown
5783
5784net_add n1
5785sim_add hv1
5786as hv1 ovs-vsctl add-br br-phys
5787as hv1 ovn_attach n1 br-phys 192.168.0.1
5788
5789as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5790OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5791
5792as hv1 ovs-vsctl del-port br-int vif1
5793OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5794
7a8f15e0 5795OVN_CLEANUP([hv1])
94f79fcb 5796
94f79fcb 5797AT_CLEANUP
e75451fe 5798
ccc6e1db
FF
5799# 1 hypervisor, 1 port
5800# make sure that the OF rules created to support a datapath are added/cleared
5801# when logical switch is created and removed.
5802AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 5803AT_KEYWORDS([cleanup])
ccc6e1db
FF
5804ovn_start
5805
5806net_add n1
5807sim_add hv1
5808as hv1 ovs-vsctl add-br br-phys
5809as hv1 ovn_attach n1 br-phys 192.168.0.1
5810
5811# This shell function checks if OF rules in br-int have clauses
5812# related to OVN datapaths. The caller determines if it should find
5813# a match in the output, or not.
5814#
5815# EXPECT_DATAPATH param determines whether flows that refer to
5816# datapath to should be present or not. 0 means
5817# they should not be.
5818# STAGE_INFO param is a simple string to help identify the stage
5819# in the test when this function was invoked.
5820test_datapath_in_of_rules() {
5821 local expect_datapath=$1 stage_info=$2
5822 echo "------ ovn-nbctl show ${stage_info} ------"
5823 ovn-nbctl show
5824 echo "------ ovn-sbctl show ${stage_info} ------"
5825 ovn-sbctl show
5826 echo "------ OF rules ${stage_info} ------"
5827 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
5828 # if there is a datapath mentioned in the output, check for the
5829 # magic keyword that represents one, based on the exit status of
5830 # a quiet grep
5831 if test $expect_datapath != 0; then
4618b102 5832 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 5833 else
4618b102 5834 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
5835 fi
5836}
5837
5838test_datapath_in_of_rules 0 "before ls+port create"
5839
5840ovn-nbctl ls-add ls1
5841ovn-nbctl lsp-add ls1 lp1
5842ovn-nbctl lsp-set-addresses lp1 unknown
5843
5844as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5845OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5846
5847test_datapath_in_of_rules 1 "after port is bound"
5848
5849as hv1 ovs-vsctl del-port br-int vif1
5850OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5851
5852ovn-nbctl lsp-set-addresses lp1
5853ovn-nbctl lsp-del lp1
5854ovn-nbctl ls-del ls1
5855
5856# wait for earlier changes to take effect
5857AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
5858
5859# ensure OF rules are no longer present. There used to be a bug here.
5860test_datapath_in_of_rules 0 "after lport+ls removal"
5861
5862OVN_CLEANUP([hv1])
5863
5864AT_CLEANUP
5865
f8a8db39 5866AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
5867AT_SKIP_IF([test $HAVE_PYTHON = no])
5868ovn_start
5869
5870#TODO: since patch port for IPv6 logical router port is not ready not,
5871# so we are not going to test vifs on different lswitches cases. Try
5872# to update for that once relevant stuff implemented.
5873
5874# In this test cases we create 1 lswitch, it has 2 VIF ports attached
5875# with. NS packet we test, from one VIF for another VIF, will be replied
5876# by local ovn-controller, but not by target VIF.
5877
5878# Create hypervisors and logical switch lsw0.
5879ovn-nbctl ls-add lsw0
5880net_add n1
5881sim_add hv1
5882as hv1
5883ovs-vsctl add-br br-phys
5884ovn_attach n1 br-phys 192.168.0.2
5885
5886# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5887ovs-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
5888ovn-nbctl lsp-add lsw0 lp1
5889ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5890ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5891
5892# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5893ovs-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
5894ovn-nbctl lsp-add lsw0 lp2
5895ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5896ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5897
5898# Add ACL rule for ICMPv6 on lsw0
5899ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5900ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5901ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5902
5903# Allow some time for ovn-northd and ovn-controller to catch up.
5904# XXX This should be more systematic.
5905sleep 1
5906
5907# Given the name of a logical port, prints the name of the hypervisor
5908# on which it is located.
5909vif_to_hv() {
5910 echo hv1${1%?}
5911}
e75451fe
ZKL
5912for i in 1 2; do
5913 : > $i.expected
5914done
5915
5916# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5917# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5918# vif2 will not receive NS packet, since ovn-controller will reply for it.
5919ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5920na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5921
5922as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 5923echo $na_packet >> 1.expected
e75451fe 5924
e75451fe
ZKL
5925echo "------ hv1 dump ------"
5926as hv1 ovs-vsctl show
5927as hv1 ovs-ofctl -O OpenFlow13 show br-int
5928as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5929
5930for i in 1 2; do
49d7c759 5931 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
5932done
5933
7a8f15e0 5934OVN_CLEANUP([hv1])
e75451fe
ZKL
5935
5936AT_CLEANUP
7417d147
RM
5937
5938AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
5939ovn_start
5940
5941net_add n1
5942
5943sim_add hv1
5944as hv1
5945ovs-vsctl add-br br-phys
5946ovn_attach n1 br-phys 192.168.0.1
5947
5948row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5949ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5950ovn-nbctl destroy Address_Set $row
5951
5952sleep 1
5953
5954# A bug previously existed in the address set support code
5955# that caused ovn-controller to crash after an address set
5956# was updated and then removed. This test case ensures
5957# that ovn-controller is at least still running after
5958# creating, updating, and deleting an address set.
5959AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5960
5961OVN_CLEANUP([hv1])
5962
5963AT_CLEANUP
8639f9be
ND
5964
5965AT_SETUP([ovn -- ipam])
8639f9be
ND
5966AT_SKIP_IF([test $HAVE_PYTHON = no])
5967ovn_start
5968
5969# Add a port to a switch that does not have a subnet set, then set the
5970# subnet which should result in an address being allocated for the port.
f1301a25 5971ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
8639f9be
ND
5972ovn-nbctl ls-add sw0
5973ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 5974ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be 5975AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
c814545b 5976 ["0a:00:00:a8:01:03 192.168.1.2"
8639f9be
ND
5977])
5978
5979# Add 9 more ports to sw0, addresses should all be unique.
5980for n in `seq 1 9`; do
11547f85 5981 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5982done
5983AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
c814545b 5984 ["0a:00:00:a8:01:04 192.168.1.3"
8639f9be
ND
5985])
5986AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
c814545b 5987 ["0a:00:00:a8:01:05 192.168.1.4"
8639f9be
ND
5988])
5989AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
c814545b 5990 ["0a:00:00:a8:01:06 192.168.1.5"
8639f9be
ND
5991])
5992AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
c814545b 5993 ["0a:00:00:a8:01:07 192.168.1.6"
8639f9be
ND
5994])
5995AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
c814545b 5996 ["0a:00:00:a8:01:08 192.168.1.7"
8639f9be
ND
5997])
5998AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
c814545b 5999 ["0a:00:00:a8:01:09 192.168.1.8"
8639f9be
ND
6000])
6001AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
c814545b 6002 ["0a:00:00:a8:01:0a 192.168.1.9"
8639f9be
ND
6003])
6004AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
c814545b 6005 ["0a:00:00:a8:01:0b 192.168.1.10"
8639f9be
ND
6006])
6007AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
c814545b 6008 ["0a:00:00:a8:01:0c 192.168.1.11"
8639f9be
ND
6009])
6010
6011# Trying similar tests with a second switch. MAC addresses should be unique
6012# across both switches but IP's only need to be unique within the same switch.
6013ovn-nbctl ls-add sw1
6014ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 6015ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be 6016AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
c814545b 6017 ["0a:00:00:a8:01:0d 192.168.1.2"
8639f9be
ND
6018])
6019
6020for n in `seq 11 19`; do
11547f85 6021 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
6022done
6023AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
c814545b 6024 ["0a:00:00:a8:01:0e 192.168.1.3"
8639f9be
ND
6025])
6026AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
c814545b 6027 ["0a:00:00:a8:01:0f 192.168.1.4"
8639f9be
ND
6028])
6029AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
c814545b 6030 ["0a:00:00:a8:01:10 192.168.1.5"
8639f9be
ND
6031])
6032AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
c814545b 6033 ["0a:00:00:a8:01:11 192.168.1.6"
8639f9be
ND
6034])
6035AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
c814545b 6036 ["0a:00:00:a8:01:12 192.168.1.7"
8639f9be
ND
6037])
6038AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
c814545b 6039 ["0a:00:00:a8:01:13 192.168.1.8"
8639f9be
ND
6040])
6041AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
c814545b 6042 ["0a:00:00:a8:01:14 192.168.1.9"
8639f9be
ND
6043])
6044AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
c814545b 6045 ["0a:00:00:a8:01:15 192.168.1.10"
8639f9be
ND
6046])
6047AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
c814545b 6048 ["0a:00:00:a8:01:16 192.168.1.11"
8639f9be
ND
6049])
6050
6051# Change a port's address to test for multiple ip's for a single address entry
6052# and addresses set by the user.
c814545b 6053ovn-nbctl lsp-set-addresses p0 "0a:00:00:a8:01:17 192.168.1.2 192.168.1.12 192.168.1.14"
11547f85 6054ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be 6055AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
c814545b 6056 ["0a:00:00:a8:01:18 192.168.1.13"
8639f9be
ND
6057])
6058
6059# Test for logical router port address management.
6060ovn-nbctl create Logical_Router name=R1
6061ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
c814545b 6062network="192.168.1.1/24" mac=\"0a:00:00:a8:01:19\" \
8639f9be
ND
6063-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
6064-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 6065ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be 6066AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
c814545b 6067 ["0a:00:00:a8:01:1a 192.168.1.15"
8639f9be
ND
6068])
6069
6070# Test for address reuse after logical port is deleted.
6071ovn-nbctl lsp-del p0
11547f85 6072ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be 6073AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
c814545b 6074 ["0a:00:00:a8:01:03 192.168.1.2"
8639f9be
ND
6075])
6076
6077# Test for multiple addresses to one logical port.
6078ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
c814545b 6079"0a:00:00:a8:01:1b 192.168.1.12" "0a:00:00:a8:01:1c 192.168.1.14"
11547f85 6080ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be 6081AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
c814545b 6082 ["0a:00:00:a8:01:17 192.168.1.16"
8639f9be
ND
6083])
6084
6085# Test for exhausting subnet address space.
6086ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 6087ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be 6088AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
c814545b 6089 ["0a:00:00:10:01:03 172.16.1.2"
8639f9be
ND
6090])
6091
11547f85 6092ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 6093AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
c814545b 6094 ["0a:00:00:00:00:01"
8639f9be
ND
6095])
6096
6097# Test that address management does not add duplicate MAC for lsp/lrp peers.
6098ovn-nbctl create Logical_Router name=R2
6099ovn-nbctl ls-add sw3
6100ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
c814545b 6101"0a:00:00:a8:01:18"
8639f9be 6102ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
c814545b 6103network="192.168.2.1/24" mac=\"0a:00:00:a8:01:18\" \
8639f9be
ND
6104-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
6105-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 6106ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be 6107AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
c814545b 6108 ["0a:00:00:a8:01:1d 192.168.1.17"
8639f9be
ND
6109])
6110
6374d518
LR
6111# Test static MAC address with dynamically allocated IP
6112ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
6113"fe:dc:ba:98:76:54 dynamic"
6114AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6115 ["fe:dc:ba:98:76:54 192.168.1.18"
6116])
6117
6c4f7a8a
NS
6118# Update the static MAC address with dynamically allocated IP and check
6119# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
6120ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
6c4f7a8a
NS
6121
6122AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6123 ["fe:dc:ba:98:76:55 192.168.1.18"
6124])
6125
6126ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
6127AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
c814545b 6128 ["0a:00:00:a8:01:1e 192.168.1.18"
6c4f7a8a
NS
6129])
6130
6131ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
6132AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6133 ["fe:dc:ba:98:76:56 192.168.1.18"
6134])
6135
161ea2c8
NS
6136
6137# Test the exclude_ips from the IPAM list
6138ovn-nbctl --wait=sb set logical_switch sw0 \
6139other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
6140
6141ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
6142"dynamic"
6143# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
6144AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
c814545b 6145 ["0a:00:00:a8:01:1e 192.168.1.20"
161ea2c8
NS
6146])
6147
6148ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
6149"dynamic"
6150# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
6151AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
c814545b 6152 ["0a:00:00:a8:01:1f 192.168.1.22"
161ea2c8
NS
6153])
6154
6155ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
6156"dynamic"
6157# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
6158AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
c814545b 6159 ["0a:00:00:a8:01:34 192.168.1.51"
161ea2c8
NS
6160])
6161
6162# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
6163ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
6164ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
6165"dynamic"
6166AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
c814545b 6167 ["0a:00:00:a8:01:20 192.168.1.19"
161ea2c8
NS
6168])
6169
6170# Set invalid data in exclude_ips list. It should be ignored.
6171ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
6172ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
6173"dynamic"
6174# 192.168.1.21 should be assigned as that's the next free one.
6175AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
c814545b 6176 ["0a:00:00:a8:01:21 192.168.1.21"
161ea2c8
NS
6177])
6178
6179# Clear the dynamic addresses assignment request.
6180ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
6181AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
6182 [[[]]
6183])
6184
7cc0741e
NS
6185# Set IPv6 prefix
6186ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
6187ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
6188"dynamic"
6189
6190# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
6191# - aef0::800:ff:fe00:26 (EUI64)
6192AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
c814545b 6193 ["0a:00:00:a8:01:21 192.168.1.21 aef0::800:ff:fea8:121"
7cc0741e
NS
6194])
6195
6196ovn-nbctl --wait=sb ls-add sw4
451624fe
MM
6197ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
6198-- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
7cc0741e
NS
6199ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
6200"dynamic"
6201
6202AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
c814545b 6203 ["0a:00:00:a8:02:03 192.168.2.2 bef0::800:ff:fea8:203"
7cc0741e
NS
6204])
6205
6206ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
6207"f0:00:00:00:10:12 dynamic"
6208
6209AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
6210 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
6211])
6212
451624fe
MM
6213# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
6214# p40 should not have an IPv4 address since the pool is exhausted
7cc0741e
NS
6215ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
6216"dynamic"
7cc0741e 6217AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
c814545b 6218 ["0a:00:00:00:00:02 bef0::800:ff:fe00:2"
451624fe
MM
6219])
6220
6221# Test dynamic changes on switch ports.
6222#
6223ovn-nbctl --wait=sb ls-add sw5
6224ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
6225"dynamic"
6226# p41 will start with nothing
6227AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
7cc0741e
NS
6228 [[[]]
6229])
6230
451624fe
MM
6231# Set a subnet. Now p41 should have an ipv4 address, too
6232ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
6233AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
c814545b 6234 ["0a:00:00:a8:01:22 192.168.1.2"
451624fe 6235])
7cc0741e 6236
451624fe
MM
6237# Clear the other_config. The IPv4 address should be gone
6238ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
6239AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6240 [[[]]
7cc0741e
NS
6241])
6242
451624fe
MM
6243# Set an IPv6 prefix. Now p41 should have an IPv6 address.
6244ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
7cc0741e 6245AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
c814545b 6246 ["0a:00:00:00:00:03 aef0::800:ff:fe00:3"
451624fe
MM
6247])
6248
6249# Change the MAC address to a static one. The IPv6 address should update.
6250ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
6251AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6252 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
6253])
6254
6255# Change the IPv6 prefix. The IPv6 address should update.
6256ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
6257AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6258 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
6259])
6260
6261# Clear the other_config. The IPv6 address should be gone
6262ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
6263AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6264 [[[]]
6265])
6266
6267# Set the subnet again. Now p41 should get the IPv4 address again.
6268ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
6269AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6270 ["f0:00:00:00:10:2b 192.168.1.2"
6271])
6272
451624fe
MM
6273# Add an excluded IP address that conflicts with p41. p41 should update.
6274ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
863fb61f 6275exclude_ips="192.168.1.2"
451624fe 6276AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
863fb61f 6277 ["f0:00:00:00:10:2b 192.168.1.3"
7cc0741e
NS
6278])
6279
e46b7020
LB
6280# Add static ip address
6281ovn-nbctl --wait=sb lsp-set-addresses p41 "dynamic 192.168.1.100"
6282ovn-nbctl list Logical-Switch-Port p41
6283ovn-nbctl --wait=sb lsp-add sw5 p42 -- lsp-set-addresses p42 \
6284"dynamic 192.168.1.101"
6285AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6286 ["0a:00:00:a8:01:65 192.168.1.100"
6287])
6288AT_CHECK([ovn-nbctl get Logical-Switch-Port p42 dynamic_addresses], [0],
6289 ["0a:00:00:a8:01:66 192.168.1.101"
6290])
6291
282e5357
LB
6292# define a mac address prefix
6293ovn-nbctl ls-add sw6
6294ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22:33:44:55"
6295ovn-nbctl --wait=sb set Logical-Switch sw6 other_config:subnet=192.168.100.0/24
6296for n in $(seq 1 3); do
6297 ovn-nbctl --wait=sb lsp-add sw6 "p5$n" -- lsp-set-addresses "p5$n" dynamic
6298done
6299AT_CHECK([ovn-nbctl get Logical-Switch-Port p51 dynamic_addresses], [0],
c814545b 6300 ["00:11:22:a8:64:03 192.168.100.2"
282e5357
LB
6301])
6302AT_CHECK([ovn-nbctl get Logical-Switch-Port p52 dynamic_addresses], [0],
c814545b 6303 ["00:11:22:a8:64:04 192.168.100.3"
282e5357
LB
6304])
6305AT_CHECK([ovn-nbctl get Logical-Switch-Port p53 dynamic_addresses], [0],
c814545b 6306 ["00:11:22:a8:64:05 192.168.100.4"
282e5357
LB
6307])
6308
04438dbf
LB
6309# verify configuration order does not break IPAM/MACAM
6310ovn-nbctl ls-add sw7
6311for n in $(seq 1 3); do
6312 ovn-nbctl --wait=sb lsp-add sw7 "p7$n" -- lsp-set-addresses "p7$n" dynamic
6313done
6314ovn-nbctl --wait=sb set Logical-Switch sw7 other_config:ipv6_prefix="bef0::"
6315p71_addr=$(ovn-nbctl get Logical-Switch-Port p71 dynamic_addresses)
6316p72_addr=$(ovn-nbctl get Logical-Switch-Port p72 dynamic_addresses)
6317p73_addr=$(ovn-nbctl get Logical-Switch-Port p73 dynamic_addresses)
6318AT_CHECK([test "$p71_addr" != "$p72_addr"], [0], [])
6319AT_CHECK([test "$p71_addr" != "$p73_addr"], [0], [])
6320AT_CHECK([test "$p72_addr" != "$p73_addr"], [0], [])
6321
10b9890f
LB
6322# request to assign mac only
6323#
6324ovn-nbctl ls-add sw8
6325ovn-nbctl --wait=sb set Logical-Switch sw8 other_config:mac_only=true
6326for n in $(seq 1 3); do
6327 ovn-nbctl --wait=sb lsp-add sw8 "p8$n" -- lsp-set-addresses "p8$n" dynamic
6328done
6329AT_CHECK([ovn-nbctl get Logical-Switch-Port p81 dynamic_addresses], [0],
6330 ["00:11:22:00:00:06"
6331])
6332AT_CHECK([ovn-nbctl get Logical-Switch-Port p82 dynamic_addresses], [0],
6333 ["00:11:22:00:00:07"
6334])
6335AT_CHECK([ovn-nbctl get Logical-Switch-Port p83 dynamic_addresses], [0],
6336 ["00:11:22:00:00:08"
6337])
6338
f1301a25
LB
6339# clear mac_prefix and check it is allocated in a random manner
6340ovn-nbctl --wait=hv remove NB_Global . options mac_prefix
6341ovn-nbctl ls-add sw9
6342ovn-nbctl --wait=sb set Logical-Switch sw9 other_config:mac_only=true
6343ovn-nbctl --wait=sb lsp-add sw9 p91 -- lsp-set-addresses p91 dynamic
6344
6345mac_prefix=$(ovn-nbctl --wait=sb get NB_Global . options:mac_prefix | tr -d \")
6346port_addr=$(ovn-nbctl get Logical-Switch-Port p91 dynamic_addresses | tr -d \")
6347AT_CHECK([test "$port_addr" = "${mac_prefix}:00:00:09"], [0], [])
6348
de0c1c32
LB
6349ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22"
6350ovn-nbctl ls-add sw10
6351ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:ipv6_prefix="ae01::"
6352ovn-nbctl --wait=sb lsp-add sw10 p101 -- lsp-set-addresses p101 "dynamic ae01::1"
6353AT_CHECK([ovn-nbctl get Logical-Switch-Port p101 dynamic_addresses], [0],
6354 ["00:11:22:00:00:0a ae01::1"
6355])
6356
6357ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:subnet=192.168.110.0/24
6358ovn-nbctl --wait=sb lsp-add sw10 p102 -- lsp-set-addresses p102 "dynamic 192.168.110.10 ae01::2"
6359AT_CHECK([ovn-nbctl get Logical-Switch-Port p102 dynamic_addresses], [0],
6360 ["00:11:22:a8:6e:0b 192.168.110.10 ae01::2"
6361])
6362
8639f9be
ND
6363as ovn-sb
6364OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6365
6366as ovn-nb
6367OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6368
6369as northd
6370OVS_APP_EXIT_AND_WAIT([ovn-northd])
6371
7861ca30
JP
6372as northd-backup
6373OVS_APP_EXIT_AND_WAIT([ovn-northd])
6374
8639f9be
ND
6375AT_CLEANUP
6376
6377AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
6378AT_SKIP_IF([test $HAVE_PYTHON = no])
6379ovn_start
6380
6381ovn-nbctl lr-add R1
6382
6383# Test for a ping using dynamically allocated addresses.
f1301a25 6384ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
8639f9be
ND
6385ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
6386ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
6387
6388# Connect foo to R1
6389ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6390ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
6391 options:router-port=foo \
6392 -- lsp-set-addresses rp-foo router
8639f9be
ND
6393
6394# Connect alice to R1
6395ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
6396ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
6397 options:router-port=alice addresses=\"00:00:00:01:02:04\"
6398
6399# Create logical port foo1 in foo
fd3b31e9 6400ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 6401-- lsp-set-addresses foo1 "dynamic"
c814545b 6402AT_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
6403
6404# Create logical port alice1 in alice
fd3b31e9 6405ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 6406-- lsp-set-addresses alice1 "dynamic"
c814545b 6407AT_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
6408
6409# Create logical port foo2 in foo
fd3b31e9 6410ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 6411-- lsp-set-addresses foo2 "dynamic"
c814545b 6412AT_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
6413
6414# Create a hypervisor and create OVS ports corresponding to logical ports.
6415net_add n1
6416
6417sim_add hv1
6418as hv1
6419ovs-vsctl add-br br-phys
6420ovn_attach n1 br-phys 192.168.0.1
6421ovs-vsctl -- add-port br-int hv1-vif1 -- \
6422 set interface hv1-vif1 external-ids:iface-id=foo1 \
6423 options:tx_pcap=hv1/vif1-tx.pcap \
6424 options:rxq_pcap=hv1/vif1-rx.pcap \
6425 ofport-request=1
6426
6427ovs-vsctl -- add-port br-int hv1-vif2 -- \
6428 set interface hv1-vif2 external-ids:iface-id=foo2 \
6429 options:tx_pcap=hv1/vif2-tx.pcap \
6430 options:rxq_pcap=hv1/vif2-rx.pcap \
6431 ofport-request=2
6432
6433ovs-vsctl -- add-port br-int hv1-vif3 -- \
6434 set interface hv1-vif3 external-ids:iface-id=alice1 \
6435 options:tx_pcap=hv1/vif3-tx.pcap \
6436 options:rxq_pcap=hv1/vif3-rx.pcap \
6437 ofport-request=3
6438
6439# Allow some time for ovn-northd and ovn-controller to catch up.
6440# XXX This should be more systematic.
6441sleep 1
6442
6443ip_to_hex() {
6444 printf "%02x%02x%02x%02x" "$@"
6445}
8639f9be
ND
6446
6447# Send ip packets between foo1 and foo2
c814545b
LB
6448src_mac="0a0000a80103"
6449dst_mac="0a0000a80104"
8639f9be
ND
6450src_ip=`ip_to_hex 192 168 1 2`
6451dst_ip=`ip_to_hex 192 168 1 3`
6452packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6453as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6454
6455# Send ip packets between foo1 and alice1
c814545b 6456src_mac="0a0000a80103"
8639f9be
ND
6457dst_mac="000000010203"
6458src_ip=`ip_to_hex 192 168 1 2`
6459dst_ip=`ip_to_hex 192 168 2 2`
6460packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6461as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6462
6463echo "---------NB dump-----"
6464ovn-nbctl show
6465echo "---------------------"
6466ovn-nbctl list logical_router
6467echo "---------------------"
6468ovn-nbctl list logical_router_port
6469echo "---------------------"
6470
6471echo "---------SB dump-----"
6472ovn-sbctl list datapath_binding
6473echo "---------------------"
6474ovn-sbctl list port_binding
6475echo "---------------------"
6476
6477echo "------ hv1 dump ----------"
6478as hv1 ovs-ofctl dump-flows br-int
6479
6480# Packet to Expect at foo2
c814545b
LB
6481src_mac="0a0000a80103"
6482dst_mac="0a0000a80104"
8639f9be
ND
6483src_ip=`ip_to_hex 192 168 1 2`
6484dst_ip=`ip_to_hex 192 168 1 3`
6485expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6486
e4543cfe
DDP
6487$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
6488echo $expected > expout
8639f9be
ND
6489AT_CHECK([cat received1.packets], [0], [expout])
6490
6491# Packet to Expect at alice1
6492src_mac="000000010204"
c814545b 6493dst_mac="0a0000a80203"
8639f9be
ND
6494src_ip=`ip_to_hex 192 168 1 2`
6495dst_ip=`ip_to_hex 192 168 2 2`
6496expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6497
e4543cfe
DDP
6498$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
6499echo $expected > expout
8639f9be
ND
6500AT_CHECK([cat received2.packets], [0], [expout])
6501
6502OVN_CLEANUP([hv1])
6503
6504AT_CLEANUP
f5792c3f
NS
6505
6506AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 6507AT_KEYWORDS([vswitchd])
f5792c3f
NS
6508AT_SKIP_IF([test $HAVE_PYTHON = no])
6509ovn_start
6510
6511ovn-nbctl ls-add ls1
6512
6513ovn-nbctl lsp-add ls1 ls1-lp1 \
6514-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
6515
6516ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
6517
6518net_add n1
6519sim_add hv1
6520
6521as hv1
6522ovs-vsctl add-br br-phys
6523ovn_attach n1 br-phys 192.168.0.1
6524ovs-vsctl -- add-port br-int hv1-vif1 -- \
6525 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6526 options:tx_pcap=hv1/vif1-tx.pcap \
6527 options:rxq_pcap=hv1/vif1-rx.pcap \
6528 ofport-request=1
6529
74868f2c 6530OVN_POPULATE_ARP
f5792c3f
NS
6531sleep 2
6532
6533as hv1 ovs-vsctl show
6534
6535echo "---------------------"
6536ovn-sbctl dump-flows
6537echo "---------------------"
6538
6539echo "------ hv1 dump ----------"
6540as hv1 ovs-ofctl dump-flows br-int
6541total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6542
6543echo "Total flows before vswitchd restart = " $total_flows
6544
6545# Code taken from ovs-save utility
6546save_flows () {
6547 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
6548 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
6549 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
6550 echo "EOF" >> restore_flows.sh
6551}
6552
6553restart_vswitchd () {
6554 restore_flows=$1
6555
6556 if test $restore_flows = true; then
6557 save_flows
6558 fi
6559
6560 as hv1
6561 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6562
6563 if test $restore_flows = true; then
6564 as hv1
6565 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
6566 fi
6567
6568 as hv1
6569 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
6570 ovs-ofctl dump-flows br-int
6571
6572 if test $restore_flows = true; then
6573 sh ./restore_flows.sh
6574 echo "Flows after restore"
6575 as hv1
6576 ovs-ofctl dump-flows br-int
6577 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
6578 flow-restore-wait="true"
6579 fi
6580}
6581
6582# Save the flows, restart vswitchd and restore the flows
6583restart_vswitchd true
6584OVS_WAIT_UNTIL([
6585 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6586 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6587 test "${total_flows}" = "${total_flows_after_restart}"
6588])
6589
6590# Restart vswitchd without restoring
6591restart_vswitchd false
6592OVS_WAIT_UNTIL([
6593 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6594 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6595 test "${total_flows}" = "${total_flows_after_restart}"
6596])
6597
6598OVN_CLEANUP([hv1])
6599AT_CLEANUP
47021598
CSV
6600
6601AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
6602AT_SKIP_IF([test $HAVE_PYTHON = no])
6603ovn_start
6604
6605# Topology: Two LSs - ls1 and ls2 are connected via router r0
6606
6607# Create logical switches
6608ovn-nbctl ls-add ls1
6609ovn-nbctl ls-add ls2
6610
6611# Create router
6612ovn-nbctl create Logical_Router name=lr0
6613
6614# Add router ls1p1 port to gateway router
6615ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
6616ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
6617 type=router options:router-port=lrp-ls1lp1 \
6618 addresses='"f0:00:00:00:00:01 192.168.0.1"'
6619
6620# Add router ls2p2 port to gateway router
6621ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
6622ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
6623 type=router options:router-port=lrp-ls2lp1 \
6624 addresses='"f0:00:00:00:00:02 192.168.1.1"'
6625
6626# Set default gateway (nexthop) to 192.168.1.254
6627ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
6628
6629# Create logical port ls1lp2 in ls1
6630ovn-nbctl lsp-add ls1 ls1lp2 \
6631-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
6632
6633# Create logical port ls2lp2 in ls2
6634ovn-nbctl lsp-add ls2 ls2lp2 \
6635-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
6636
6637net_add n1
6638sim_add hv1
6639as hv1
6640ovs-vsctl add-br br-phys
6641ovn_attach n1 br-phys 192.168.0.1
6642ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
6643 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
6644 options:tx_pcap=hv1/ls1lp2-tx.pcap \
6645 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
6646 ofport-request=1
6647ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
6648 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
6649 options:tx_pcap=hv1/ls2lp2-tx.pcap \
6650 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
6651 ofport-request=2
6652
6653# Allow some time for ovn-northd and ovn-controller to catch up.
6654# XXX This should be more systematic.
6655sleep 1
6656
6657echo "---------NB dump-----"
6658ovn-nbctl show
6659echo "---------------------"
6660ovn-nbctl list logical_router
6661echo "---------------------"
6662ovn-nbctl list logical_router_port
6663echo "---------------------"
6664
6665echo "---------SB dump-----"
6666ovn-sbctl list datapath_binding
6667echo "---------------------"
6668ovn-sbctl list port_binding
6669echo "---------------------"
6670ovn-sbctl dump-flows
6671echo "---------------------"
6672ovn-sbctl list chassis
6673ovn-sbctl list encap
6674echo "---------------------"
6675
6676echo "------Flows dump-----"
6677as hv1
6678ovs-ofctl dump-flows
6679echo "---------------------"
6680
6681ip_to_hex() {
6682 printf "%02x%02x%02x%02x" "$@"
6683}
6684
6685src_mac="f00000000003"
6686dst_mac="f00000000001"
6687src_ip=`ip_to_hex 192 168 0 2`
6688dst_ip=`ip_to_hex 8 8 8 8`
6689packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6690
6691# Send IP packet destined to 8.8.8.8 from lsp1lp2
6692as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
6693
6694trim_zeros() {
6695 sed 's/\(00\)\{1,\}$//'
6696}
6697
6698# ARP packet should be received with Target IP Address set to 192.168.1.254 and
6699# not 8.8.8.8
6700
6701$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
6702expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
6703echo $expected > expout
6704AT_CHECK([cat packets], [0], [expout])
6705cat packets
6706
6707OVN_CLEANUP([hv1])
6708
6709AT_CLEANUP
8439c2eb
CSV
6710
6711AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
6712AT_SKIP_IF([test $HAVE_PYTHON = no])
6713ovn_start
6714# Create logical switch
6715ovn-nbctl ls-add ls0
6716# Create gateway router
6717ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6718# Add router port to gateway router
6719ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6720ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 6721 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
6722# Add nat-address option
6723ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
6724
6725net_add n1
6726sim_add hv1
6727as hv1
6728ovs-vsctl \
6729 -- add-br br-phys \
6730 -- add-br br-eth0
6731
6732ovn_attach n1 br-phys 192.168.0.1
6733
6734AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6735AT_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])
6736
6737# Create a localnet port.
6738AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6739AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6740AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6741AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6742
d65586b6
NS
6743# Wait until the patch ports are created in hv1 to connect br-int to br-eth0
6744OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-vsctl show | \
6745grep "Port patch-br-int-to-ln_port" | wc -l`])
8439c2eb
CSV
6746
6747# Wait for packet to be received.
6748OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6749trim_zeros() {
6750 sed 's/\(00\)\{1,\}$//'
6751}
6752$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
d65586b6 6753expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8439c2eb 6754echo $expected > expout
d65586b6
NS
6755expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6756echo $expected >> expout
8439c2eb 6757AT_CHECK([sort packets], [0], [expout])
8439c2eb
CSV
6758
6759OVN_CLEANUP([hv1])
6760
6761AT_CLEANUP
6e31816f 6762
e914fb54
MS
6763AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6764AT_SKIP_IF([test $HAVE_PYTHON = no])
6765ovn_start
6766# Create logical switch
6767ovn-nbctl ls-add ls0
6768# Create gateway router
6769ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6770# Add router port to gateway router
6771ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6772ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 6773 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
6774# Add nat-address option
6775ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6776# Add NAT rules
6777AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6778AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6779# Add load balancers
6780AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6781AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6782AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6783AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6784
6785net_add n1
6786sim_add hv1
6787as hv1
6788ovs-vsctl \
6789 -- add-br br-phys \
6790 -- add-br br-eth0
6791
6792ovn_attach n1 br-phys 192.168.0.1
6793
6794AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6795AT_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])
6796
6797# Create a localnet port.
6798AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6799AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6800AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6801AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6802
d65586b6
NS
6803# Wait until the patch ports are created to connect br-int to br-eth0
6804OVS_WAIT_UNTIL([test 1 = `ovs-vsctl show | \
6805grep "Port patch-br-int-to-ln_port" | wc -l`])
e914fb54 6806
d65586b6
NS
6807ovn-sbctl list port_binding lrp0-rp
6808echo "*****"
6809ovn-nbctl list logical_switch_port lrp0-rp
6810ovn-nbctl list logical_router_port lrp0
6811ovn-nbctl show
e914fb54
MS
6812# Wait for packet to be received.
6813OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6814trim_zeros() {
6815 sed 's/\(00\)\{1,\}$//'
6816}
6817$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6818expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6819echo $expected > expout
6820expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6821echo $expected >> expout
6822expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6823echo $expected >> expout
6824AT_CHECK([sort packets], [0], [expout])
e914fb54
MS
6825
6826OVN_CLEANUP([hv1])
6827
6828AT_CLEANUP
6829
6e31816f 6830AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
6831ovn_start
6832net_add n1
6833sim_add hv1
6834as hv1
6835ovs-vsctl -- add-br br-phys
6836ovn_attach n1 br-phys 192.168.0.1
6837# Create logical switch ls0
6838ovn-nbctl ls-add ls0
6839# Create ports lp0, lp1 in ls0
6840ovn-nbctl lsp-add ls0 lp0
6841ovn-nbctl lsp-add ls0 lp1
6842ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6843ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6844dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6845ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6846ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6847ovn-sbctl find MAC_Binding
093aa761 6848# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
6849ovn-nbctl lsp-del lp0
6850ovn-sbctl find MAC_Binding
093aa761
BP
6851OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6852# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
6853ovn-nbctl ls-del ls0
6854ovn-sbctl find MAC_Binding
093aa761 6855OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
6856
6857OVN_CLEANUP([hv1])
6858
6859AT_CLEANUP
926c34fd
RM
6860
6861AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
6862AT_SKIP_IF([test $HAVE_PYTHON = no])
6863ovn_start
6864
6865# Logical network:
6866# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6867# connected to a router R1.
6868# foo has foo1 to act as a client.
6869# bar has bar1, bar2, bar3 to act as servers.
6870
6871net_add n1
6872
6873sim_add hv1
6874as hv1
6875ovs-vsctl add-br br-phys
6876ovn_attach n1 br-phys 192.168.0.1
6877for i in foo1 bar1 bar2 bar3; do
6878 ovs-vsctl -- add-port br-int $i -- \
6879 set interface $i external-ids:iface-id=$i \
6880 options:tx_pcap=hv1/$i-tx.pcap \
6881 options:rxq_pcap=hv1/$i-rx.pcap
6882done
6883
6884ovn-nbctl create Logical_Router name=R1
6885ovn-nbctl ls-add foo
6886ovn-nbctl ls-add bar
6887
6888# Connect foo to R1
6889ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6890ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6891 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6892
6893# Connect bar to R1
6894ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6895ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6896 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6897
6898# Create logical port foo1 in foo
6899ovn-nbctl lsp-add foo foo1 \
6900-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6901
6902# Create logical port bar1, bar2 and bar3 in bar
6903for i in `seq 1 3`; do
6904 ip=`expr $i + 1`
6905 ovn-nbctl lsp-add bar bar$i \
6906 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6907done
6908
6909OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6910
6911OVN_CLEANUP([hv1])
6912
6913AT_CLEANUP
b511690b
GS
6914
6915AT_SETUP([ovn -- tag allocation])
b511690b
GS
6916ovn_start
6917
6918AT_CHECK([ovn-nbctl ls-add ls0])
6919AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6920AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6921AT_CHECK([ovn-nbctl ls-add ls1])
6922
6923dnl When a tag is provided, no allocation is done
6924AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6925AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6926])
6927dnl The same 'tag' gets created in southbound database.
6928AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6929logical_port="c0"], [0], [3
6930])
6931
6932dnl Allocate tags and see it getting created in both NB and SB
6933AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6934AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6935])
6936AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6937logical_port="c1"], [0], [1
6938])
6939
6940AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6941AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6942])
6943AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6944logical_port="c2"], [0], [2
6945])
6946AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6947AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6948])
6949AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6950logical_port="c3"], [0], [4
6951])
6952
6953dnl A different parent.
6954AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6955AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6956])
6957AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6958logical_port="c4"], [0], [1
6959])
6960
6961AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6962AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6963])
6964AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6965logical_port="c5"], [0], [2
6966])
6967
6968dnl Delete a logical port and create a new one.
6969AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6970AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6971AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6972])
6973AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6974logical_port="c6"], [0], [1
6975])
6976
6977dnl Restart northd to see that the same allocation remains.
6978as northd
6979OVS_APP_EXIT_AND_WAIT([ovn-northd])
6980start_daemon ovn-northd \
6981 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6982 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6983
6984dnl Create a switch to make sure that ovn-northd has run through the main loop.
6985AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6986AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6987])
6988AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6989])
6990AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6991])
6992AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6993])
6994AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6995])
6996AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6997])
6998
6999dnl Create a switch port with a tag that has already been allocated.
7000dnl It should go through fine with a duplicate tag.
7001AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
7002AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
7003])
7004AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
7005logical_port="c7"], [0], [2
7006])
7007AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
7008])
7009
7010AT_CHECK([ovn-nbctl ls-add ls2])
7011dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
7012dnl gets copied to 'tag'
7013AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
7014AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
7015])
7016dnl The same 'tag' gets created in southbound database.
7017AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
7018logical_port="local0"], [0], [25
7019])
7020dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
7021AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
7022AT_CHECK([ovn-nbctl lsp-get-tag local1])
7023dnl change the tag_request.
7024AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
7025AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
7026])
7027
7028AT_CLEANUP
57afd0c0
RR
7029
7030AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
7031ovn_start
7032ovn-nbctl ls-add lsw0
7033net_add n1
7034for i in 1 2; do
7035 sim_add hv$i
7036 as hv$i
7037 ovs-vsctl add-br br-phys
7038 ovn_attach n1 br-phys 192.168.0.$i
7039 ovs-vsctl add-br br-eth0
7040 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
7041done
7042
7043# Create a localnet port.
7044AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
7045AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7046AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7047AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7048
7049
7050# Create 3 vifs.
7051AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
7052AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
7053AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
7054AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
863fb61f 7055AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
57afd0c0
RR
7056AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
7057AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
7058AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
7059AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
7060
7061# Bind the localvif1 to hv1.
7062as hv1
7063AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
7064
7065# On hv1, check that there are no flows outputting bcast to tunnel
7066OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7067
1ea9b847 7068# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 7069as hv2
1ea9b847 7070OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
7071
7072# Now bind vif2 on hv2.
7073AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
7074
7075# At this point, the broadcast flow on vif2 should be deleted.
7076# because, there is now a localnet vif bound (table=32 programming logic)
7077OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7078
7079# Verify that the local net patch port exists on hv2.
7080OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7081
7082# Now bind vif3 on hv2.
7083AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
7084
7085# Verify that the local net patch port still exists on hv2
7086OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7087
7088# Delete localvif2
7089AT_CHECK([ovn-nbctl lsp-del localvif2])
7090
7091# Verify that the local net patch port still exists on hv2,
7092# because, localvif3 is still bound.
7093OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7094
57afd0c0 7095OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
7096
7097AT_CLEANUP
7098
d383eed5
JP
7099
7100AT_SETUP([ovn -- ACL logging])
7101AT_KEYWORDS([ovn])
7102ovn_start
7103
7104net_add n1
7105
7106sim_add hv
7107as hv
7108ovs-vsctl add-br br-phys
7109ovn_attach n1 br-phys 192.168.0.1
7110for i in lp1 lp2; do
7111 ovs-vsctl -- add-port br-int $i -- \
7112 set interface $i external-ids:iface-id=$i \
7113 options:tx_pcap=hv/$i-tx.pcap \
7114 options:rxq_pcap=hv/$i-rx.pcap
7115done
7116
7117lp1_mac="f0:00:00:00:00:01"
7118lp1_ip="192.168.1.2"
7119
7120lp2_mac="f0:00:00:00:00:02"
7121lp2_ip="192.168.1.3"
7122
7123ovn-nbctl ls-add lsw0
7124ovn-nbctl --wait=sb lsp-add lsw0 lp1
7125ovn-nbctl --wait=sb lsp-add lsw0 lp2
7126ovn-nbctl lsp-set-addresses lp1 $lp1_mac
7127ovn-nbctl lsp-set-addresses lp2 $lp2_mac
7128ovn-nbctl --wait=sb sync
7129
7130ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
7131ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
7132
7133ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
7134ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
7135
7136ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
7137ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
7138
7139ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
abf11558 7140ovn-nbctl --wait=hv --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
d383eed5
JP
7141
7142ovn-sbctl dump-flows
7143
7144
7145# Send packet that should be dropped without logging.
7146packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7147 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7148 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
7149as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7150
7151# Send packet that should be dropped with logging.
7152packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7153 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7154 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
7155as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7156
7157# Send packet that should be allowed without logging.
7158packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7159 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7160 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
7161as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7162
7163# Send packet that should be allowed with logging.
7164packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7165 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7166 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
7167as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7168
7169# Send packet that should allow related flows without logging.
7170packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7171 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7172 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
7173as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7174
7175# Send packet that should allow related flows with logging.
7176packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7177 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7178 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
7179as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7180
df48cfc7 7181# Send packet that should be rejected without logging.
d383eed5
JP
7182packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7183 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7184 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
7185as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7186
df48cfc7 7187# Send packet that should be rejected with logging.
d383eed5
JP
7188packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7189 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7190 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
7191as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7192
c1f272f9
NS
7193OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
7194
d383eed5
JP
7195AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
7196name="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
7197name="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
7198name="<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
7199name="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
7200])
7201
7202OVN_CLEANUP([hv])
7203AT_CLEANUP
7204
7205
23749245
JP
7206AT_SETUP([ovn -- ACL rate-limited logging])
7207AT_KEYWORDS([ovn])
7208ovn_start
7209
7210net_add n1
7211
7212sim_add hv
7213as hv
7214ovs-vsctl add-br br-phys
7215ovn_attach n1 br-phys 192.168.0.1
7216for i in lp1 lp2; do
7217 ovs-vsctl -- add-port br-int $i -- \
7218 set interface $i external-ids:iface-id=$i \
7219 options:tx_pcap=hv/$i-tx.pcap \
7220 options:rxq_pcap=hv/$i-rx.pcap
7221done
7222
7223lp1_mac="f0:00:00:00:00:01"
7224lp1_ip="192.168.1.2"
7225
7226lp2_mac="f0:00:00:00:00:02"
7227lp2_ip="192.168.1.3"
7228
7229ovn-nbctl ls-add lsw0
7230ovn-nbctl --wait=sb lsp-add lsw0 lp1
7231ovn-nbctl --wait=sb lsp-add lsw0 lp2
7232ovn-nbctl lsp-set-addresses lp1 $lp1_mac
7233ovn-nbctl lsp-set-addresses lp2 $lp2_mac
7234ovn-nbctl --wait=sb sync
7235
7236
7237# Add an ACL that rate-limits logs at 10 per second.
7238ovn-nbctl meter-add http-rl1 drop 10 pktps
7239ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
7240
7241# Add an ACL that rate-limits logs at 5 per second.
7242ovn-nbctl meter-add http-rl2 drop 5 pktps
7243ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
7244
7245# Add an ACL that doesn't rate-limit logs.
7246ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
abf11558 7247ovn-nbctl --wait=hv sync
23749245
JP
7248
7249# For each ACL, send 100 packets.
7250for i in `seq 1 100`; do
7251 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)'
7252
7253 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)'
7254
7255 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)'
7256done
7257
2600ef02
JP
7258# The rate at which packets are sent is highly system-dependent, so we
7259# can't count on precise drop counts. To work around that, we just
7260# check that exactly 100 "http-acl3" actions were logged and that there
7261# were more "http-acl1" actions than "http-acl2" ones.
7262OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
7263
7264# On particularly slow or overloaded systems, the transmission rate may
7265# be lower than the configured meter rate. To prevent false test
7266# failures, we check the duration count of the meter, and if it's
7267# greater than nine seconds, just skip the test.
7268d_secs=$(as hv ovs-ofctl -O OpenFlow13 meter-stats br-int | grep "meter:1" | sed 's/.* duration:\([[0-9]]\{1,\}\)\.[[0-9]]\+s .*/\1/')
7269
7270echo "Meter duration: $d_secs"
7271AT_SKIP_IF([test $d_secs -gt 9])
7272
23749245
JP
7273# Print some information that may help debugging.
7274as hv ovs-appctl -t ovn-controller meter-table-list
7275as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
7276
23749245
JP
7277n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
7278n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
7279n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
7280
7281AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
7282AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
7283
23749245
JP
7284OVN_CLEANUP([hv])
7285AT_CLEANUP
7286
7287
66d89287 7288AT_SETUP([ovn -- DSCP marking and meter check])
1a03fc7d
BS
7289AT_KEYWORDS([ovn])
7290ovn_start
7291
7292ovn-nbctl ls-add lsw0
7293ovn-nbctl --wait=sb lsp-add lsw0 lp1
7294ovn-nbctl --wait=sb lsp-add lsw0 lp2
e50ed58a 7295ovn-nbctl --wait=sb lsp-add lsw0 lp3
1a03fc7d
BS
7296ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
7297ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
e50ed58a 7298ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
1a03fc7d
BS
7299ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
7300ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
7301ovn-nbctl --wait=sb sync
7302net_add n1
7303sim_add hv
7304as hv
7305ovs-vsctl add-br br-phys
7306ovn_attach n1 br-phys 192.168.0.1
7307ovs-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
7308ovs-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
7309
7310AT_CAPTURE_FILE([trace])
7311ovn_trace () {
7312 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7313}
7314
7315# Extracts nw_tos from the final flow from ofproto/trace output and prints
7316# it on stdout. Prints "none" if no nw_tos was included.
7317get_final_nw_tos() {
7318 if flow=$(grep '^Final flow:' stdout); then :; else
7319 # The output didn't have a final flow.
7320 return 99
7321 fi
7322
7323 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
7324 case $tos in
7325 '') echo none ;;
5a0e4aec 7326 *) echo $tos ;;
1a03fc7d
BS
7327 esac
7328}
7329
7330# check_tos TOS
7331#
7332# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
7333check_tos() {
7334 # First check with ovn-trace for logical flows.
7335 echo "checking for tos $1"
7336 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
7337 echo 'output("lp2");') > expout
7338 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])
7339
7340 # Then re-check with ofproto/trace for a physical packet.
7341 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])
7342 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
7343])
7344}
7345
7346# check at L2
7347AT_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");
7348])
7349AT_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])
7350AT_CHECK([get_final_nw_tos], [0], [none
7351])
7352
7353# check at L3 without dscp marking
7354check_tos 0
7355
7356# Mark DSCP with a valid value
e50ed58a 7357qos_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
7358AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
7359])
1a03fc7d
BS
7360check_tos 48
7361
66d89287
GL
7362# check at hv without qos meter
7363AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7364])
7365
7366# Update the meter rate
7367ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
7368
7369# check at hv with a qos meter table
7370AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
7371])
7372AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
7373])
7374
1a03fc7d
BS
7375# Update the DSCP marking
7376ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
7377check_tos 63
7378
66d89287
GL
7379# Update the meter rate
7380ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
7381
7382# check at hv with a qos meter table
7383AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
7384])
7385AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
7386])
7387
1a03fc7d
BS
7388ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
7389check_tos 63
7390
7391# Disable DSCP marking
5ee33cbd
GL
7392ovn-nbctl --wait=hv qos-del lsw0
7393AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
7394])
1a03fc7d
BS
7395check_tos 0
7396
66d89287
GL
7397# check at hv without qos meter
7398AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7399])
7400
e50ed58a
GL
7401# check meter with chassis not resident
7402ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
7403AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
7404])
7405
7406# check no meter table
7407AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7408])
7409AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
7410])
7411
1a03fc7d 7412OVN_CLEANUP([hv])
57afd0c0 7413AT_CLEANUP
7fff4eb7
LR
7414
7415AT_SETUP([ovn -- read-only sb db:ptcp access])
7416AT_SKIP_IF([test $HAVE_PYTHON = no])
7417
7418: > .$1.db.~lock~
7419ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7420
7421# Add read-only remote to sb ovsdb-server
7422AT_CHECK(
7423 [ovsdb-tool transact ovn-sb.db \
7424 ['["OVN_Southbound",
7425 {"op": "insert",
7426 "table": "SB_Global",
7427 "row": {
7428 "connections": ["set", [["named-uuid", "xyz"]]]}},
7429 {"op": "insert",
7430 "table": "Connection",
7431 "uuid-name": "xyz",
7432 "row": {"target": "ptcp:0:127.0.0.1",
7433 "read_only": true}}]']], [0], [ignore], [ignore])
7434
7435start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
7436
7437PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7438
7439# read-only accesses should succeed
7440AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
7441AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
7442
7443# write access should fail
7444AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
7445[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
7446])
7447
7448OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7449AT_CLEANUP
7450
7451AT_SETUP([ovn -- read-only sb db:pssl access])
7452AT_SKIP_IF([test $HAVE_PYTHON = no])
7453AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7454PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7455AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7456\\]"])
7457
7458: > .$1.db.~lock~
7459ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7460
7461# Add read-only remote to sb ovsdb-server
7462AT_CHECK(
7463 [ovsdb-tool transact ovn-sb.db \
7464 ['["OVN_Southbound",
7465 {"op": "insert",
7466 "table": "SB_Global",
7467 "row": {
7468 "connections": ["set", [["named-uuid", "xyz"]]]}},
7469 {"op": "insert",
7470 "table": "Connection",
7471 "uuid-name": "xyz",
7472 "row": {"target": "pssl:0:127.0.0.1",
7473 "read_only": true}}]']], [0], [ignore], [ignore])
7474
7475start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
7476 --remote=db:OVN_Southbound,SB_Global,connections \
7477 --private-key="$PKIDIR/testpki-privkey2.pem" \
7478 --certificate="$PKIDIR/testpki-cert2.pem" \
7479 --ca-cert="$PKIDIR/testpki-cacert.pem" \
7480 ovn-sb.db
7481
7482PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7483
7484# read-only accesses should succeed
7485AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7486 --private-key=$PKIDIR/testpki-privkey.pem \
7487 --certificate=$PKIDIR/testpki-cert.pem \
7488 --ca-cert=$PKIDIR/testpki-cacert.pem \
7489 list SB_Global], [0], [stdout], [ignore])
7490AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7491 --private-key=$PKIDIR/testpki-privkey.pem \
7492 --certificate=$PKIDIR/testpki-cert.pem \
7493 --ca-cert=$PKIDIR/testpki-cacert.pem \
7494 list Connection], [0], [stdout], [ignore])
7495
7496# write access should fail
7497AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7498 --private-key=$PKIDIR/testpki-privkey.pem \
7499 --certificate=$PKIDIR/testpki-cert.pem \
7500 --ca-cert=$PKIDIR/testpki-cacert.pem \
7501 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
7502[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
7503])
7504
7505OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7506AT_CLEANUP
7507
821302cf
LR
7508AT_SETUP([ovn -- nb connection/ssl commands])
7509AT_SKIP_IF([test $HAVE_PYTHON = no])
7510AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7511PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7512AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7513\\]"])
7514
7515: > .$1.db.~lock~
7516ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
7517
7518# Start nb db server using db connection/ssl entries (unpopulated initially)
7519start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
7520 --remote=db:OVN_Northbound,NB_Global,connections \
7521 --private-key=db:OVN_Northbound,SSL,private_key \
7522 --certificate=db:OVN_Northbound,SSL,certificate \
7523 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
7524 ovn-nb.db
7525
7526# Populate SSL configuration entries in nb db
7527AT_CHECK(
7528 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
7529 $PKIDIR/testpki-cert.pem \
7530 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
7531
7532# Populate a passive SSL connection in nb db
7533AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
7534
7535PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7536
7537# Verify SSL connetivity to nb db server
7538AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7539 --private-key=$PKIDIR/testpki-privkey.pem \
7540 --certificate=$PKIDIR/testpki-cert.pem \
7541 --ca-cert=$PKIDIR/testpki-cacert.pem \
7542 list NB_Global],
7543 [0], [stdout], [ignore])
7544AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7545 --private-key=$PKIDIR/testpki-privkey.pem \
7546 --certificate=$PKIDIR/testpki-cert.pem \
7547 --ca-cert=$PKIDIR/testpki-cacert.pem \
7548 list Connection],
7549 [0], [stdout], [ignore])
7550AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7551 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
7552 --certificate=$PKIDIR/testpki-cert.pem \
7553 --ca-cert=$PKIDIR/testpki-cacert.pem \
7554 get-connection],
7555 [0], [stdout], [ignore])
7556
7557OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7558AT_CLEANUP
7559
7560AT_SETUP([ovn -- sb connection/ssl commands])
7561AT_SKIP_IF([test $HAVE_PYTHON = no])
7562AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7563PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7564AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7565\\]"])
7566
7567: > .$1.db.~lock~
7568ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7569
7570# Start sb db server using db connection/ssl entries (unpopulated initially)
7571start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
7572 --remote=db:OVN_Southbound,SB_Global,connections \
7573 --private-key=db:OVN_Southbound,SSL,private_key \
7574 --certificate=db:OVN_Southbound,SSL,certificate \
7575 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
7576 ovn-sb.db
7577
7578# Populate SSL configuration entries in sb db
7579AT_CHECK(
7580 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
7581 $PKIDIR/testpki-cert.pem \
7582 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
7583
7584# Populate a passive SSL connection in sb db
7585AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
7586
7587PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7588
7589# Verify SSL connetivity to sb db server
7590AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7591 --private-key=$PKIDIR/testpki-privkey.pem \
7592 --certificate=$PKIDIR/testpki-cert.pem \
7593 --ca-cert=$PKIDIR/testpki-cacert.pem \
7594 list SB_Global],
7595 [0], [stdout], [ignore])
7596AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7597 --private-key=$PKIDIR/testpki-privkey.pem \
7598 --certificate=$PKIDIR/testpki-cert.pem \
7599 --ca-cert=$PKIDIR/testpki-cacert.pem \
7600 list Connection],
7601 [0], [stdout], [ignore])
7602AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7603 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
7604 --certificate=$PKIDIR/testpki-cert.pem \
7605 --ca-cert=$PKIDIR/testpki-cacert.pem \
7606 get-connection],
7607 [0], [stdout], [ignore])
7608
7609OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7610AT_CLEANUP
7611
75fd74f8
GS
7612AT_SETUP([ovn -- nested containers])
7613ovn_start
7614
7615# Physical network:
7616# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
7617
7618# Logical network:
7619# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
7620# and "bar" (192.168.2.0/24). They are all connected to router R1.
7621
7622ovn-nbctl lr-add R1
7623ovn-nbctl ls-add mgmt
7624ovn-nbctl ls-add foo
7625ovn-nbctl ls-add bar
7626
7627# Connect mgmt to R1
7628ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
7629ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
7630 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
7631
7632# Connect foo to R1
7633ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
7634ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7635 options:router-port=foo addresses=\"00:00:00:01:02:03\"
7636
7637# Connect bar to R1
7638ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
7639ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7640 options:router-port=bar addresses=\"00:00:00:01:02:04\"
7641
7642# "mgmt" has VM1 and VM2 connected
7643ovn-nbctl lsp-add mgmt vm1 \
7644-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
7645
7646ovn-nbctl lsp-add mgmt vm2 \
7647-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
7648
7649# "foo1" and "foo2" are containers belonging to switch "foo"
7650# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
7651ovn-nbctl lsp-add foo foo1 vm1 1 \
7652-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
7653
7654ovn-nbctl lsp-add foo foo2 vm2 2 \
7655-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7656
7657# "bar1" and "bar2" are containers belonging to switch "bar"
7658# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
7659ovn-nbctl lsp-add bar bar1 vm1 2 \
7660-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
7661
7662ovn-nbctl lsp-add bar bar2 vm2 1 \
7663-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
7664
7665# bar3 is a standalone VM belonging to switch "bar"
7666ovn-nbctl lsp-add bar bar3 \
7667-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
7668
7669# Create two hypervisor and create OVS ports corresponding to logical ports.
7670net_add n1
7671
7672sim_add hv1
7673as hv1
7674ovs-vsctl add-br br-phys
7675ovn_attach n1 br-phys 192.168.0.1
7676ovs-vsctl -- add-port br-int vm1 -- \
7677 set interface vm1 external-ids:iface-id=vm1 \
7678 options:tx_pcap=hv1/vm1-tx.pcap \
7679 options:rxq_pcap=hv1/vm1-rx.pcap \
7680 ofport-request=1
7681
7682ovs-vsctl -- add-port br-int bar3 -- \
7683 set interface bar3 external-ids:iface-id=bar3 \
7684 options:tx_pcap=hv1/bar3-tx.pcap \
7685 options:rxq_pcap=hv1/bar3-rx.pcap \
7686 ofport-request=2
7687
7688sim_add hv2
7689as hv2
7690ovs-vsctl add-br br-phys
7691ovn_attach n1 br-phys 192.168.0.2
7692ovs-vsctl -- add-port br-int vm2 -- \
7693 set interface vm2 external-ids:iface-id=vm2 \
7694 options:tx_pcap=hv2/vm2-tx.pcap \
7695 options:rxq_pcap=hv2/vm2-rx.pcap \
7696 ofport-request=1
7697
7698# Pre-populate the hypervisors' ARP tables so that we don't lose any
7699# packets for ARP resolution (native tunneling doesn't queue packets
7700# for ARP resolution).
74868f2c 7701OVN_POPULATE_ARP
75fd74f8
GS
7702
7703# Allow some time for ovn-northd and ovn-controller to catch up.
7704# XXX This should be more systematic.
7705sleep 1
7706
7707ip_to_hex() {
7708 printf "%02x%02x%02x%02x" "$@"
7709}
7710
7711# Send ip packets between foo1 and foo2 (same switch, different HVs and
7712# different VLAN tags).
7713src_mac="f00000010205"
7714dst_mac="f00000010206"
7715src_ip=`ip_to_hex 192 168 1 2`
7716dst_ip=`ip_to_hex 192 168 1 3`
7717packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7718as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7719
7720# expected packet at foo2
7721packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7722echo $packet > expected
7723OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7724
7725# Send ip packets between foo1 and bar2 (different switch, different HV)
7726src_mac="f00000010205"
7727dst_mac="000000010203"
7728src_ip=`ip_to_hex 192 168 1 2`
7729dst_ip=`ip_to_hex 192 168 2 3`
7730packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7731as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7732
7733# expected packet at bar2
7734src_mac="000000010204"
7735dst_mac="f00000010208"
7736packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7737echo $packet >> expected
7738OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7739
7740# Send ip packets between foo1 and bar1
7741# (different switch, loopback to same vm but different tag)
7742src_mac="f00000010205"
7743dst_mac="000000010203"
7744src_ip=`ip_to_hex 192 168 1 2`
7745dst_ip=`ip_to_hex 192 168 2 2`
7746packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7747as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7748
7749# expected packet at bar1
7750src_mac="000000010204"
7751dst_mac="f00000010207"
7752packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7753echo $packet > expected1
7754OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7755
7756# Send ip packets between bar1 and bar3
7757# (same switch. But one is container and another is a standalone VM)
7758src_mac="f00000010207"
7759dst_mac="f00000010209"
7760src_ip=`ip_to_hex 192 168 2 2`
7761dst_ip=`ip_to_hex 192 168 2 3`
7762packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7763as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7764
7765# expected packet at bar3
7766packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7767echo $packet > expected
7768OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7769
7770# Send ip packets between foo1 and vm1.
7771(different switch, container to the VM hosting it.)
7772src_mac="f00000010205"
7773dst_mac="000000010203"
7774src_ip=`ip_to_hex 192 168 1 2`
7775dst_ip=`ip_to_hex 172 16 1 2`
7776packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7777as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7778
7779# expected packet at vm1
7780src_mac="000000010202"
7781dst_mac="f00000010203"
7782packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7783echo $packet >> expected1
7784OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7785
7786# Send packets from vm1 to bar1.
7787(different switch, A hosting VM to a container inside it)
7788src_mac="f00000010203"
7789dst_mac="000000010202"
7790src_ip=`ip_to_hex 172 16 1 2`
7791dst_ip=`ip_to_hex 192 168 2 2`
7792packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7793as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7794
7795# expected packet at vm1
7796src_mac="000000010204"
7797dst_mac="f00000010207"
7798packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7799echo $packet >> expected1
7800OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7801
22e506d3
NS
7802# Send broadcast packet from foo1. foo1 should not receive the same packet.
7803src_mac="f00000010205"
7804dst_mac="ffffffffffff"
7805src_ip=`ip_to_hex 192 168 1 2`
7806dst_ip=`ip_to_hex 255 255 255 255`
7807packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7808as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7809
7810# expected packet at VM1
7811OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7812
75fd74f8
GS
7813OVN_CLEANUP([hv1],[hv2])
7814
7815AT_CLEANUP
440a9f4b
GS
7816
7817AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7818AT_SKIP_IF([test $HAVE_PYTHON = no])
7819ovn_start
7820
7821# Logical network:
7822# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7823# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7824# (192.168.2.0/24) connected to it.
7825#
7826# R2 and R3 are gateway routers.
7827# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7828# connected to it. Note how both alice and bob have the same subnet behind it.
7829# We are trying to simulate external network via those 2 switches. In real
7830# world the switch ports of these switches will have addresses set as "unknown"
7831# to make them learning switches. Or those switches will be "localnet" ones.
7832
7833# Create three hypervisors and create OVS ports corresponding to logical ports.
7834net_add n1
7835
7836sim_add hv1
7837as hv1
7838ovs-vsctl add-br br-phys
7839ovn_attach n1 br-phys 192.168.0.1
7840ovs-vsctl -- add-port br-int hv1-vif1 -- \
7841 set interface hv1-vif1 external-ids:iface-id=foo1 \
7842 options:tx_pcap=hv1/vif1-tx.pcap \
7843 options:rxq_pcap=hv1/vif1-rx.pcap \
7844 ofport-request=1
7845
7846ovs-vsctl -- add-port br-int hv1-vif2 -- \
7847 set interface hv1-vif2 external-ids:iface-id=bar1 \
7848 options:tx_pcap=hv1/vif2-tx.pcap \
7849 options:rxq_pcap=hv1/vif2-rx.pcap \
7850 ofport-request=2
7851
7852sim_add hv2
7853as hv2
7854ovs-vsctl add-br br-phys
7855ovn_attach n1 br-phys 192.168.0.2
7856ovs-vsctl -- add-port br-int hv2-vif1 -- \
7857 set interface hv2-vif1 external-ids:iface-id=alice1 \
7858 options:tx_pcap=hv2/vif1-tx.pcap \
7859 options:rxq_pcap=hv2/vif1-rx.pcap \
7860 ofport-request=1
7861
7862sim_add hv3
7863as hv3
7864ovs-vsctl add-br br-phys
7865ovn_attach n1 br-phys 192.168.0.3
7866ovs-vsctl -- add-port br-int hv3-vif1 -- \
7867 set interface hv3-vif1 external-ids:iface-id=bob1 \
7868 options:tx_pcap=hv3/vif1-tx.pcap \
7869 options:rxq_pcap=hv3/vif1-rx.pcap \
7870 ofport-request=1
7871
7872
7873ovn-nbctl create Logical_Router name=R1
7874ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7875ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7876
7877ovn-nbctl ls-add foo
7878ovn-nbctl ls-add bar
7879ovn-nbctl ls-add alice
7880ovn-nbctl ls-add bob
7881ovn-nbctl ls-add join
7882
7883# Connect foo to R1
7884ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7885ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7886 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7887
7888# Connect bar to R1
7889ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7890ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7891 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7892
7893# Connect alice to R2
7894ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7895ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7896 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7897
7898# Connect bob to R3
7899ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7900ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7901 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7902
7903# Connect R1 to join
7904ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7905ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7906 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7907
7908# Connect R2 to join
7909ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7910ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7911 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7912
7913# Connect R3 to join
7914ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7915ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7916 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7917
7918# Install static routes with source ip address as the policy for routing.
7919# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7920ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7921ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7922
7923# Install static routes with destination ip address as the policy for routing.
7924ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7925
7926ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7927
7928# Create logical port foo1 in foo
7929ovn-nbctl lsp-add foo foo1 \
7930-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7931
7932# Create logical port bar1 in bar
7933ovn-nbctl lsp-add bar bar1 \
7934-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7935
7936# Create logical port alice1 in alice
7937ovn-nbctl lsp-add alice alice1 \
7938-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7939
7940# Create logical port bob1 in bob
7941ovn-nbctl lsp-add bob bob1 \
7942-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7943
7944# Pre-populate the hypervisors' ARP tables so that we don't lose any
7945# packets for ARP resolution (native tunneling doesn't queue packets
7946# for ARP resolution).
74868f2c 7947OVN_POPULATE_ARP
440a9f4b
GS
7948
7949# Allow some time for ovn-northd and ovn-controller to catch up.
7950# XXX This should be more systematic.
7951sleep 1
7952
7953ip_to_hex() {
7954 printf "%02x%02x%02x%02x" "$@"
7955}
7956trim_zeros() {
7957 sed 's/\(00\)\{1,\}$//'
7958}
7959
7960# Send ip packets between foo1 and bar1
7961# (East-west traffic should flow normally)
7962src_mac="f00000010203"
7963dst_mac="000001010203"
7964src_ip=`ip_to_hex 192 168 1 2`
7965dst_ip=`ip_to_hex 192 168 2 2`
7966packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7967as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7968
7969# Send ip packets between foo1 and alice1
7970src_mac="f00000010203"
7971dst_mac="000001010203"
7972src_ip=`ip_to_hex 192 168 1 2`
7973dst_ip=`ip_to_hex 172 16 1 3`
7974packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7975as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 7976as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
7977
7978# Send ip packets between bar1 and bob1
7979src_mac="f00000010204"
7980dst_mac="000001010204"
7981src_ip=`ip_to_hex 192 168 2 2`
7982dst_ip=`ip_to_hex 172 16 1 4`
7983packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7984as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7985#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7986
7987# Packet to expect at bar1
7988src_mac="000001010204"
7989dst_mac="f00000010204"
7990src_ip=`ip_to_hex 192 168 1 2`
7991dst_ip=`ip_to_hex 192 168 2 2`
7992expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7993echo $expected > expected
7994OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7995
7996# Packet to Expect at alice1
7997src_mac="000002010203"
7998dst_mac="f00000010205"
7999src_ip=`ip_to_hex 192 168 1 2`
8000dst_ip=`ip_to_hex 172 16 1 3`
8001expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8002echo $expected > expected
8003OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8004
8005# Packet to Expect at bob1
8006src_mac="000003010203"
8007dst_mac="f00000010206"
8008src_ip=`ip_to_hex 192 168 2 2`
8009dst_ip=`ip_to_hex 172 16 1 4`
8010expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8011echo $expected > expected
8012OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
8013
c4d0e4f2 8014OVN_CLEANUP([hv1],[hv2],[hv3])
440a9f4b
GS
8015
8016AT_CLEANUP
41a15b71 8017
302eda27
NS
8018AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
8019AT_SKIP_IF([test $HAVE_PYTHON = no])
8020ovn_start
8021
8022ovn-nbctl ls-add ls1
8023
8024ovn-nbctl lsp-add ls1 ls1-lp1 \
8025-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
8026
8027ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
8028
8029ovn-nbctl lsp-add ls1 ls1-lp2 \
8030-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
8031
8032ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
8033
8034DNS1=`ovn-nbctl create DNS records={}`
8035DNS2=`ovn-nbctl create DNS records={}`
8036
8037ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
8038ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
8039ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
8040
8041ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
8042
8043net_add n1
8044sim_add hv1
8045
8046as hv1
8047ovs-vsctl add-br br-phys
8048ovn_attach n1 br-phys 192.168.0.1
8049ovs-vsctl -- add-port br-int hv1-vif1 -- \
8050 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
8051 options:tx_pcap=hv1/vif1-tx.pcap \
8052 options:rxq_pcap=hv1/vif1-rx.pcap \
8053 ofport-request=1
8054
8055ovs-vsctl -- add-port br-int hv1-vif2 -- \
8056 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
8057 options:tx_pcap=hv1/vif2-tx.pcap \
8058 options:rxq_pcap=hv1/vif2-rx.pcap \
8059 ofport-request=2
8060
74868f2c 8061OVN_POPULATE_ARP
302eda27
NS
8062sleep 2
8063as hv1 ovs-vsctl show
8064
8065echo "*************************"
8066ovn-sbctl list DNS
8067echo "*************************"
8068
8069ip_to_hex() {
8070 printf "%02x%02x%02x%02x" "$@"
8071}
8072
8073reset_pcap_file() {
8074 local iface=$1
8075 local pcap_file=$2
8076 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8077options:rxq_pcap=dummy-rx.pcap
8078 rm -f ${pcap_file}*.pcap
8079 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8080options:rxq_pcap=${pcap_file}-rx.pcap
8081}
8082
8083# set_dns_params host_name
8084# Sets the dns_req_data and dns_resp_data
8085set_dns_params() {
8086 local hname=$1
8087 local ttl=00000e10
8088 an_count=0001
8089 type=0001
8090 case $hname in
8091 vm1)
8092 # vm1.ovn.org
8093 query_name=03766d31036f766e036f726700
8094 # IPv4 address - 10.0.0.4
8095 expected_dns_answer=${query_name}00010001${ttl}00040a000004
8096 ;;
8097 vm2)
8098 # vm2.ovn.org
8099 query_name=03766d32036f766e036f726700
8100 # IPv4 address - 10.0.0.6
8101 expected_dns_answer=${query_name}00010001${ttl}00040a000006
8102 # IPv4 address - 20.0.0.4
8103 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
8104 an_count=0002
8105 ;;
8106 vm3)
8107 # vm3.ovn.org
8108 query_name=03766d33036f766e036f726700
8109 # IPv4 address - 40.0.0.4
8110 expected_dns_answer=${query_name}00010001${ttl}000428000004
8111 ;;
8112 vm1_ipv6_only)
8113 # vm1.ovn.org
8114 query_name=03766d31036f766e036f726700
8115 # IPv6 address - aef0::4
8116 type=001c
8117 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
8118 ;;
8119 vm1_ipv4_v6)
8120 # vm1.ovn.org
8121 query_name=03766d31036f766e036f726700
8122 type=00ff
8123 an_count=0002
8124 # IPv4 address - 10.0.0.4
8125 # IPv6 address - aef0::4
8126 expected_dns_answer=${query_name}00010001${ttl}00040a000004
8127 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
8128 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
8129 ;;
8130 vm1_invalid_type)
8131 # vm1.ovn.org
8132 query_name=03766d31036f766e036f726700
8133 # IPv6 address - aef0::4
8134 type=0002
8135 ;;
8136 vm1_incomplete)
8137 # set type to none
8138 type=''
8139 esac
8140 # TTL - 3600
8141 local dns_req_header=010201200001000000000000
8142 local dns_resp_header=010281200001${an_count}00000000
8143 dns_req_data=${dns_req_header}${query_name}${type}0001
8144 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
8145}
8146
8147# This shell function sends a DNS request packet
8148# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
8149test_dns() {
8150 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
8151 local dns_query_data=$7
8152 shift; shift; shift; shift; shift; shift; shift;
8153 # Packet size => IPv4 header (20) + UDP header (8) +
8154 # DNS data (header + query)
8155 ip_len=`expr 28 + ${#dns_query_data} / 2`
8156 udp_len=`expr $ip_len - 20`
8157 ip_len=$(printf "%x" $ip_len)
8158 udp_len=$(printf "%x" $udp_len)
8159 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
8160 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
8161 # dns data
8162 request=${request}${dns_query_data}
8163
8164 if test $dns_reply != 0; then
8165 local dns_reply=$1
8166 ip_len=`expr 28 + ${#dns_reply} / 2`
8167 udp_len=`expr $ip_len - 20`
8168 ip_len=$(printf "%x" $ip_len)
8169 udp_len=$(printf "%x" $udp_len)
8170 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
8171 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
8172 echo $reply >> $inport.expected
8173 else
8174 for outport; do
8175 echo $request >> $outport.expected
8176 done
8177 fi
8178 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
8179}
8180
f8e79d82
MM
8181test_dns6() {
8182 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
8183 local dns_query_data=$7
8184 shift; shift; shift; shift; shift; shift; shift;
8185 # Packet size => UDP header (8) +
8186 # DNS data (header + query)
8187 ip_len=`expr 8 + ${#dns_query_data} / 2`
8188 udp_len=$ip_len
8189 ip_len=$(printf "%x" $ip_len)
8190 udp_len=$(printf "%x" $udp_len)
8191 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
8192 request=${request}9234003500${udp_len}0000
8193 #dns data
8194 request=${request}${dns_query_data}
8195
8196 if test $dns_reply != 0; then
8197 local dns_reply=$1
8198 ip_len=`expr 8 + ${#dns_reply} / 2`
8199 udp_len=$ip_len
8200 ip_len=$(printf "%x" $ip_len)
8201 udp_len=$(printf "%x" $udp_len)
8202 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
8203 reply=${reply}0035923400${udp_len}0000${dns_reply}
8204 echo $reply >> $inport.expected
8205 else
8206 for outport; do
8207 echo $request >> $outport.expected
8208 done
8209 fi
8210 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
8211}
8212
302eda27
NS
8213AT_CAPTURE_FILE([ofctl_monitor0.log])
8214as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8215--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8216
8217set_dns_params vm2
8218src_ip=`ip_to_hex 10 0 0 4`
8219dst_ip=`ip_to_hex 10 0 0 1`
8220dns_reply=1
8221test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8222
8223# NXT_RESUMEs should be 1.
8224OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8225
8226$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8227cat 1.expected | cut -c -48 > expout
8228AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
8229# Skipping the IPv4 checksum.
8230cat 1.expected | cut -c 53- > expout
8231AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
8232
8233reset_pcap_file hv1-vif1 hv1/vif1
8234reset_pcap_file hv1-vif2 hv1/vif2
8235rm -f 1.expected
8236rm -f 2.expected
8237
8238set_dns_params vm1
8239src_ip=`ip_to_hex 10 0 0 6`
8240dst_ip=`ip_to_hex 10 0 0 1`
8241dns_reply=1
8242test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8243
8244# NXT_RESUMEs should be 2.
8245OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8246
8247$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8248cat 2.expected | cut -c -48 > expout
8249AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8250# Skipping the IPv4 checksum.
8251cat 2.expected | cut -c 53- > expout
8252AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8253
8254reset_pcap_file hv1-vif1 hv1/vif1
8255reset_pcap_file hv1-vif2 hv1/vif2
8256rm -f 1.expected
8257rm -f 2.expected
8258
8259# Clear the query name options for ls1-lp2
8260ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
8261
8262set_dns_params vm2
8263src_ip=`ip_to_hex 10 0 0 4`
8264dst_ip=`ip_to_hex 10 0 0 1`
8265dns_reply=0
8266test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
8267
8268# NXT_RESUMEs should be 3.
8269OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8270
8271$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8272AT_CHECK([cat 1.packets], [0], [])
8273
8274reset_pcap_file hv1-vif1 hv1/vif1
8275reset_pcap_file hv1-vif2 hv1/vif2
8276rm -f 1.expected
8277rm -f 2.expected
8278
8279# Clear the query name for ls1-lp1
8280# Since ls1 has no query names configued,
8281# ovn-northd should not add the DNS flows.
8282ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
8283
8284set_dns_params vm1
8285src_ip=`ip_to_hex 10 0 0 6`
8286dst_ip=`ip_to_hex 10 0 0 1`
8287dns_reply=0
8288test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8289
8290# NXT_RESUMEs should be 3 only.
8291OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8292
8293$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8294AT_CHECK([cat 2.packets], [0], [])
8295
8296reset_pcap_file hv1-vif1 hv1/vif1
8297reset_pcap_file hv1-vif2 hv1/vif2
8298rm -f 1.expected
8299rm -f 2.expected
8300
8301# Test IPv6 (AAAA records) using IPv4 packet.
8302# Add back the DNS options for ls1-lp1.
4f4ac4bb 8303ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
302eda27
NS
8304
8305set_dns_params vm1_ipv6_only
8306src_ip=`ip_to_hex 10 0 0 6`
8307dst_ip=`ip_to_hex 10 0 0 1`
8308dns_reply=1
8309test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8310
8311# NXT_RESUMEs should be 4.
8312OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8313
8314$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8315cat 2.expected | cut -c -48 > expout
8316AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8317# Skipping the IPv4 checksum.
8318cat 2.expected | cut -c 53- > expout
8319AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8320
8321reset_pcap_file hv1-vif1 hv1/vif1
8322reset_pcap_file hv1-vif2 hv1/vif2
8323rm -f 1.expected
8324rm -f 2.expected
8325
8326# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
8327set_dns_params vm1_ipv4_v6
8328src_ip=`ip_to_hex 10 0 0 6`
8329dst_ip=`ip_to_hex 10 0 0 1`
8330dns_reply=1
8331test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8332
8333# NXT_RESUMEs should be 5.
8334OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8335
8336$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8337cat 2.expected | cut -c -48 > expout
8338AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8339# Skipping the IPv4 checksum.
8340cat 2.expected | cut -c 53- > expout
8341AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8342
8343reset_pcap_file hv1-vif1 hv1/vif1
8344reset_pcap_file hv1-vif2 hv1/vif2
8345rm -f 1.expected
8346rm -f 2.expected
8347
8348# Invalid type.
8349set_dns_params vm1_invalid_type
8350src_ip=`ip_to_hex 10 0 0 6`
8351dst_ip=`ip_to_hex 10 0 0 1`
8352dns_reply=0
8353test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8354
8355# NXT_RESUMEs should be 6.
8356OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8357
8358$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8359AT_CHECK([cat 2.packets], [0], [])
8360
8361reset_pcap_file hv1-vif1 hv1/vif1
8362reset_pcap_file hv1-vif2 hv1/vif2
8363rm -f 1.expected
8364rm -f 2.expected
8365
8366# Incomplete DNS packet.
8367set_dns_params vm1_incomplete
8368src_ip=`ip_to_hex 10 0 0 6`
8369dst_ip=`ip_to_hex 10 0 0 1`
8370dns_reply=0
8371test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8372
8373# NXT_RESUMEs should be 7.
8374OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8375
8376$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8377AT_CHECK([cat 2.packets], [0], [])
8378
8379reset_pcap_file hv1-vif1 hv1/vif1
8380reset_pcap_file hv1-vif2 hv1/vif2
8381rm -f 1.expected
8382rm -f 2.expected
8383
8384# Add one more DNS record to the ls1.
8385ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
8386
8387set_dns_params vm3
8388src_ip=`ip_to_hex 10 0 0 4`
8389dst_ip=`ip_to_hex 10 0 0 1`
8390dns_reply=1
8391test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8392
8393# NXT_RESUMEs should be 8.
8394OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8395
8396$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8397cat 1.expected | cut -c -48 > expout
8398AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
8399# Skipping the IPv4 checksum.
8400cat 1.expected | cut -c 53- > expout
8401AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
8402
8403reset_pcap_file hv1-vif1 hv1/vif1
8404reset_pcap_file hv1-vif2 hv1/vif2
8405rm -f 1.expected
8406rm -f 2.expected
8407
f8e79d82
MM
8408# Try DNS query over IPv6
8409set_dns_params vm1
8410src_ip=aef00000000000000000000000000004
8411dst_ip=aef00000000000000000000000000001
8412dns_reply=1
8413test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8414
8415# NXT_RESUMEs should be 9.
8416OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8417
8418$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
b75f2651
MM
8419# Skipping the UDP checksum.
8420cat 1.expected | cut -c 1-120,125- > expout
8421AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
f8e79d82
MM
8422
8423reset_pcap_file hv1-vif1 hv1/vif1
8424reset_pcap_file hv1-vif2 hv1/vif2
8425rm -f 1.expected
8426rm -f 2.expected
8427
c4d0e4f2 8428OVN_CLEANUP([hv1])
302eda27 8429
302eda27
NS
8430AT_CLEANUP
8431
75f9e007 8432AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 8433AT_SKIP_IF([test $HAVE_PYTHON = no])
8434ovn_start
8435
8436net_add n1
8437
8438sim_add hv1
8439as hv1
8440ovs-vsctl add-br br-phys
8441ovn_attach n1 br-phys 192.168.0.1
8442ovs-vsctl -- add-port br-int hv1-vif1 -- \
8443 set interface hv1-vif1 external-ids:iface-id=foo1 \
8444 options:tx_pcap=hv1/vif1-tx.pcap \
8445 options:rxq_pcap=hv1/vif1-rx.pcap \
8446 ofport-request=1
8447
8448sim_add gw1
8449as gw1
8450ovs-vsctl add-br br-phys
8451ovn_attach n1 br-phys 192.168.0.2
8452
8453sim_add gw2
8454as gw2
8455ovs-vsctl add-br br-phys
8456ovn_attach n1 br-phys 192.168.0.4
8457
8458sim_add ext1
8459as ext1
8460ovs-vsctl add-br br-phys
8461ovn_attach n1 br-phys 192.168.0.3
8462ovs-vsctl -- add-port br-int ext1-vif1 -- \
8463 set interface ext1-vif1 external-ids:iface-id=outside1 \
8464 options:tx_pcap=ext1/vif1-tx.pcap \
8465 options:rxq_pcap=ext1/vif1-rx.pcap \
8466 ofport-request=1
8467
8468# Pre-populate the hypervisors' ARP tables so that we don't lose any
8469# packets for ARP resolution (native tunneling doesn't queue packets
8470# for ARP resolution).
74868f2c 8471OVN_POPULATE_ARP
1da17a0b 8472
8473ovn-nbctl create Logical_Router name=R1
8474
8475ovn-nbctl ls-add foo
8476ovn-nbctl ls-add alice
8477ovn-nbctl ls-add outside
8478
8479# Connect foo to R1
8480ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8481ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8482 type=router options:router-port=foo \
8483 -- lsp-set-addresses rp-foo router
8484
8485# Connect alice to R1 as distributed router gateway port on gw1
8486ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8487
8488ovn-nbctl \
8489 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8490 chassis_name=gw1 \
8491 priority=20 -- \
8492 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8493 chassis_name=gw2 \
8494 priority=10 -- \
8495 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8496
8497ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8498 type=router options:router-port=alice \
8499 -- lsp-set-addresses rp-alice router
8500
8501# Create logical port foo1 in foo
8502ovn-nbctl lsp-add foo foo1 \
8503-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8504
8505# Create logical port outside1 in outside
8506ovn-nbctl lsp-add outside outside1 \
8507-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8508
8509# Create localnet port in alice
8510ovn-nbctl lsp-add alice ln-alice
8511ovn-nbctl lsp-set-addresses ln-alice unknown
8512ovn-nbctl lsp-set-type ln-alice localnet
8513ovn-nbctl lsp-set-options ln-alice network_name=phys
8514
8515# Create localnet port in outside
8516ovn-nbctl lsp-add outside ln-outside
8517ovn-nbctl lsp-set-addresses ln-outside unknown
8518ovn-nbctl lsp-set-type ln-outside localnet
8519ovn-nbctl lsp-set-options ln-outside network_name=phys
8520
8521# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8522# mapping to the external network, is the one generating packets
8523as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8524as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8525as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8526
8527AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8528
8529# Allow some time for ovn-northd and ovn-controller to catch up.
8530# XXX This should be more systematic.
8531sleep 2
8532
8533ip_to_hex() {
8534 printf "%02x%02x%02x%02x" "$@"
8535}
8536
8537reset_pcap_file() {
8538 local iface=$1
8539 local pcap_file=$2
8540 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8541options:rxq_pcap=dummy-rx.pcap
8542 rm -f ${pcap_file}*.pcap
8543 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8544options:rxq_pcap=${pcap_file}-rx.pcap
8545}
8546
8547test_ip_packet()
8548{
8549 local active_gw=$1
8550 local backup_gw=$2
8e37d8fb 8551 local backup_vswitchd_dead=$3
1da17a0b 8552
8553 # Send ip packet between foo1 and outside1
8554 src_mac="f00000010203" # foo1 mac
8555 dst_mac="000001010203" # rp-foo mac (internal router leg)
8556 src_ip=`ip_to_hex 192 168 1 2`
8557 dst_ip=`ip_to_hex 172 16 1 3`
8558 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8559
8560 # ARP request packet to expect at outside1
8561 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8562
8563 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8564
8565 # Send ARP reply from outside1 back to the router
8566 # XXX: note, we could avoid this if we plug this port into a netns
8567 # and setup the IP address into the port, so the kernel would simply reply
8568 src_mac="000002010203"
8569 reply_mac="f00000010204"
8570 dst_ip=`ip_to_hex 172 16 1 3`
8571 src_ip=`ip_to_hex 172 16 1 1`
8572 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8573
8574 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8575
86c9d79a
NS
8576 OVS_WAIT_UNTIL([
8577 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8578grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8579 ])
8580
1da17a0b 8581 # Packet to Expect at ext1 chassis, outside1 port
8582 src_mac="000002010203"
8583 dst_mac="f00000010204"
8584 src_ip=`ip_to_hex 192 168 1 2`
8585 dst_ip=`ip_to_hex 172 16 1 3`
8586 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8587 echo $expected > ext1-vif1.expected
d65586b6
NS
8588 exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
8589 echo $exp_gw_ip_garp >> ext1-vif1.expected
1da17a0b 8590 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8e37d8fb
NS
8591
8592 if test $backup_vswitchd_dead != 1; then
8593 # Reset the file only if vswitchd in backup gw is alive
8594 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8595 fi
1da17a0b 8596 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8597
8598 # Resend packet from foo1 to outside1
8599 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8600
8601 sleep 1
8602
8603 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8604 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
d65586b6 8605 cat packets | grep $expected > exp
fbe67a7d
NS
8606 # Its possible that $active_gw/br-phys_n1-tx.pcap may have received multiple
8607 # garp packets. So consider only the first packet.
8608 cat packets | grep $exp_gw_ip_garp | head -1 >> exp
d65586b6
NS
8609 AT_CHECK([cat exp], [0], [expout])
8610 rm -f expout
8e37d8fb
NS
8611 if test $backup_vswitchd_dead != 1; then
8612 # Check for backup gw only if vswitchd is alive
8613 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8614 AT_CHECK([grep $expected packets | sort], [0], [])
8615 fi
1da17a0b 8616}
8617
8e37d8fb 8618test_ip_packet gw1 gw2 0
1da17a0b 8619
75f9e007
GZ
8620ovn-nbctl --timeout=3 --wait=hv \
8621 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8622 chassis_name=gw1 \
8623 priority=10 -- \
8624 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8625 chassis_name=gw2 \
8626 priority=20 -- \
8627 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8628
8e37d8fb
NS
8629test_ip_packet gw2 gw1 0
8630
8631# Get the claim count of both gw1 and gw2.
8632gw1_claim_ct=`grep "cr-alice: Claiming" gw1/ovn-controller.log | wc -l`
8633gw2_claim_ct=`grep "cr-alice: Claiming" gw2/ovn-controller.log | wc -l`
8634
8635# Stop ovs-vswitchd in gw2. gw1 should claim the gateway port.
8636as gw2
8637OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
8638
8639# gw1 should claim the cr-alice and the claim count of gw1 should be
8640# incremented by 1.
8641gw1_claim_ct=$((gw1_claim_ct+1))
8642
8643OVS_WAIT_UNTIL([test $gw1_claim_ct = `cat gw1/ovn-controller.log \
8644| grep -c "cr-alice: Claiming"`])
8645
8646AT_CHECK([test $gw2_claim_ct = `cat gw2/ovn-controller.log | \
8647grep -c "cr-alice: Claiming"`])
8648
8649test_ip_packet gw1 gw2 1
8650
8651as gw2
8652OVS_APP_EXIT_AND_WAIT([ovn-controller])
8653OVS_APP_EXIT_AND_WAIT([ovsdb-server])
8654
8655OVN_CLEANUP([hv1],[gw1],[ext1])
75f9e007 8656
75f9e007
GZ
8657AT_CLEANUP
8658
8659AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
8660AT_SKIP_IF([test $HAVE_PYTHON = no])
8661ovn_start
8662
8663net_add n1
8664
8665sim_add hv1
8666as hv1
8667ovs-vsctl add-br br-phys
8668ovn_attach n1 br-phys 192.168.0.1
8669ovs-vsctl -- add-port br-int hv1-vif1 -- \
8670 set interface hv1-vif1 external-ids:iface-id=foo1 \
8671 options:tx_pcap=hv1/vif1-tx.pcap \
8672 options:rxq_pcap=hv1/vif1-rx.pcap \
8673 ofport-request=1
8674
8675sim_add gw1
8676as gw1
8677ovs-vsctl add-br br-phys
8678ovn_attach n1 br-phys 192.168.0.2
8679
8680sim_add gw2
8681as gw2
8682ovs-vsctl add-br br-phys
8683ovn_attach n1 br-phys 192.168.0.4
8684
8685sim_add ext1
8686as ext1
8687ovs-vsctl add-br br-phys
8688ovn_attach n1 br-phys 192.168.0.3
8689ovs-vsctl -- add-port br-int ext1-vif1 -- \
8690 set interface ext1-vif1 external-ids:iface-id=outside1 \
8691 options:tx_pcap=ext1/vif1-tx.pcap \
8692 options:rxq_pcap=ext1/vif1-rx.pcap \
8693 ofport-request=1
8694
8695# Pre-populate the hypervisors' ARP tables so that we don't lose any
8696# packets for ARP resolution (native tunneling doesn't queue packets
8697# for ARP resolution).
74868f2c 8698OVN_POPULATE_ARP
75f9e007
GZ
8699
8700ovn-nbctl create Logical_Router name=R0
8701ovn-nbctl create Logical_Router name=R1
8702
8703ovn-nbctl ls-add foo
8704ovn-nbctl ls-add join
8705ovn-nbctl ls-add alice
8706ovn-nbctl ls-add outside
8707
8708#Connect foo to R0
8709ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
8710ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
8711 type=router options:router-port=R0-foo \
8712 -- lsp-set-addresses foo-R0 router
8713
8714#Connect R0 to join
8715ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
8716ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
8717 type=router options:router-port=R0-join \
8718 -- lsp-set-addresses join-R0 router
8719
8720#Connect join to R1
8721ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
8722ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
8723 type=router options:router-port=R1-join \
8724 -- lsp-set-addresses join-R1 router
8725
8726#add route rules
8727ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
8728ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
8729
8730# Connect alice to R1 as distributed router gateway port on gw1
8731ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8732
8733ovn-nbctl \
8734 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8735 chassis_name=gw1 \
8736 priority=20 -- \
8737 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8738 chassis_name=gw2 \
8739 priority=10 -- \
8740 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8741
8742ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8743 type=router options:router-port=alice \
8744 -- lsp-set-addresses rp-alice router
8745
8746# Create logical port foo1 in foo
8747ovn-nbctl lsp-add foo foo1 \
8748-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8749
8750# Create logical port outside1 in outside
8751ovn-nbctl lsp-add outside outside1 \
8752-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8753
8754# Create localnet port in alice
8755ovn-nbctl lsp-add alice ln-alice
8756ovn-nbctl lsp-set-addresses ln-alice unknown
8757ovn-nbctl lsp-set-type ln-alice localnet
8758ovn-nbctl lsp-set-options ln-alice network_name=phys
8759
8760# Create localnet port in outside
8761ovn-nbctl lsp-add outside ln-outside
8762ovn-nbctl lsp-set-addresses ln-outside unknown
8763ovn-nbctl lsp-set-type ln-outside localnet
8764ovn-nbctl lsp-set-options ln-outside network_name=phys
8765
8766# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8767# mapping to the external network, is the one generating packets
8768as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8769as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8770as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8771
8772AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8773
1be1e0e5
NS
8774# hv1 should be in 'ref_chassis' of the ha_chasssi_group as logical
8775# switch 'foo' can reach the router 'R1' (which has gw router port)
8776# via foo1 -> foo -> R0 -> join -> R1
8777hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
8778OVS_WAIT_UNTIL(
8779 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
8780 # Trim the spaces.
8781 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
8782 test "$hv1_ch_uuid" = "$ref_ch_list"])
8783
75f9e007
GZ
8784# Allow some time for ovn-northd and ovn-controller to catch up.
8785# XXX This should be more systematic.
8786sleep 2
8787
8788ip_to_hex() {
8789 printf "%02x%02x%02x%02x" "$@"
8790}
8791
8792reset_pcap_file() {
8793 local iface=$1
8794 local pcap_file=$2
8795 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8796options:rxq_pcap=dummy-rx.pcap
8797 rm -f ${pcap_file}*.pcap
8798 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8799options:rxq_pcap=${pcap_file}-rx.pcap
8800}
8801
8802test_ip_packet()
8803{
8804 local active_gw=$1
8805 local backup_gw=$2
8806
8807 # Send ip packet between foo1 and outside1
8808 src_mac="f00000010203" # foo1 mac
8809 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8810 src_ip=`ip_to_hex 192 168 1 2`
8811 dst_ip=`ip_to_hex 172 16 1 3`
8812 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8813
8814 # ARP request packet to expect at outside1
8815 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8816
8817 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8818
8819 # Send ARP reply from outside1 back to the router
8820 # XXX: note, we could avoid this if we plug this port into a netns
8821 # and setup the IP address into the port, so the kernel would simply reply
8822 src_mac="000002010203"
8823 reply_mac="f00000010204"
8824 dst_ip=`ip_to_hex 172 16 1 3`
8825 src_ip=`ip_to_hex 172 16 1 1`
8826 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8827
8828 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8829
86c9d79a
NS
8830 OVS_WAIT_UNTIL([
8831 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8832grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8833 ])
8834
75f9e007
GZ
8835 # Packet to Expect at ext1 chassis, outside1 port
8836 src_mac="000002010203"
8837 dst_mac="f00000010204"
8838 src_ip=`ip_to_hex 192 168 1 2`
8839 dst_ip=`ip_to_hex 172 16 1 3`
8840 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8841 echo $expected > ext1-vif1.expected
d65586b6
NS
8842 exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
8843 echo $exp_gw_ip_garp >> ext1-vif1.expected
75f9e007
GZ
8844
8845 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8846 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8847 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8848
8849 # Resend packet from foo1 to outside1
8850 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8851
75f9e007
GZ
8852 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8853 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
d65586b6 8854 cat packets | grep $expected > exp
fbe67a7d 8855 cat packets | grep $exp_gw_ip_garp | head -1 >> exp
d65586b6
NS
8856 AT_CHECK([cat exp], [0], [expout])
8857
75f9e007
GZ
8858 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8859 AT_CHECK([grep $expected packets | sort], [0], [])
8860}
8861
8862test_ip_packet gw1 gw2
8863
8e1d9349 8864ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 8865 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8866 chassis_name=gw1 \
8867 priority=10 -- \
8868 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8869 chassis_name=gw2 \
8870 priority=20 -- \
8871 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8872
8873test_ip_packet gw2 gw1
8874
8875OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8876AT_CLEANUP
8877
41a15b71
MS
8878AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8879AT_SKIP_IF([test $HAVE_PYTHON = no])
8880ovn_start
8881
8882# Logical network:
8883# One LR R1 that has switches foo (192.168.1.0/24) and
8884# alice (172.16.1.0/24) connected to it. The logical port
8885# between R1 and alice has a "redirect-chassis" specified,
8886# i.e. it is the distributed router gateway port.
8887# Switch alice also has a localnet port defined.
8888# An additional switch outside has a localnet port and the
8889# same subnet as alice (172.16.1.0/24).
8890
8891# Physical network:
8892# Three hypervisors hv[123].
8893# hv1 hosts vif foo1.
8894# hv2 is the "redirect-chassis" that hosts the distributed
8895# router gateway port.
8896# hv3 hosts vif outside1.
8897# In order to show that connectivity works only through hv2,
8898# an initial round of tests is run without any bridge-mapping
8899# defined for the localnet on hv2. These tests are expected
8900# to fail.
8901# Subsequent tests are run after defining the bridge-mapping
8902# for the localnet on hv2. These tests are expected to succeed.
8903
8904# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 8905# to logical ports.
41a15b71
MS
8906net_add n1
8907
8908sim_add hv1
8909as hv1
8910ovs-vsctl add-br br-phys
8911ovn_attach n1 br-phys 192.168.0.1
8912ovs-vsctl -- add-port br-int hv1-vif1 -- \
8913 set interface hv1-vif1 external-ids:iface-id=foo1 \
8914 options:tx_pcap=hv1/vif1-tx.pcap \
8915 options:rxq_pcap=hv1/vif1-rx.pcap \
8916 ofport-request=1
8917
8918sim_add hv2
8919as hv2
8920ovs-vsctl add-br br-phys
8921ovn_attach n1 br-phys 192.168.0.2
8922
8923sim_add hv3
8924as hv3
8925ovs-vsctl add-br br-phys
8926ovn_attach n1 br-phys 192.168.0.3
8927ovs-vsctl -- add-port br-int hv3-vif1 -- \
8928 set interface hv3-vif1 external-ids:iface-id=outside1 \
8929 options:tx_pcap=hv3/vif1-tx.pcap \
8930 options:rxq_pcap=hv3/vif1-rx.pcap \
8931 ofport-request=1
8932
8933# Pre-populate the hypervisors' ARP tables so that we don't lose any
8934# packets for ARP resolution (native tunneling doesn't queue packets
8935# for ARP resolution).
74868f2c 8936OVN_POPULATE_ARP
41a15b71
MS
8937
8938ovn-nbctl create Logical_Router name=R1
8939
8940ovn-nbctl ls-add foo
8941ovn-nbctl ls-add alice
8942ovn-nbctl ls-add outside
8943
8944# Connect foo to R1
8945ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8946ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8947 type=router options:router-port=foo \
8948 -- lsp-set-addresses rp-foo router
8949
8950# Connect alice to R1 as distributed router gateway port on hv2
8951ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8952 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8953ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8954 type=router options:router-port=alice \
8955 -- lsp-set-addresses rp-alice router
8956
8957# Create logical port foo1 in foo
8958ovn-nbctl lsp-add foo foo1 \
8959-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8960
8961# Create logical port outside1 in outside
8962ovn-nbctl lsp-add outside outside1 \
8963-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8964
8965# Create localnet port in alice
8966ovn-nbctl lsp-add alice ln-alice
8967ovn-nbctl lsp-set-addresses ln-alice unknown
8968ovn-nbctl lsp-set-type ln-alice localnet
8969ovn-nbctl lsp-set-options ln-alice network_name=phys
8970
8971# Create localnet port in outside
8972ovn-nbctl lsp-add outside ln-outside
8973ovn-nbctl lsp-set-addresses ln-outside unknown
8974ovn-nbctl lsp-set-type ln-outside localnet
8975ovn-nbctl lsp-set-options ln-outside network_name=phys
8976
8977# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8978as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8979as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8980
8981
8982# Allow some time for ovn-northd and ovn-controller to catch up.
8983# XXX This should be more systematic.
8984sleep 2
8985
8986echo "---------NB dump-----"
8987ovn-nbctl show
8988echo "---------------------"
8989ovn-nbctl list logical_router
8990echo "---------------------"
8991ovn-nbctl list logical_router_port
8992echo "---------------------"
8993
8994echo "---------SB dump-----"
8995ovn-sbctl list datapath_binding
8996echo "---------------------"
8997ovn-sbctl list port_binding
8998echo "---------------------"
8999ovn-sbctl dump-flows
9000echo "---------------------"
9001ovn-sbctl list chassis
9002ovn-sbctl list encap
1da17a0b 9003echo "------ Gateway_Chassis dump (SBDB) -------"
9004ovn-sbctl list Gateway_Chassis
9005echo "------ Port_Binding chassisredirect -------"
9006ovn-sbctl find Port_Binding type=chassisredirect
9007echo "-------------------------------------------"
41a15b71
MS
9008
9009echo "------ hv1 dump ----------"
9010as hv1 ovs-ofctl show br-int
9011as hv1 ovs-ofctl dump-flows br-int
9012echo "------ hv2 dump ----------"
9013as hv2 ovs-ofctl show br-int
9014as hv2 ovs-ofctl dump-flows br-int
9015echo "------ hv3 dump ----------"
9016as hv3 ovs-ofctl show br-int
9017as hv3 ovs-ofctl dump-flows br-int
9018echo "--------------------------"
9019
1da17a0b 9020
41a15b71
MS
9021# Check that redirect mapping is programmed only on hv2
9022AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
9023])
9024AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
9025])
9026# Check that hv1 sends chassisredirect port traffic to hv2
9027AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
9028])
9029AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
9030])
9031# Check that arp reply on distributed gateway port is only programmed on hv2
b0684540 9032AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
41a15b71 9033])
b0684540 9034AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
41a15b71
MS
9035])
9036
9037
9038ip_to_hex() {
9039 printf "%02x%02x%02x%02x" "$@"
9040}
9041
9042
9043: > hv2-vif1.expected
9044: > hv3-vif1.expected
9045
9046# test_arp INPORT SHA SPA TPA [REPLY_HA]
9047#
9048# Causes a packet to be received on INPORT. The packet is an ARP
9049# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
9050# it should be the hardware address of the target to expect to receive in an
9051# ARP reply; otherwise no reply is expected.
9052#
9053# INPORT is an logical switch port number, e.g. 11 for vif11.
9054# SHA and REPLY_HA are each 12 hex digits.
9055# SPA and TPA are each 8 hex digits.
9056test_arp() {
9057 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
9058 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
9059 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
9060
9061 if test X$reply_ha != X; then
9062 # Expect to receive the reply, if any.
9063 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
9064 echo $reply >> hv${hv}-vif$inport.expected
9065 fi
9066}
9067
9068rtr_ip=$(ip_to_hex 172 16 1 1)
9069foo_ip=$(ip_to_hex 192 168 1 2)
9070outside_ip=$(ip_to_hex 172 16 1 3)
9071
9072echo $rtr_ip
9073echo $foo_ip
9074echo $outside_ip
9075
9076# ARP for router IP address from outside1, no response expected
9077test_arp 3 1 f00000010204 $outside_ip $rtr_ip
9078
9079# Now check the packets actually received against the ones expected.
9080OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9081
9082# Send ip packet between foo1 and outside1
9083src_mac="f00000010203"
9084dst_mac="000001010203"
9085src_ip=`ip_to_hex 192 168 1 2`
9086dst_ip=`ip_to_hex 172 16 1 3`
9087packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9088
9089# Now check the packets actually received against the ones expected.
9090OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9091
9092# Now add bridge-mappings on hv2, which should make everything work
9093as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9094
d65586b6
NS
9095# Wait until the patch ports are created in hv2 to connect br-int to br-phys
9096OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
9097grep "Port patch-br-int-to-ln-alice" | wc -l`])
41a15b71
MS
9098
9099# ARP for router IP address from outside1
9100test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
9101
d65586b6
NS
9102# hv3-vif1.expected should also have the gw router port garp packet.
9103exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
9104echo $exp_gw_ip_garp >> hv3-vif1.expected
9105
41a15b71
MS
9106# Now check the packets actually received against the ones expected.
9107OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9108
9109# Send ip packet between foo1 and outside1
9110src_mac="f00000010203"
9111dst_mac="000001010203"
9112src_ip=`ip_to_hex 192 168 1 2`
9113dst_ip=`ip_to_hex 172 16 1 3`
9114packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9115
41a15b71
MS
9116# Packet to Expect at outside1
9117src_mac="000002010203"
9118dst_mac="f00000010204"
41a15b71
MS
9119expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
9120
41a15b71
MS
9121as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9122
9123echo "------ hv1 dump ----------"
9124as hv1 ovs-ofctl show br-int
9125as hv1 ovs-ofctl dump-flows br-int
9126echo "------ hv2 dump ----------"
9127as hv2 ovs-ofctl show br-int
9128as hv2 ovs-ofctl dump-flows br-int
9129echo "------ hv3 dump ----------"
9130as hv3 ovs-ofctl show br-int
9131as hv3 ovs-ofctl dump-flows br-int
9132echo "----------------------------"
9133
9134echo $expected >> hv3-vif1.expected
9135OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9136
9137#Check ovn-trace over "chassisredirect" port
9138AT_CAPTURE_FILE([trace])
9139ovn_trace () {
9140 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
9141}
9142
9143echo 'ip.ttl--;' > expout
9144echo 'eth.src = 00:00:02:01:02:03;' >> expout
9145echo 'eth.dst = f0:00:00:01:02:04;' >> expout
9146echo 'output("ln-alice");' >> expout
9147AT_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])
9148
9149# Create logical port alice1 in alice on hv1
9150as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
9151 set interface hv1-vif2 external-ids:iface-id=alice1 \
9152 options:tx_pcap=hv1/vif2-tx.pcap \
9153 options:rxq_pcap=hv1/vif2-rx.pcap \
9154 ofport-request=1
9155
9156ovn-nbctl lsp-add alice alice1 \
9157-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
9158
9159# Create logical port foo2 in foo on hv2
9160as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
9161 set interface hv2-vif1 external-ids:iface-id=foo2 \
9162 options:tx_pcap=hv2/vif1-tx.pcap \
9163 options:rxq_pcap=hv2/vif1-rx.pcap \
9164 ofport-request=1
9165
9166ovn-nbctl lsp-add foo foo2 \
9167-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
9168
9169# Allow some time for ovn-northd and ovn-controller to catch up.
9170# XXX This should be more systematic.
9171sleep 1
9172
9173: > hv1-vif2.expected
9174
9175# Send ip packet between alice1 and foo2
9176src_mac="f00000010205"
9177dst_mac="000002010203"
9178src_ip=`ip_to_hex 172 16 1 4`
9179dst_ip=`ip_to_hex 192 168 1 3`
9180packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9181
9182as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
9183
9184# Packet to Expect at foo2
9185src_mac="000001010203"
9186dst_mac="f00000010206"
9187src_ip=`ip_to_hex 172 16 1 4`
9188dst_ip=`ip_to_hex 192 168 1 3`
9189expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
9190
9191echo $expected >> hv2-vif1.expected
f5f64552 9192OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 9193
0d31e5be 9194AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 9195])
9196
8e1d9349 9197ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 9198
0d31e5be 9199AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 9200])
9201
41a15b71
MS
9202OVN_CLEANUP([hv1],[hv2],[hv3])
9203
9204AT_CLEANUP
26b9e08d
MS
9205
9206AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
9207AT_SKIP_IF([test $HAVE_PYTHON = no])
9208ovn_start
9209# Create logical switches
9210ovn-nbctl ls-add ls0
9211ovn-nbctl ls-add ls1
9212# Create distributed router
9213ovn-nbctl create Logical_Router name=lr0
9214# Add distributed gateway port to distributed router
9215ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
9216 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
9217ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9218 type=router options:router-port=lrp0 addresses="router"
9219# Add router port to ls1
9220ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9221ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9222 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
9223# Add logical ports for NAT rules
9224ovn-nbctl lsp-add ls1 foo1 \
9225-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
9226ovn-nbctl lsp-add ls1 foo2 \
9227-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
9228# Add nat-addresses option
9229ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9230# Add NAT rules
9231AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
9232AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
9233AT_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 9234AT_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
9235
9236net_add n1
9237sim_add hv1
9238as hv1
9239ovs-vsctl add-br br-phys
9240ovn_attach n1 br-phys 192.168.0.1
9241
9242AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9243AT_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])
9244
9245sim_add hv2
9246as hv2
9247ovs-vsctl add-br br-phys
9248ovn_attach n1 br-phys 192.168.0.2
9249# Initially test with no bridge-mapping on hv2, expect to receive no packets
9250
f40c5588
MS
9251sim_add hv3
9252as hv3
9253ovs-vsctl add-br br-phys
9254ovn_attach n1 br-phys 192.168.0.3
9255# Initially test with no bridge-mapping on hv3
9256
26b9e08d
MS
9257# Create a localnet port.
9258AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9259AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9260AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
d65586b6 9261AT_CHECK([ovn-nbctl --wait=hv lsp-set-options ln_port network_name=physnet1])
26b9e08d
MS
9262
9263# Allow some time for ovn-northd and ovn-controller to catch up.
9264# XXX This should be more systematic.
9265sleep 2
9266
9267# Expect no packets when hv2 bridge-mapping is not present
9268: > packets
9269OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
9270
9271# Add bridge-mapping on hv2
f40c5588 9272AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d 9273
d65586b6
NS
9274# Wait until the patch ports are created in hv2 to connect br-int to br-phys
9275OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
9276grep "Port patch-br-int-to-ln_port" | wc -l`])
9277
26b9e08d
MS
9278# Wait for packets to be received.
9279OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9280trim_zeros() {
9281 sed 's/\(00\)\{1,\}$//'
9282}
9283$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
9284expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
9285echo $expected > expout
9286expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
9287echo $expected >> expout
9288AT_CHECK([sort packets], [0], [expout])
f40c5588 9289sort packets | cat
26b9e08d 9290
f40c5588
MS
9291# Temporarily remove nat-addresses option to avoid race conditions
9292# due to GARP backoff
9293ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
9294
9295reset_pcap_file() {
9296 local iface=$1
9297 local pcap_file=$2
9298 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9299options:rxq_pcap=dummy-rx.pcap
9300 rm -f ${pcap_file}*.pcap
9301 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9302options:rxq_pcap=${pcap_file}-rx.pcap
9303}
9304
9305as hv1 reset_pcap_file snoopvif hv1/snoopvif
9306
9307# Add OVS ports for foo1 and foo2 on hv3
9308ovs-vsctl -- add-port br-int hv3-vif1 -- \
9309 set interface hv3-vif1 external-ids:iface-id=foo1 \
9310 ofport-request=1
9311ovs-vsctl -- add-port br-int hv3-vif2 -- \
9312 set interface hv3-vif2 external-ids:iface-id=foo2 \
9313 ofport-request=2
9314
9315# Add bridge-mapping on hv3
9316AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9317
d65586b6
NS
9318# Wait until the patch ports are created in hv3 to connect br-int to br-phys
9319OVS_WAIT_UNTIL([test 1 = `as hv3 ovs-vsctl show | \
9320grep "Port patch-br-int-to-ln_port" | wc -l`])
9321
f40c5588
MS
9322# Re-add nat-addresses option
9323ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9324
9325# Wait for packets to be received.
9326OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
9327trim_zeros() {
9328 sed 's/\(00\)\{1,\}$//'
9329}
9330
9331$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
d65586b6
NS
9332garp_1="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
9333echo $garp_1 > expout
9334garp_2="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
9335echo $garp_2 >> expout
9336
9337cat packets | grep $garp_1 | head -1 > exp
9338cat packets | grep $garp_2 | head -1 >> exp
9339AT_CHECK([cat exp], [0], [expout])
f40c5588
MS
9340
9341OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
9342
9343AT_CLEANUP
6b785fd8 9344
85706c34
NS
9345# VLAN traffic for external network redirected through distributed router
9346# gateway port should use vlans(i.e input network vlan tag) across hypervisors
9347# instead of tunneling.
9348AT_SETUP([ovn -- vlan traffic for external network with distributed router gateway port])
9349AT_SKIP_IF([test $HAVE_PYTHON = no])
9350ovn_start
9351
9352# Logical network:
9353# # One LR R1 that has switches foo (192.168.1.0/24) and
9354# # alice (172.16.1.0/24) connected to it. The logical port
9355# # between R1 and alice has a "redirect-chassis" specified,
9356# # i.e. it is the distributed router gateway port(172.16.1.6).
9357# # Switch alice also has a localnet port defined.
9358# # An additional switch outside has the same subnet as alice
9359# # (172.16.1.0/24), a localnet port and nexthop port(172.16.1.1)
9360# # which will receive the packet destined for external network
9361# # (i.e 8.8.8.8 as destination ip).
9362
9363# Physical network:
ed198fb3 9364# # Four hypervisors hv[1234].
85706c34
NS
9365# # hv1 hosts vif foo1.
9366# # hv2 is the "redirect-chassis" that hosts the distributed router gateway port.
ed198fb3 9367# # Later to test GARPs for the router port - foo, hv2 and hv4 are added to the ha_chassis_group
85706c34
NS
9368# # hv3 hosts nexthop port vif outside1.
9369# # All other tests connect hypervisors to network n1 through br-phys for tunneling.
9370# # But in this test, hv1 won't connect to n1(and no br-phys in hv1), and
9371# # in order to show vlans(instead of tunneling) used between hv1 and hv2,
9372# # a new network n2 created and hv1 and hv2 connected to this network through br-ex.
9373# # hv2 and hv3 are still connected to n1 network through br-phys.
9374net_add n1
9375
9376# We are not calling ovn_attach for hv1, to avoid adding br-phys.
9377# Tunneling won't work in hv1 as ovn-encap-ip is not added to any bridge in hv1
9378sim_add hv1
9379as hv1
9380ovs-vsctl \
9381 -- set Open_vSwitch . external-ids:system-id=hv1 \
9382 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
9383 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
9384 -- set Open_vSwitch . external-ids:ovn-encap-ip=192.168.0.1 \
9385 -- add-br br-int \
9386 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
9387 -- set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-ex
9388
9389start_daemon ovn-controller
9390ovs-vsctl -- add-port br-int hv1-vif1 -- \
9391 set interface hv1-vif1 external-ids:iface-id=foo1 \
ed198fb3
NS
9392 options:tx_pcap=hv1/vif1-tx.pcap \
9393 options:rxq_pcap=hv1/vif1-rx.pcap \
85706c34
NS
9394 ofport-request=1
9395
9396sim_add hv2
9397as hv2
9398ovs-vsctl add-br br-phys
9399ovn_attach n1 br-phys 192.168.0.2
9400ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
9401
9402sim_add hv3
9403as hv3
9404ovs-vsctl add-br br-phys
9405ovn_attach n1 br-phys 192.168.0.3
9406ovs-vsctl -- add-port br-int hv3-vif1 -- \
9407 set interface hv3-vif1 external-ids:iface-id=outside1 \
9408 options:tx_pcap=hv3/vif1-tx.pcap \
9409 options:rxq_pcap=hv3/vif1-rx.pcap \
9410 ofport-request=1
9411ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="phys:br-phys"
9412
ed198fb3
NS
9413sim_add hv4
9414as hv4
9415ovs-vsctl add-br br-phys
9416ovn_attach n1 br-phys 192.168.0.4
9417ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
9418
85706c34
NS
9419# Create network n2 for vlan connectivity between hv1 and hv2
9420net_add n2
9421
9422as hv1
9423ovs-vsctl add-br br-ex
9424net_attach n2 br-ex
9425
9426as hv2
9427ovs-vsctl add-br br-ex
9428net_attach n2 br-ex
9429
ed198fb3
NS
9430as hv4
9431ovs-vsctl add-br br-ex
9432net_attach n2 br-ex
9433
85706c34
NS
9434OVN_POPULATE_ARP
9435
9436ovn-nbctl create Logical_Router name=R1
9437
9438ovn-nbctl ls-add foo
9439ovn-nbctl ls-add alice
9440ovn-nbctl ls-add outside
9441
9442# Connect foo to R1
9443ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
9444ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
9445 type=router options:router-port=foo \
9446 -- lsp-set-addresses rp-foo router
9447
9448# Connect alice to R1 as distributed router gateway port (172.16.1.6) on hv2
9449ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.6/24 \
9450 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
9451ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9452 type=router options:router-port=alice \
9453 -- lsp-set-addresses rp-alice router \
9454
9455# Create logical port foo1 in foo
9456ovn-nbctl lsp-add foo foo1 \
9457-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9458
9459# Create logical port outside1 in outside, which is a nexthop address
9460# for 172.16.1.0/24
9461ovn-nbctl lsp-add outside outside1 \
9462-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.1"
9463
9464# Set default gateway (nexthop) to 172.16.1.1
9465ovn-nbctl lr-route-add R1 "0.0.0.0/0" 172.16.1.1 alice
9466AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.6 192.168.1.1/24])
9467ovn-nbctl set Logical_Switch_Port rp-alice options:nat-addresses=router
9468
9469ovn-nbctl lsp-add foo ln-foo
9470ovn-nbctl lsp-set-addresses ln-foo unknown
9471ovn-nbctl lsp-set-options ln-foo network_name=public
9472ovn-nbctl lsp-set-type ln-foo localnet
9473AT_CHECK([ovn-nbctl set Logical_Switch_Port ln-foo tag=2])
9474
9475# Create localnet port in alice
9476ovn-nbctl lsp-add alice ln-alice
9477ovn-nbctl lsp-set-addresses ln-alice unknown
9478ovn-nbctl lsp-set-type ln-alice localnet
9479ovn-nbctl lsp-set-options ln-alice network_name=phys
9480
9481# Create localnet port in outside
9482ovn-nbctl lsp-add outside ln-outside
9483ovn-nbctl lsp-set-addresses ln-outside unknown
9484ovn-nbctl lsp-set-type ln-outside localnet
9485ovn-nbctl lsp-set-options ln-outside network_name=phys
9486
9487# Allow some time for ovn-northd and ovn-controller to catch up.
9488# XXX This should be more systematic.
9489ovn-nbctl --wait=hv --timeout=3 sync
9490
9491# Check that there is a logical flow in logical switch foo's pipeline
9492# to set the outport to rp-foo (which is expected).
9493OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
9494grep rp-foo | grep -v is_chassis_resident | wc -l`])
9495
9496# Set the option 'reside-on-redirect-chassis' for foo
9497ovn-nbctl set logical_router_port foo options:reside-on-redirect-chassis=true
9498# Check that there is a logical flow in logical switch foo's pipeline
9499# to set the outport to rp-foo with the condition is_chassis_redirect.
9500ovn-sbctl dump-flows foo
9501OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
9502grep rp-foo | grep is_chassis_resident | wc -l`])
9503
9504echo "---------NB dump-----"
9505ovn-nbctl show
9506echo "---------------------"
9507ovn-nbctl list logical_router
9508echo "---------------------"
9509ovn-nbctl list nat
9510echo "---------------------"
9511ovn-nbctl list logical_router_port
9512echo "---------------------"
9513
9514echo "---------SB dump-----"
9515ovn-sbctl list datapath_binding
9516echo "---------------------"
9517ovn-sbctl list port_binding
9518echo "---------------------"
9519ovn-sbctl dump-flows
9520echo "---------------------"
9521ovn-sbctl list chassis
9522echo "---------------------"
9523
9524for chassis in hv1 hv2 hv3; do
9525 as $chassis
9526 echo "------ $chassis dump ----------"
9527 ovs-vsctl show br-int
9528 ovs-ofctl show br-int
9529 ovs-ofctl dump-flows br-int
9530 echo "--------------------------"
9531done
9532
9533ip_to_hex() {
9534 printf "%02x%02x%02x%02x" "$@"
9535}
9536
9537foo1_ip=$(ip_to_hex 192 168 1 2)
9538gw_ip=$(ip_to_hex 172 16 1 6)
9539dst_ip=$(ip_to_hex 8 8 8 8)
9540nexthop_ip=$(ip_to_hex 172 16 1 1)
9541
9542foo1_mac="f00000010203"
9543foo_mac="000001010203"
9544gw_mac="000002010203"
9545nexthop_mac="f00000010204"
9546
9547# Send ip packet from foo1 to 8.8.8.8
9548src_mac="f00000010203"
9549dst_mac="000001010203"
9550packet=${foo_mac}${foo1_mac}08004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
9551
81e92852 9552# Wait for GARPs announcing gw IP to arrive
85706c34
NS
9553OVS_WAIT_UNTIL([
9554 test `as hv2 ovs-ofctl dump-flows br-int | grep table=66 | \
9555grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
9556 ])
9557
9558# VLAN tagged packet with router port(192.168.1.1) MAC as destination MAC
9559# is expected on bridge connecting hv1 and hv2
9560expected=${foo_mac}${foo1_mac}8100000208004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
9561echo $expected > hv1-br-ex_n2.expected
9562
9563# Packet to Expect at outside1 i.e nexthop(172.16.1.1) port.
9564# As connection tracking not enabled for this test, snat can't be done on the packet.
9565# We still see foo1 as the source ip address. But source mac(gateway MAC) and
9566# dest mac(nexthop mac) are properly configured.
9567expected=${nexthop_mac}${gw_mac}08004500001c000000003f110100${foo1_ip}${dst_ip}0035111100080000
9568echo $expected > hv3-vif1.expected
9569
9570reset_pcap_file() {
9571 local iface=$1
9572 local pcap_file=$2
9573 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9574options:rxq_pcap=dummy-rx.pcap
9575 rm -f ${pcap_file}*.pcap
9576 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9577options:rxq_pcap=${pcap_file}-rx.pcap
9578}
9579
9580as hv1 reset_pcap_file br-ex_n2 hv1/br-ex_n2
9581as hv3 reset_pcap_file hv3-vif1 hv3/vif1
85706c34
NS
9582as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9583sleep 2
9584
85706c34
NS
9585# On hv1, table 32 check that no packet goes via the tunnel port
9586AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 \
9587| grep "NXM_NX_TUN_ID" | grep -v n_packets=0 | wc -l], [0], [[0
9588]])
9589
9590ip_packet() {
9591 grep "1010203f00000010203"
9592}
9593
9594# Check vlan tagged packet on the bridge connecting hv1 and hv2 with the
9595# foo1's mac.
9596$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-ex_n2-tx.pcap | ip_packet | uniq > hv1-br-ex_n2
9597cat hv1-br-ex_n2.expected > expout
9598AT_CHECK([sort hv1-br-ex_n2], [0], [expout])
9599
9600# Check expected packet on nexthop interface
9601$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/vif1-tx.pcap | grep ${foo1_ip}${dst_ip} | uniq > hv3-vif1
9602cat hv3-vif1.expected > expout
9603AT_CHECK([sort hv3-vif1], [0], [expout])
9604
ed198fb3
NS
9605# Test the GARP for the router port ip - 192.168.1.1
9606ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
9607
9608as hv1 reset_pcap_file hv1-vif1 hv1/vif1
9609as hv2 reset_pcap_file br-ex_n2 hv2/br-ex_n2
9610as hv4 reset_pcap_file br-ex_n2 hv4/br-ex_n2
9611
9612ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv2 30
9613ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv4 20
9614
9615hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
9616ovn-nbctl remove logical_router_port alice options redirect-chassis
9617ovn-nbctl --wait=sb set logical_router_port alice ha_chassis_group=$hagrp1_uuid
9618
9619# When hv2 claims the gw router port cr-alice, it should send out
9620# GARP for 192.168.1.1 and it should be received by foo1 on hv1.
9621
9622# foo1 (on hv1) should receive GARP without VLAN tag
9623exp_garp_on_foo1="ffffffffffff00000101020308060001080006040001000001010203c0a80101000000000000c0a80101"
9624echo $exp_garp_on_foo1 > foo1.expout
9625
9626# ovn-controller on hv2 should send garp with VLAN tag
9627sent_garp="ffffffffffff0000010102038100000208060001080006040001000001010203c0a80101000000000000c0a80101"
ed198fb3
NS
9628
9629OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [foo1.expout])
fbe67a7d
NS
9630# Wait until we receive atleast 1 packet
9631OVS_WAIT_UNTIL([test 1=`$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap | wc -l`])
9632$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap | head -1 > packets
9633echo $sent_garp > expout
9634AT_CHECK([cat packets], [0], [expout])
ed198fb3
NS
9635$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv4/br-ex_n2-tx.pcap > empty
9636AT_CHECK([cat empty], [0], [])
9637
9638# Make hv4 master
9639as hv1 reset_pcap_file hv1-vif1 hv1/vif1
ed198fb3
NS
9640as hv4 reset_pcap_file br-ex_n2 hv4/br-ex_n2
9641ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv4 40
9642
fbe67a7d
NS
9643# Wait till cr-alice is claimed by hv4
9644hv4_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=hv4)
9645# check that the chassis redirect port has been claimed by the gw1 chassis
9646OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
9647logical_port=cr-alice | grep $hv4_chassis | wc -l], [0],[[1
9648]])
9649
9650# Reset the pcap file for hv2/br-ex_n2. From now on ovn-controller in hv2
9651# should not send GARPs for the router ports.
9652as hv2 reset_pcap_file br-ex_n2 hv2/br-ex_n2
9653
9654echo $sent_garp > br-ex_n2.expout
ed198fb3
NS
9655OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [foo1.expout])
9656OVN_CHECK_PACKETS([hv4/br-ex_n2-tx.pcap], [br-ex_n2.expout])
fbe67a7d
NS
9657
9658sleep 2
9659
ed198fb3
NS
9660$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap > empty
9661AT_CHECK([cat empty], [0], [])
9662
9663OVN_CLEANUP([hv1],[hv2],[hv3], [hv4])
85706c34
NS
9664AT_CLEANUP
9665
4364646c
ZKL
9666AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
9667AT_KEYWORDS([ovn-nd_ra])
9668AT_SKIP_IF([test $HAVE_PYTHON = no])
9669ovn_start
9670
9671# In this test case we create 1 lswitch with 3 VIF ports attached,
9672# and a lrouter connected to the lswitch.
9673# We generate the Router solicitation packet and verify the Router Advertisement
9674# reply packet from the ovn-controller.
9675
9676# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
9677# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
9678# 'slaac' to allow lrp0 send RA for SLAAC mode.
9679ovn-nbctl ls-add lsw0
9680ovn-nbctl lr-add lr0
9681ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
9682ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
9683ovn-nbctl \
9684 -- lsp-add lsw0 lsp0 \
9685 -- set Logical_Switch_Port lsp0 type=router \
9686 options:router-port=lrp0 \
9687 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
9688net_add n1
9689sim_add hv1
9690as hv1
9691ovs-vsctl add-br br-phys
9692ovn_attach n1 br-phys 192.168.0.2
9693
9694ovn-nbctl lsp-add lsw0 lp1
9695ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
9696ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
9697
9698ovn-nbctl lsp-add lsw0 lp2
9699ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
9700ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
9701
9702ovn-nbctl lsp-add lsw0 lp3
9703ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
9704ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
9705
9706# Add ACL rule for ICMPv6 on lsw0
9707ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
9708ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
9709ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
9710ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
9711
9712ovs-vsctl -- add-port br-int hv1-vif1 -- \
9713 set interface hv1-vif1 external-ids:iface-id=lp1 \
9714 options:tx_pcap=hv1/vif1-tx.pcap \
9715 options:rxq_pcap=hv1/vif1-rx.pcap \
9716 ofport-request=1
9717
9718ovs-vsctl -- add-port br-int hv1-vif2 -- \
9719 set interface hv1-vif2 external-ids:iface-id=lp2 \
9720 options:tx_pcap=hv1/vif2-tx.pcap \
9721 options:rxq_pcap=hv1/vif2-rx.pcap \
9722 ofport-request=2
9723
9724ovs-vsctl -- add-port br-int hv1-vif3 -- \
9725 set interface hv1-vif3 external-ids:iface-id=lp3 \
9726 options:tx_pcap=hv1/vif3-tx.pcap \
9727 options:rxq_pcap=hv1/vif3-rx.pcap \
9728 ofport-request=3
9729
9730# Allow some time for ovn-northd and ovn-controller to catch up.
9731# XXX This should be more systematic.
9732sleep 1
9733
9734reset_pcap_file() {
9735 local iface=$1
9736 local pcap_file=$2
9737 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9738options:rxq_pcap=dummy-rx.pcap
9739 rm -f ${pcap_file}*.pcap
9740 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9741options:rxq_pcap=${pcap_file}-rx.pcap
9742}
9743
9744# Make sure that ovn-controller has installed the corresponding OF Flow.
9745OVS_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"`])
9746
9747# This shell function sends a Router Solicitation packet.
9748# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
9749test_ipv6_ra() {
9750 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
9751 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
9752
9753 local len=24
9754 local mtu_opt=""
9755 if test $mtu != 0; then
9756 len=`expr $len + 8`
9757 mtu_opt=05010000${mtu}
9758 fi
9759
9760 if test ${#prefix_opt} != 0; then
9761 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
9762 len=`expr $len + ${#prefix_opt} / 2`
9763 fi
9764
9765 len=$(printf "%x" $len)
9766 local lrp_mac=fa163e000001
9767 local lrp_lla=fe80000000000000f8163efffe000001
9768 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
9769 echo $reply >> $inport.expected
9770
9771 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
9772}
9773
9774AT_CAPTURE_FILE([ofctl_monitor0.log])
9775as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
9776--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
9777
9778# MTU is not set and the address mode is set to slaac
9779addr_mode=00
9780default_prefix_option_config=030440c0ffffffffffffffff00000000
9781src_mac=fa163e000002
9782src_lla=fe80000000000000f8163efffe000002
9783test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
9784
9785# NXT_RESUME should be 1.
9786OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9787
9788$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9789
9790cat 1.expected | cut -c -112 > expout
9791AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9792
9793# Skipping the ICMPv6 checksum.
9794cat 1.expected | cut -c 117- > expout
9795AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9796
9797rm -f *.expected
9798reset_pcap_file hv1-vif1 hv1/vif1
9799reset_pcap_file hv1-vif2 hv1/vif2
9800reset_pcap_file hv1-vif3 hv1/vif3
9801
9802# Set the MTU to 1500
9803ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
9804
9805# Make sure that ovn-controller has installed the corresponding OF Flow.
9806OVS_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"`])
9807
9808addr_mode=00
9809default_prefix_option_config=030440c0ffffffffffffffff00000000
9810src_mac=fa163e000003
9811src_lla=fe80000000000000f8163efffe000003
9812mtu=000005dc
9813
9814test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9815
9816# NXT_RESUME should be 2.
9817OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9818
9819$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
9820
9821cat 2.expected | cut -c -112 > expout
9822AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9823
9824# Skipping the ICMPv6 checksum.
9825cat 2.expected | cut -c 117- > expout
9826AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9827
9828rm -f *.expected
9829reset_pcap_file hv1-vif1 hv1/vif1
9830reset_pcap_file hv1-vif2 hv1/vif2
9831reset_pcap_file hv1-vif3 hv1/vif3
9832
9833# Set the address mode to dhcpv6_stateful
9834ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
9835# Make sure that ovn-controller has installed the corresponding OF Flow.
9836OVS_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"`])
9837
9838addr_mode=80
36ffc466 9839default_prefix_option_config=03044080ffffffffffffffff00000000
4364646c
ZKL
9840src_mac=fa163e000004
9841src_lla=fe80000000000000f8163efffe000004
9842mtu=000005dc
9843
9844test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9845
9846# NXT_RESUME should be 3.
9847OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9848
9849$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
9850
9851cat 3.expected | cut -c -112 > expout
9852AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
9853
9854# Skipping the ICMPv6 checksum.
9855cat 3.expected | cut -c 117- > expout
9856AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
9857
9858rm -f *.expected
9859reset_pcap_file hv1-vif1 hv1/vif1
9860reset_pcap_file hv1-vif2 hv1/vif2
9861reset_pcap_file hv1-vif3 hv1/vif3
9862
9863# Set the address mode to dhcpv6_stateless
9864ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
9865# Make sure that ovn-controller has installed the corresponding OF Flow.
9866OVS_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"`])
9867
9868addr_mode=40
9869default_prefix_option_config=030440c0ffffffffffffffff00000000
9870src_mac=fa163e000002
9871src_lla=fe80000000000000f8163efffe000002
9872mtu=000005dc
9873
9874test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9875
9876# NXT_RESUME should be 4.
9877OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9878
9879$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9880
9881cat 1.expected | cut -c -112 > expout
9882AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9883
9884# Skipping the ICMPv6 checksum.
9885cat 1.expected | cut -c 117- > expout
9886AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9887
9888rm -f *.expected
9889reset_pcap_file hv1-vif1 hv1/vif1
9890reset_pcap_file hv1-vif2 hv1/vif2
9891reset_pcap_file hv1-vif3 hv1/vif3
9892
9893# Set the address mode to invalid.
9894ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
9895# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
9896OVS_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"`])
9897
9898addr_mode=40
9899default_prefix_option_config=""
9900src_mac=fa163e000002
9901src_lla=fe80000000000000f8163efffe000002
9902mtu=000005dc
9903
9904test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9905
9906# NXT_RESUME should be 4 only.
9907OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9908
9909$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9910AT_CHECK([cat 1.packets], [0], [])
9911
9912OVN_CLEANUP([hv1])
9913AT_CLEANUP
9914
6b785fd8
GS
9915AT_SETUP([ovn -- /32 router IP address])
9916AT_SKIP_IF([test $HAVE_PYTHON = no])
9917ovn_start
9918
9919# Logical network:
9920# 2 LS 'foo' and 'alice' connected via router R1.
9921# R1 connects to 'alice' with a /32 IP address. We use static routes and
9922# nexthop to push traffic to a logical port in switch 'alice'
9923
9924ovn-nbctl lr-add R1
9925
9926ovn-nbctl ls-add foo
9927ovn-nbctl ls-add alice
9928
9929# Connect foo to R1
9930ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
9931ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
9932 options:router-port=foo addresses=\"00:00:00:01:02:03\"
9933
9934# Connect alice to R1.
9935ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
9936ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9937 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
9938
9939# Create logical port foo1 in foo
9940ovn-nbctl lsp-add foo foo1 \
9941-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9942
9943# Create logical port alice1 in alice
9944ovn-nbctl lsp-add alice alice1 \
9945-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
9946
9947#install default route in R1 to use alice1's IP address as nexthop
9948ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
9949
9950# Create two hypervisor and create OVS ports corresponding to logical ports.
9951net_add n1
9952
9953sim_add hv1
9954as hv1
9955ovs-vsctl add-br br-phys
9956ovn_attach n1 br-phys 192.168.0.1
9957ovs-vsctl -- add-port br-int hv1-vif1 -- \
9958 set interface hv1-vif1 external-ids:iface-id=foo1 \
9959 options:tx_pcap=hv1/vif1-tx.pcap \
9960 options:rxq_pcap=hv1/vif1-rx.pcap \
9961 ofport-request=1
9962
9963sim_add hv2
9964as hv2
9965ovs-vsctl add-br br-phys
9966ovn_attach n1 br-phys 192.168.0.2
9967ovs-vsctl -- add-port br-int hv2-vif1 -- \
9968 set interface hv2-vif1 external-ids:iface-id=alice1 \
9969 options:tx_pcap=hv2/vif1-tx.pcap \
9970 options:rxq_pcap=hv2/vif1-rx.pcap \
9971 ofport-request=1
9972
9973
9974# Pre-populate the hypervisors' ARP tables so that we don't lose any
9975# packets for ARP resolution (native tunneling doesn't queue packets
9976# for ARP resolution).
74868f2c 9977OVN_POPULATE_ARP
6b785fd8
GS
9978
9979# Allow some time for ovn-northd and ovn-controller to catch up.
9980# XXX This should be more systematic.
9981sleep 1
9982
9983ip_to_hex() {
9984 printf "%02x%02x%02x%02x" "$@"
9985}
9986
9987# Send ip packets between foo1 and alice1
9988src_mac="f00000010203"
9989dst_mac="000000010203"
9990src_ip=`ip_to_hex 192 168 1 2`
9991dst_ip=`ip_to_hex 10 0 0 2`
9992packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9993
9994# Send the first packet to trigger a ARP response and population of
9995# mac_bindings table.
9996as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9997OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
b0b27a83 9998ovn-nbctl --wait=hv sync
6b785fd8
GS
9999
10000# Packet to Expect at 'alice1'
10001src_mac="000000010204"
10002dst_mac="f00000010204"
10003src_ip=`ip_to_hex 192 168 1 2`
10004dst_ip=`ip_to_hex 10 0 0 2`
10005echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
10006
10007OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
10008
10009OVN_CLEANUP([hv1],[hv2])
10010
10011AT_CLEANUP
2a38ef45
DA
10012
10013AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
10014AT_SKIP_IF([test $HAVE_PYTHON = no])
10015ovn_start
10016
10017ovn-nbctl ls-add ls1
10018
10019# Add localport to the switch
10020ovn-nbctl lsp-add ls1 lp01
10021ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
10022ovn-nbctl lsp-set-type lp01 localport
10023
10024net_add n1
10025
10026for i in 1 2; do
10027 sim_add hv$i
10028 as hv$i
10029 ovs-vsctl add-br br-phys
10030 ovn_attach n1 br-phys 192.168.0.$i
10031 ovs-vsctl add-port br-int vif01 -- \
10032 set Interface vif01 external-ids:iface-id=lp01 \
10033 options:tx_pcap=hv${i}/vif01-tx.pcap \
10034 options:rxq_pcap=hv${i}/vif01-rx.pcap \
10035 ofport-request=${i}0
10036
10037 ovs-vsctl add-port br-int vif${i}1 -- \
10038 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
10039 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
10040 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
10041 ofport-request=${i}1
10042
10043 ovn-nbctl lsp-add ls1 lp${i}1
10044 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
10045 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
10046
10047 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
10048done
10049
10050ovn-nbctl --wait=sb sync
10051ovn-sbctl dump-flows
10052
74868f2c 10053OVN_POPULATE_ARP
2a38ef45
DA
10054
10055# Given the name of a logical port, prints the name of the hypervisor
10056# on which it is located.
10057vif_to_hv() {
10058 echo hv${1%?}
10059}
10060#
10061# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
10062#
10063# This shell function causes a packet to be received on INPORT. The packet's
10064# content has Ethernet destination DST and source SRC (each exactly 12 hex
10065# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
10066# logical switch port numbers, e.g. 11 for vif11.
10067#
10068# EOUT is the end-to-end output port, that is, where the packet will end up
10069# after possibly bouncing through one or more localnet ports. LOUT is the
10070# logical output port, which might be a localnet port, as seen by ovn-trace
10071# (which doesn't know what localnet ports are connected to and therefore can't
10072# figure out the end-to-end answer).
10073#
10074# DEFHV is the default hypervisor from where the packet is going to be sent
10075# if the source port is a localport.
10076for i in 1 2; do
10077 for j in 0 1; do
10078 : > $i$j.expected
10079 done
10080done
10081test_packet() {
10082 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
10083 echo "$@"
10084
10085 # First try tracing the packet.
10086 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
10087 if test $lout != drop; then
10088 echo "output(\"$lout\");"
10089 fi > expout
10090 AT_CAPTURE_FILE([trace])
10091 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
10092
10093 # Then actually send a packet, for an end-to-end test.
10094 local packet=$(echo $dst$src | sed 's/://g')${eth}
10095 hv=`vif_to_hv $inport`
10096 # If hypervisor 0 (localport) use the defhv parameter
da88b550 10097 if test $hv = hv0; then
2a38ef45
DA
10098 hv=$defhv
10099 fi
10100 vif=vif$inport
10101 as $hv ovs-appctl netdev-dummy/receive $vif $packet
10102 if test $eout != drop; then
10103 echo $packet >> ${eout#lp}.expected
10104 fi
10105}
10106
10107
10108# lp11 and lp21 are on different hypervisors
10109test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
10110test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
10111
10112# Both VIFs should be able to reach the localport on their own HV
10113test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
10114test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
10115
10116# Packet sent from localport on same hv should reach the vif
10117test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
10118test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
10119
10120# Packet sent from localport on different hv should be dropped
10121test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
10122test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
10123
10124# Now check the packets actually received against the ones expected.
10125for i in 1 2; do
10126 for j in 0 1; do
10127 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
10128 done
10129done
10130
10131OVN_CLEANUP([hv1],[hv2])
10132
10133AT_CLEANUP
1da17a0b 10134
10135AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
10136AT_SKIP_IF([test $HAVE_PYTHON = no])
10137ovn_start
10138
10139net_add n1
10140
10141# create gateways with external network connectivity
10142
10143for i in 1 2; do
10144 sim_add gw$i
10145 as gw$i
10146 ovs-vsctl add-br br-phys
10147 ovn_attach n1 br-phys 192.168.0.$i
10148 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10149done
10150
10151ovn-nbctl ls-add inside
10152ovn-nbctl ls-add outside
10153
10154# create hypervisors with a vif port each to an internal network
10155
10156for i in 1 2; do
10157 sim_add hv$i
10158 as hv$i
10159 ovs-vsctl add-br br-phys
10160 ovn_attach n1 br-phys 192.168.0.1$i
10161 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10162 set interface hv$i-vif1 external-ids:iface-id=inside$i \
10163 options:tx_pcap=hv$i/vif1-tx.pcap \
10164 options:rxq_pcap=hv$i/vif1-rx.pcap \
10165 ofport-request=1
10166
10167 ovn-nbctl lsp-add inside inside$i \
10168 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
10169
10170done
10171
74868f2c 10172OVN_POPULATE_ARP
1da17a0b 10173
10174ovn-nbctl create Logical_Router name=R1
10175
10176# Connect inside to R1
10177ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
10178ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
10179 type=router options:router-port=inside \
10180 -- lsp-set-addresses rp-inside router
10181
10182# Connect outside to R1 as distributed router gateway port on gw1+gw2
10183ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
10184
10185ovn-nbctl --id=@gc0 create Gateway_Chassis \
10186 name=outside_gw1 chassis_name=gw1 priority=20 -- \
10187 --id=@gc1 create Gateway_Chassis \
10188 name=outside_gw2 chassis_name=gw2 priority=10 -- \
10189 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10190
10191ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
10192 type=router options:router-port=outside \
10193 -- lsp-set-addresses rp-outside router
10194
10195# Create localnet port in outside
10196ovn-nbctl lsp-add outside ln-outside
10197ovn-nbctl lsp-set-addresses ln-outside unknown
10198ovn-nbctl lsp-set-type ln-outside localnet
10199ovn-nbctl lsp-set-options ln-outside network_name=phys
10200
10201# Allow some time for ovn-northd and ovn-controller to catch up.
10202# XXX This should be more systematic.
8e1d9349 10203ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 10204
10205echo "---------NB dump-----"
10206ovn-nbctl show
10207echo "---------------------"
10208ovn-nbctl list logical_router
10209echo "---------------------"
10210ovn-nbctl list logical_router_port
10211echo "---------------------"
10212
10213echo "---------SB dump-----"
10214ovn-sbctl list datapath_binding
10215echo "---------------------"
10216ovn-sbctl list port_binding
10217echo "---------------------"
10218ovn-sbctl dump-flows
10219echo "---------------------"
10220ovn-sbctl list chassis
10221ovn-sbctl list encap
10222echo "---------------------"
10223echo "------ Gateway_Chassis dump (SBDB) -------"
10224ovn-sbctl list Gateway_Chassis
10225echo "------ Port_Binding chassisredirect -------"
10226ovn-sbctl find Port_Binding type=chassisredirect
10227echo "-------------------------------------------"
10228
1be1e0e5
NS
10229# There should be one ha_chassis_group with the name "outside"
10230ha_chassi_grp_name=`ovn-sbctl --bare --columns name find \
10231ha_chassis_group name="outside"`
10232
10233AT_CHECK([test $ha_chassi_grp_name = outside])
10234
10235# There should be 2 ha_chassis rows in SB DB.
de779178
NS
10236AT_CHECK([ovn-sbctl list ha_chassis | grep chassis | \
10237grep -v chassis-name | awk '{print $3}' \
1be1e0e5
NS
10238| grep '-' | wc -l ], [0], [2
10239])
10240
10241ha_ch=`ovn-sbctl --bare --columns ha_chassis find ha_chassis_group`
10242# Trim the spaces.
10243ha_ch=`echo $ha_ch | sed 's/ //g'`
10244
10245ha_ch_list=''
10246for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
10247do
10248 ha_ch_list="$ha_ch_list $i"
10249done
10250
10251# Trim the spaces.
10252ha_ch_list=`echo $ha_ch_list | sed 's/ //g'`
10253
10254AT_CHECK([test "$ha_ch_list" = "$ha_ch"])
10255
3475695e
VA
10256for chassis in gw1 gw2 hv1 hv2; do
10257 as $chassis
10258 echo "------ $chassis dump ----------"
10259 ovs-ofctl show br-int
10260 ovs-ofctl dump-flows br-int
3475695e
VA
10261 echo "--------------------------"
10262done
20be3a72 10263bfd_dump() {
508b7f96 10264 for chassis in gw1 gw2 hv1 hv2; do
10265 as $chassis
10266 echo "------ $chassis dump (BFD)----"
10267 echo "BFD (from $chassis):"
10268 # dump BFD config and status to the other chassis
10269 for chassis2 in gw1 gw2 hv1 hv2; do
10270 if [[ "$chassis" != "$chassis2" ]]; then
10271 echo " -> $chassis2:"
10272 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
10273 fi
10274 done
10275 echo "--------------------------"
10276 done
10277}
10278
10279bfd_dump
1da17a0b 10280
10281hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
10282hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
10283hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
10284hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
10285
10286echo $hv1_gw1_ofport
10287echo $hv1_gw2_ofport
10288echo $hv2_gw1_ofport
10289echo $hv2_gw2_ofport
10290
10291echo "--- hv1 ---"
10292as hv1 ovs-ofctl dump-flows br-int table=32
10293
10294echo "--- hv2 ---"
10295as hv2 ovs-ofctl dump-flows br-int table=32
10296
508b7f96 10297gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
10298gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
10299
1be1e0e5
NS
10300OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10301grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
10302| wc -l], [0], [1
1da17a0b 10303])
10304
1be1e0e5
NS
10305OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10306grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
10307| wc -l], [0], [1
1da17a0b 10308])
10309
508b7f96 10310# make sure that flows for handling the outside router port reside on gw1
96080083 10311OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
1be1e0e5 10312grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 10313]])
96080083 10314OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
1be1e0e5 10315grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 10316]])
10317
10318# make sure ARP responder flows for outside router port reside on gw1 too
1be1e0e5
NS
10319OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
10320grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
508b7f96 10321]])
1be1e0e5 10322OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
508b7f96 10323]])
10324
508b7f96 10325# check that the chassis redirect port has been claimed by the gw1 chassis
1be1e0e5
NS
10326OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10327logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
508b7f96 10328]])
10329
1be1e0e5
NS
10330hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
10331hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
10332
10333exp_ref_ch_list=''
10334for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
10335do
10336 if test $i = $hv1_ch_uuid; then
10337 exp_ref_ch_list="${exp_ref_ch_list}$i"
10338 elif test $i = $hv2_ch_uuid; then
10339 exp_ref_ch_list="${exp_ref_ch_list}$i"
10340 fi
10341done
10342
10343OVS_WAIT_UNTIL(
10344 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10345 # Trim the spaces.
10346 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10347 test "$exp_ref_ch_list" = "$ref_ch_list"])
10348
508b7f96 10349
10350# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 10351
10352ovn-nbctl --id=@gc0 create Gateway_Chassis \
10353 name=outside_gw1 chassis_name=gw1 priority=10 -- \
10354 --id=@gc1 create Gateway_Chassis \
10355 name=outside_gw2 chassis_name=gw2 priority=20 -- \
10356 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10357
508b7f96 10358
1da17a0b 10359# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 10360ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 10361
508b7f96 10362# we make sure that the hypervisors noticed, and inverted the slave ports
1be1e0e5
NS
10363OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10364grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
10365| wc -l], [0], [1
1da17a0b 10366])
10367
1be1e0e5
NS
10368OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10369grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
10370| wc -l], [0], [1
1da17a0b 10371])
10372
508b7f96 10373# check that the chassis redirect port has been reclaimed by the gw2 chassis
1be1e0e5
NS
10374OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10375logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
508b7f96 10376]])
1da17a0b 10377
3475695e
VA
10378# check BFD enablement on tunnel ports from gw1 #########
10379as gw1
10380for chassis in gw2 hv1 hv2; do
10381 echo "checking gw1 -> $chassis"
10382 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10383 [[enable=true
10384]])
10385done
10386
10387
10388# check BFD enablement on tunnel ports from gw2 ##########
10389as gw2
10390for chassis in gw1 hv1 hv2; do
10391 echo "checking gw2 -> $chassis"
10392 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10393 [[enable=true
10394]])
10395done
10396
10397# check BFD enablement on tunnel ports from hv1 ###########
10398as hv1
10399for chassis in gw1 gw2; do
10400 echo "checking hv1 -> $chassis"
10401 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10402 [[enable=true
10403]])
10404done
10405# make sure BFD is not enabled to hv2, we don't need it
10406AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
2d661a27 10407 [[
3475695e
VA
10408]])
10409
10410
10411# check BFD enablement on tunnel ports from hv2 ##########
10412as hv2
10413for chassis in gw1 gw2; do
10414 echo "checking hv2 -> $chassis"
10415 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10416 [[enable=true
10417]])
10418done
10419# make sure BFD is not enabled to hv1, we don't need it
10420AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
2d661a27 10421 [[
3475695e
VA
10422]])
10423
508b7f96 10424# make sure that flows for handling the outside router port reside on gw2 now
96080083 10425OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
1be1e0e5 10426grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 10427]])
96080083 10428OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
1be1e0e5 10429grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 10430]])
10431
10432# disconnect GW2 from the network, GW1 should take over
10433as gw2
10434port=${sandbox}_br-phys
10435as main ovs-vsctl del-port n1 $port
508b7f96 10436
10437bfd_dump
10438
10439# make sure that flows for handling the outside router port reside on gw2 now
96080083 10440OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
1be1e0e5 10441grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 10442]])
96080083 10443OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
1be1e0e5 10444grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 10445]])
10446
10447# check that the chassis redirect port has been reclaimed by the gw1 chassis
1be1e0e5
NS
10448OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10449logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
508b7f96 10450]])
10451
2d661a27
NS
10452ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
10453as gw2
10454for chassis in gw1 hv1 hv2; do
10455 echo "checking gw2 -> $chassis"
10456 OVS_WAIT_UNTIL([
10457 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10458 test "$bfd_cfg" = "enable=true min_rx=2000"
10459])
10460done
10461ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
10462for chassis in gw1 hv1 hv2; do
10463 echo "checking gw2 -> $chassis"
10464 OVS_WAIT_UNTIL([
10465 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10466 test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
10467])
10468done
10469ovn-nbctl remove NB_Global . options "bfd-min-rx"
10470ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
10471for chassis in gw1 hv1 hv2; do
10472 echo "checking gw2 -> $chassis"
10473 OVS_WAIT_UNTIL([
10474 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10475 test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
10476])
10477done
10478
1be1e0e5
NS
10479# Delete the inside1 vif. The ref_chassis in ha_chassis_group shouldn't have
10480# reference to hv1.
10481as hv1 ovs-vsctl del-port hv1-vif1
10482
10483OVS_WAIT_UNTIL(
10484 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10485 # Trim the spaces.
10486 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10487 test "$hv2_ch_uuid" = "$ref_ch_list"])
10488
10489# Delete the inside2 vif.
10490ovn-sbctl show
10491
10492echo "Deleting hv2-vif1"
10493as hv2 ovs-vsctl del-port hv2-vif1
10494
10495# ref_chassis of ha_chassis_group should be empty
10496OVS_WAIT_UNTIL(
10497 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10498 # Trim the spaces.
10499 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10500 exp_ref_ch_list=""
10501 test "$exp_ref_ch_list" = "$ref_ch_list"])
10502
10503# Delete the Gateway_Chassis for lrp - outside
10504ovn-nbctl clear Logical_Router_Port outside gateway_chassis
10505
10506# There shoud be no ha_chassis_group rows in SB DB.
10507OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis_group | wc -l`])
10508OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
10509
bddb73db
NS
10510ovn-nbctl remove NB_Global . options "bfd-min-rx"
10511ovn-nbctl remove NB_Global . options "bfd-min-tx"
10512ovn-nbctl remove NB_Global . options "bfd-mult"
10513
10514# Now test with HA chassis group instead of Gateway chassis in NB DB
10515ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
10516
10517ovn-nbctl list ha_chassis_group
10518ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1
10519hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
10520ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw1 30
10521ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 20
10522
10523# ovn-northd should not create HA chassis group and HA chassis rows
10524# unless the HA chassis group in OVN NB DB is associated to
10525# a logical router port.
10526OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
10527
10528# Associate hagrp1 to outside logical router port
10529ovn-nbctl set Logical_Router_Port outside ha_chassis_group=$hagrp1_uuid
10530
10531OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns _uuid \
10532find ha_chassis_group | wc -l`])
10533
de779178
NS
10534OVS_WAIT_UNTIL([test 2 = `ovn-sbctl list ha_chassis | grep chassis | \
10535grep -v chassis-name | wc -l`])
bddb73db
NS
10536
10537OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10538grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
10539| wc -l], [0], [1
10540])
10541
10542OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10543grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
10544| wc -l], [0], [1
10545])
10546
10547# make sure that flows for handling the outside router port reside on gw1
10548OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10549grep 00:00:02:01:02:04 | wc -l], [0], [[1
10550]])
10551OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10552grep 00:00:02:01:02:04 | wc -l], [0], [[0
10553]])
10554
10555# make sure ARP responder flows for outside router port reside on gw1 too
10556OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
10557grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
10558]])
10559OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
10560]])
10561
10562# check that the chassis redirect port has been claimed by the gw1 chassis
10563OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10564logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10565]])
10566
10567# Re add the ovs ports.
10568for i in 1 2; do
10569 as hv$i
10570 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10571 set interface hv$i-vif1 external-ids:iface-id=inside$i \
10572 options:tx_pcap=hv$i/vif1-tx.pcap \
10573 options:rxq_pcap=hv$i/vif1-rx.pcap \
10574 ofport-request=1
10575done
10576
10577hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
10578hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
10579
10580exp_ref_ch_list=''
10581for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
10582do
10583 if test $i = $hv1_ch_uuid; then
10584 exp_ref_ch_list="${exp_ref_ch_list}$i"
10585 elif test $i = $hv2_ch_uuid; then
10586 exp_ref_ch_list="${exp_ref_ch_list}$i"
10587 fi
10588done
10589
10590OVS_WAIT_UNTIL(
10591 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10592 # Trim the spaces.
10593 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10594 test "$exp_ref_ch_list" = "$ref_ch_list"])
10595
10596# Increase the priority of gw2
10597ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 40
10598
10599OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10600grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
10601| wc -l], [0], [1
10602])
10603
10604OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10605grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
10606| wc -l], [0], [1
10607])
10608
10609# check that the chassis redirect port has been reclaimed by the gw2 chassis
10610OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10611logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
10612]])
10613
10614# check BFD enablement on tunnel ports from gw1 #########
10615as gw1
10616for chassis in gw2 hv1 hv2; do
10617 echo "checking gw1 -> $chassis"
10618 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10619 [[enable=true
10620]])
10621done
10622
10623# check BFD enablement on tunnel ports from gw2 ##########
10624as gw2
10625for chassis in gw1 hv1 hv2; do
10626 echo "checking gw2 -> $chassis"
10627 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10628 [[enable=true
10629]])
10630done
10631
10632# check BFD enablement on tunnel ports from hv1 ###########
10633as hv1
10634for chassis in gw1 gw2; do
10635 echo "checking hv1 -> $chassis"
10636 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10637 [[enable=true
10638]])
10639done
10640# make sure BFD is not enabled to hv2, we don't need it
10641AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
10642 [[
10643]])
10644
10645# check BFD enablement on tunnel ports from hv2 ##########
10646as hv2
10647for chassis in gw1 gw2; do
10648 echo "checking hv2 -> $chassis"
10649 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10650 [[enable=true
10651]])
10652done
10653# make sure BFD is not enabled to hv1, we don't need it
10654AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
10655 [[
10656]])
10657
10658# make sure that flows for handling the outside router port reside on gw2 now
10659OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10660grep 00:00:02:01:02:04 | wc -l], [0], [[1
10661]])
10662OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10663grep 00:00:02:01:02:04 | wc -l], [0], [[0
10664]])
10665
10666# disconnect GW2 from the network, GW1 should take over
10667as gw2
10668port=${sandbox}_br-phys
10669as main ovs-vsctl del-port n1 $port
10670
10671bfd_dump
10672
10673# make sure that flows for handling the outside router port reside on gw2 now
10674OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10675grep 00:00:02:01:02:04 | wc -l], [0], [[1
10676]])
10677OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10678grep 00:00:02:01:02:04 | wc -l], [0], [[0
10679]])
10680
10681# check that the chassis redirect port has been reclaimed by the gw1 chassis
10682OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10683logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10684]])
10685
1da17a0b 10686OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
10687
10688AT_CLEANUP
acfc41ff
VAK
10689
10690AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
10691AT_SKIP_IF([test $HAVE_PYTHON = no])
10692ovn_start
10693ovn-nbctl ls-add ls0
10694ovn-nbctl ls-add ls1
10695ovn-nbctl create Logical_Router name=lr0
10696ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
10697
10698ovn-nbctl --id=@gc0 create Gateway_Chassis \
10699 name=outside_gw1 chassis_name=hv2 priority=10 -- \
10700 --id=@gc1 create Gateway_Chassis \
10701 name=outside_gw2 chassis_name=hv3 priority=1 -- \
10702 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
10703
10704ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
10705 type=router options:router-port=lrp0 addresses="router"
10706ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
10707ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
10708 type=router options:router-port=lrp1 addresses="router"
10709
10710# Add NAT rules
10711AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
10712
10713net_add n1
10714sim_add hv1
10715as hv1
10716ovs-vsctl add-br br-phys
10717ovn_attach n1 br-phys 192.168.0.1
10718AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10719AT_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])
10720
10721sim_add hv2
10722as hv2
10723ovs-vsctl add-br br-phys
10724ovn_attach n1 br-phys 192.168.0.2
10725AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10726
10727sim_add hv3
10728as hv3
10729ovs-vsctl add-br br-phys
10730ovn_attach n1 br-phys 192.168.0.3
10731AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10732
10733# Create a localnet port.
10734AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
10735AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
10736AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
10737AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
10738
10739# wait for earlier changes to take effect
6c8d3d69 10740AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
acfc41ff
VAK
10741
10742reset_pcap_file() {
10743 local iface=$1
10744 local pcap_file=$2
10745 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10746options:rxq_pcap=dummy-rx.pcap
10747 rm -f ${pcap_file}*.pcap
10748 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10749options:rxq_pcap=${pcap_file}-rx.pcap
10750}
10751
10752as hv1 reset_pcap_file snoopvif hv1/snoopvif
10753as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10754as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10755# add nat-addresses option
6c8d3d69 10756ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
acfc41ff
VAK
10757
10758# Wait for packets to be received through hv2.
10759OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10760trim_zeros() {
10761 sed 's/\(00\)\{1,\}$//'
10762}
10763
2db7bb2c 10764only_broadcast_from_lrp1() {
10765 grep "fffffffffffff00000000001"
10766}
10767
acfc41ff 10768garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 10769echo $garp > expout
10770
10771$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
10772echo "packets on hv1-snoopvif:"
10773cat hv1_snoop_tx
10774AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 10775$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
10776echo "packets on hv2 br-phys tx"
10777cat hv2_br_phys_tx
10778AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 10779$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
10780echo "packets on hv3 br-phys tx"
10781cat hv3_br_phys_tx
10782AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
10783
10784
10785# at this point, we invert the priority of the gw chassis between hv2 and hv3
10786
10787ovn-nbctl --wait=hv \
10788 --id=@gc0 create Gateway_Chassis \
10789 name=outside_gw1 chassis_name=hv2 priority=1 -- \
10790 --id=@gc1 create Gateway_Chassis \
10791 name=outside_gw2 chassis_name=hv3 priority=10 -- \
10792 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
10793
10794
10795as hv1 reset_pcap_file snoopvif hv1/snoopvif
10796as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10797as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10798
10799# Wait for packets to be received.
10800OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10801trim_zeros() {
10802 sed 's/\(00\)\{1,\}$//'
10803}
10804
2db7bb2c 10805$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 10806AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 10807$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 10808AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 10809$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 10810AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
10811
10812# change localnet port tag.
10813AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
10814
10815# wait for earlier changes to take effect
d65586b6
NS
10816OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-ofctl dump-flows br-int table=65 | \
10817grep "actions=mod_vlan_vid:2014" | wc -l`
10818])
10819
10820OVS_WAIT_UNTIL([test 1 = `as hv3 ovs-ofctl dump-flows br-int table=65 | \
10821grep "actions=mod_vlan_vid:2014" | wc -l`
10822])
03b85a58
GL
10823
10824# update nat-addresses option
d65586b6
NS
10825ovn-nbctl --wait=hv clear logical_switch_port lrp0-rp options
10826
10827#Wait until the Port_Binding.nat_addresses is cleared.
10828OVS_WAIT_UNTIL([test 0 = `ovn-sbctl --bare --columns nat_addresses find port_binding \
10829logical_port=lrp0-rp | grep is_chassis | wc -l`])
03b85a58
GL
10830
10831as hv1 reset_pcap_file snoopvif hv1/snoopvif
10832as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10833as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10834
d65586b6
NS
10835ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
10836
10837#Wait until the Port_Binding.nat_addresses is set.
10838OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns nat_addresses find port_binding \
10839logical_port=lrp0-rp | grep is_chassis | wc -l`])
10840
03b85a58
GL
10841# Wait for packets to be received.
10842OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10843trim_zeros() {
10844 sed 's/\(00\)\{1,\}$//'
10845}
10846
10847garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
10848echo $garp > expout
10849
10850$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
10851AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
10852$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10853AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
10854$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10855AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
10856
acfc41ff
VAK
10857OVN_CLEANUP([hv1],[hv2],[hv3])
10858
10859AT_CLEANUP
79371ff5 10860
10861AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
10862AT_SKIP_IF([test $HAVE_PYTHON = no])
10863ovn_start
10864
10865net_add n1
10866
10867# create two gateways with external network connectivity
10868for i in 1 2; do
10869 sim_add gw$i
10870 as gw$i
10871 ovs-vsctl add-br br-phys
10872 ovn_attach n1 br-phys 192.168.0.$i
10873 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10874done
10875
10876ovn-nbctl ls-add inside
10877ovn-nbctl ls-add outside
10878
10879# create one hypervisors with a vif port the internal network
10880sim_add hv1
10881as hv1
10882ovs-vsctl add-br br-phys
10883ovn_attach n1 br-phys 192.168.0.11
10884ovs-vsctl -- add-port br-int hv1-vif1 -- \
10885 set interface hv1-vif1 external-ids:iface-id=inside1 \
10886 options:tx_pcap=hv1/vif1-tx.pcap \
10887 options:rxq_pcap=hv1/vif1-rx.pcap \
10888 ofport-request=1
10889
10890ovn-nbctl lsp-add inside inside1 \
10891 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
10892
10893
74868f2c 10894OVN_POPULATE_ARP
79371ff5 10895
10896ovn-nbctl create Logical_Router name=R1
10897
10898# Connect inside to R1
10899ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
10900ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
10901 type=router options:router-port=inside \
10902 -- lsp-set-addresses rp-inside router
10903
10904# Connect outside to R1 as distributed router gateway port on gw1+gw2
10905ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
10906
10907ovn-nbctl --id=@gc0 create Gateway_Chassis \
10908 name=outside_gw1 chassis_name=gw1 priority=20 -- \
10909 --id=@gc1 create Gateway_Chassis \
10910 name=outside_gw2 chassis_name=gw2 priority=10 -- \
10911 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10912
10913ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
10914 type=router options:router-port=outside \
10915 -- lsp-set-addresses rp-outside router
10916
10917# Create localnet port in outside
10918ovn-nbctl lsp-add outside ln-outside
10919ovn-nbctl lsp-set-addresses ln-outside unknown
10920ovn-nbctl lsp-set-type ln-outside localnet
10921ovn-nbctl lsp-set-options ln-outside network_name=phys
10922
10923# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 10924ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 10925
10926# currently when ovn-controller is restarted, the old entry is deleted
10927# and a new one is created, which leaves the Gateway_Chassis with
10928# an empty chassis for a while. NOTE: restarting ovn-controller in tests
10929# doesn't have the same effect because "name" is conserved, and the
10930# Chassis entry is not replaced.
10931
3a0c5805 10932> gw1/ovn-controller.log
325b2b1a 10933
79371ff5 10934gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
10935ovn-sbctl destroy Chassis $gw2_chassis
10936
1be1e0e5 10937OVS_WAIT_UNTIL([test 0 = `grep -c "Releasing lport" gw1/ovn-controller.log`])
79371ff5 10938
10939OVN_CLEANUP([gw1],[gw2],[hv1])
10940
10941AT_CLEANUP
63d91afa 10942
b1a3a6a4
NS
10943AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
10944AT_KEYWORDS([ovn-nd_ns for unknown mac])
10945AT_SKIP_IF([test $HAVE_PYTHON = no])
10946ovn_start
10947
10948ovn-nbctl ls-add sw0_ip6
10949ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
10950ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
10951"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
10952
10953ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
10954"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
10955
10956ovn-nbctl lr-add lr0_ip6
847dc1c2 10957ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
10958ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
10959ovn-nbctl lsp-set-type lrp0_ip6-attachment router
bec7c641 10960ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
b1a3a6a4
NS
10961ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
10962ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
10963
10964ovn-nbctl ls-add public
10965ovn-nbctl lsp-add public ln-public
10966ovn-nbctl lsp-set-addresses ln-public unknown
10967ovn-nbctl lsp-set-type ln-public localnet
10968ovn-nbctl lsp-set-options ln-public network_name=phys
10969
10970ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
109712001:db8:1:0:200:02ff:fe01:0204/64 \
10972-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
10973
250ed434
NS
10974#install static route
10975ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
10976ip_prefix="\:\:/0" nexthop="2001\:db8\:1\:0\:200\:02ff\:fe01\:1305" \
10977-- add Logical_Router lr0_ip6 static_routes @lrt
b1a3a6a4
NS
10978
10979ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
10980rp-ip6_public type=router options:router-port=ip6_public \
10981-- lsp-set-addresses rp-ip6_public router
10982
10983net_add n1
10984sim_add hv1
10985as hv1
10986ovs-vsctl add-br br-phys
10987ovn_attach n1 br-phys 192.168.0.2
10988
10989ovs-vsctl -- add-port br-int hv1-vif1 -- \
10990 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
10991 options:tx_pcap=hv1/vif1-tx.pcap \
10992 options:rxq_pcap=hv1/vif1-rx.pcap \
10993 ofport-request=1
10994ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10995
86c9d79a 10996OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
bec7c641
NS
10997
10998# There should be 2 Neighbor Advertisement flows for the router port
10999# aef0:: ip address in logical switch pipeline with action nd_na_router.
11000AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
11001grep "nd_na_router" | wc -l], [0], [2
11002])
11003
11004# There should be 4 Neighbor Advertisement flows with action nd_na_router
11005# in the router pipeline for the router lr0_ip6.
11006AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
11007wc -l], [0], [4
11008])
11009
86c9d79a
NS
11010cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
11011
11012# There is only one chassis.
11013chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
11014OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
b1a3a6a4
NS
11015
11016trim_zeros() {
11017 sed 's/\(00\)\{1,\}$//'
11018}
11019
250ed434
NS
11020reset_pcap_file() {
11021 local iface=$1
11022 local pcap_file=$2
11023 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11024options:rxq_pcap=dummy-rx.pcap
11025 rm -f ${pcap_file}*.pcap
11026 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11027options:rxq_pcap=${pcap_file}-rx.pcap
11028}
11029
b1a3a6a4
NS
11030# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
11031# addresses. ovn-controller should generate an IPv6 NS request for IPv6
11032# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
11033# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11034# This function sends ipv6 packet
11035test_ipv6() {
250ed434
NS
11036 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11037 local dst_mcast_mac=$6 mcast_node_ip=$7 nd_target=$8
b1a3a6a4
NS
11038
11039 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
11040 packet=${packet}8000000000000000
b1a3a6a4 11041
b1a3a6a4 11042 src_mac=000002010204
250ed434
NS
11043 expected_packet=${dst_mcast_mac}${src_mac}86dd6000000000203aff${src_ip}
11044 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000
11045 expected_packet=${expected_packet}${nd_target}0101${src_mac}
b1a3a6a4
NS
11046
11047 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
250ed434 11048 rm -f ipv6_ns.expected
b1a3a6a4
NS
11049 echo $expected_packet >> ipv6_ns.expected
11050}
11051
11052src_mac=506400000002
11053dst_mac=00000000af01
11054src_ip=aef0000000000000526400fffe000002
250ed434
NS
11055dst_ip=20010db800010000020002fffe010205
11056dst_mcast_mac=3333ff010205
11057mcast_node_ip=ff0200000000000000000001ff010205
11058nd_target=20010db800010000020002fffe010205
b1a3a6a4
NS
11059# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
11060# should be received by the ports attached to br-phys.
250ed434
NS
11061test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
11062$mcast_node_ip $nd_target
11063
11064OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
11065OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
11066
11067$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
11068trim_zeros > 1.packets
11069$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
11070trim_zeros > 2.packets
11071
11072cat ipv6_ns.expected | cut -c -112 > expout
11073AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
11074AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
11075
11076# Skipping the ICMPv6 checksum
11077cat ipv6_ns.expected | cut -c 117- > expout
11078AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
11079AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
11080
11081# Now send a packet with destination ip other than
11082# 2001:db8:1:0:200:02ff:fe01:0204/64 prefix.
11083reset_pcap_file br-phys_n1 hv1/br-phys_n1
11084reset_pcap_file br-phys hv1/br-phys
11085
11086src_mac=506400000002
11087dst_mac=00000000af01
11088src_ip=aef0000000000000526400fffe000002
11089dst_ip=20020ab8000100000200020000020306
11090# multicast mac of the nexthop IP - 2001:db8:1:0:200:02ff:fe01:1305
11091dst_mcast_mac=3333ff011305
11092mcast_node_ip=ff0200000000000000000001ff011305
11093nd_target=20010db800010000020002fffe011305
11094test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
11095$mcast_node_ip $nd_target
b1a3a6a4 11096
86c9d79a
NS
11097OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
11098OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
11099
b1a3a6a4
NS
11100$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
11101trim_zeros > 1.packets
11102$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
11103trim_zeros > 2.packets
11104
11105cat ipv6_ns.expected | cut -c -112 > expout
11106AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
11107AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
11108
11109# Skipping the ICMPv6 checksum
11110cat ipv6_ns.expected | cut -c 117- > expout
11111AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
11112AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
11113
11114OVN_CLEANUP([hv1])
11115
11116AT_CLEANUP
11117
63d91afa
LR
11118AT_SETUP([ovn -- options:requested-chassis for logical port])
11119ovn_start
11120
11121net_add n1
11122
11123ovn-nbctl ls-add ls0
11124ovn-nbctl lsp-add ls0 lsp0
11125
11126# create two hypervisors, each with one vif port
11127sim_add hv1
11128as hv1
11129ovs-vsctl add-br br-phys
11130ovn_attach n1 br-phys 192.168.0.11
99cc5c92
NS
11131ovs-vsctl -- add-port br-int hv1-vif0 -- \
11132set Interface hv1-vif0 ofport-request=1
63d91afa
LR
11133
11134sim_add hv2
11135as hv2
11136ovs-vsctl add-br br-phys
11137ovn_attach n1 br-phys 192.168.0.12
99cc5c92
NS
11138ovs-vsctl -- add-port br-int hv2-vif0 -- \
11139set Interface hv2-vif0 ofport-request=1
63d91afa
LR
11140
11141# Allow only chassis hv1 to bind logical port lsp0.
11142ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
11143
11144# Allow some time for ovn-northd and ovn-controller to catch up.
11145ovn-nbctl --wait=hv --timeout=3 sync
11146
11147# Retrieve hv1 and hv2 chassis UUIDs from southbound database
2aa57f08
HZ
11148ovn-sbctl wait-until chassis hv1
11149ovn-sbctl wait-until chassis hv2
63d91afa
LR
11150hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
11151hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
11152
11153# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
11154echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
11155as hv2
11156ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
11157
11158OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
11159AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
11160
99cc5c92
NS
11161# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
11162AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11163AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11164
11165# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
63d91afa
LR
11166echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
11167as hv1
11168ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
11169
11170OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
2aa57f08 11171AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
63d91afa 11172
99cc5c92
NS
11173# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
11174as hv1 ovs-ofctl dump-flows br-int
11175AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11176AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11177
11178# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
63d91afa
LR
11179# the requested chassis for lsp0 is changed from hv1 to hv2.
11180echo "verifying that lsp0 binding moves when requested-chassis is changed"
11181
11182ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
11183OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
2aa57f08 11184OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
63d91afa 11185
99cc5c92
NS
11186# (6) Chassis hv2 should add flows and hv1 should not.
11187AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11188AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11189
11190AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11191AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11192
63d91afa
LR
11193OVN_CLEANUP([hv1],[hv2])
11194
11195AT_CLEANUP
bd32425f
RB
11196
11197AT_SETUP([ovn -- options:requested-chassis with hostname])
11198
11199ovn_start
11200
11201ovn-nbctl ls-add ls0
11202ovn-nbctl lsp-add ls0 lsp0
11203
11204net_add n1
11205sim_add hv1
11206as hv1
11207ovs-vsctl add-br br-phys
11208ovn_attach n1 br-phys 192.168.0.11
99cc5c92 11209ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
bd32425f 11210
362ab40a 11211ovn-sbctl wait-until chassis hv1
bd32425f
RB
11212hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
11213echo "hv1_hostname=${hv1_hostname}"
11214ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
11215as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
11216
11217hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
11218echo "hv1_uuid=${hv1_uuid}"
11219OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
11220AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
99cc5c92
NS
11221AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11222AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
bd32425f
RB
11223
11224ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
11225OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
11226ovn-nbctl --wait=hv --timeout=3 sync
11227AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
99cc5c92
NS
11228AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11229AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
bd32425f
RB
11230
11231OVN_CLEANUP([hv1])
11232
11233AT_CLEANUP
4446661a
MM
11234
11235AT_SETUP([ovn -- IPv6 periodic RA])
11236ovn_start
11237
11238# This test sets up two hypervisors.
11239# hv1 and hv2 run ovn-controllers, and
11240# each has a VIF connected to the same
11241# logical switch in OVN. The logical
11242# switch is connected to a logical
11243# router port that is configured to send
11244# periodic router advertisements.
11245#
11246# The reason for having two ovn-controller
11247# hypervisors is to ensure that the
11248# periodic RAs being sent by each ovn-controller
11249# are kept to their local hypervisors. If the
11250# packets are not kept local, then each port
11251# will receive too many RAs.
11252
11253net_add n1
11254sim_add hv1
11255sim_add hv2
11256as hv1
11257ovs-vsctl add-br br-phys
11258ovn_attach n1 br-phys 192.168.0.2
11259as hv2
11260ovs-vsctl add-br br-phys
11261ovn_attach n1 br-phys 192.168.0.3
11262
11263ovn-nbctl lr-add ro
1ea1b0d0 11264ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
4446661a
MM
11265
11266ovn-nbctl ls-add sw
11267ovn-nbctl lsp-add sw sw-ro
11268ovn-nbctl lsp-set-type sw-ro router
11269ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
11270ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
11271ovn-nbctl lsp-add sw sw-p1
11272ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
11273ovn-nbctl lsp-add sw sw-p2
11274ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
11275
11276ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
11277ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
11278ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
11279ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
11280
86c9d79a
NS
11281for i in 1 2 ; do
11282 as hv$i
11283 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
11284 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
11285 options:tx_pcap=hv$i/vif1-tx.pcap \
11286 options:rxq_pcap=hv$i/vif1-rx.pcap \
4446661a
MM
11287 ofport-request=1
11288done
11289
86c9d79a
NS
11290OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
11291OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
4446661a
MM
11292
11293reset_pcap_file() {
11294 local iface=$1
11295 local pcap_file=$2
11296 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11297options:rxq_pcap=dummy-rx.pcap
11298 rm -f ${pcap_file}*.pcap
11299 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11300options:rxq_pcap=${pcap_file}-rx.pcap
11301
11302}
11303
11304construct_expected_ra() {
11305 local src_mac=000000000001
11306 local dst_mac=333300000001
11307 local src_addr=fe80000000000000020000fffe000001
11308 local dst_addr=ff020000000000000000000000000001
11309
11310 local mtu=$1
11311 local ra_mo=$2
11312 local ra_prefix_la=$3
11313
11314 local slla=0101${src_mac}
11315 local mtu_opt=""
11316 if test $mtu != 0; then
11317 mtu_opt=05010000${mtu}
11318 fi
11319 shift 3
11320
11321 local prefix=""
11322 while [[ $# -gt 0 ]] ; do
11323 local size=$1
11324 local net=$2
11325 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
11326 shift 2
11327 done
11328
895ceaf7 11329 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
4446661a
MM
11330 local icmp=8600XXXX${ra}
11331
11332 local ip_len=$(expr ${#icmp} / 2)
1ea1b0d0 11333 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
4446661a
MM
11334
11335 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
11336 local eth=${dst_mac}${src_mac}86dd${ip}
11337 local packet=${eth}
11338 echo $packet >> expected
11339}
11340
11341ra_test() {
11342 construct_expected_ra $@
11343
11344 for i in hv1 hv2 ; do
11345 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
11346
11347 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
11348
11349 cat expected | cut -c -112 > expout
11350 AT_CHECK([cat packets | cut -c -112], [0], [expout])
11351
11352 # Skip ICMPv6 checksum.
11353 cat expected | cut -c 117- > expout
11354 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
11355
11356 rm -f packets
11357 as $i reset_pcap_file $i-vif1 $i/vif1
11358 done
11359
11360 rm -f expected
11361}
11362
11363# Baseline test with no MTU
11364ra_test 0 00 c0 40 aef00000000000000000000000000000
11365
11366# Now make sure an MTU option makes it
11367ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
11368ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
11369
11370# Now test for multiple network prefixes
11371ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
11372ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11373
11374# Test a different address mode now
11375ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
11376ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11377
11378# And the other address mode
11379ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
c7ea79f5 11380ra_test 000005dc 40 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
4446661a
MM
11381
11382OVN_CLEANUP([hv1],[hv2])
11383AT_CLEANUP
4826add0
LB
11384
11385AT_SETUP([ovn -- ACL reject rule test])
11386AT_KEYWORDS([acl-reject])
11387AT_SKIP_IF([test $HAVE_PYTHON = no])
11388ovn_start
11389
11390# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
11391#
11392# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
11393# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
11394# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
11395# unreachable frame generated from ACL rule hit
11396#
11397# INPORT is a lport number, e.g. 11 for vif11.
11398# HV is a hypervisor number
11399# ETH_SRC and ETH_DST are each 12 hex digits.
11400# IPV4_SRC and IPV4_DST are each 8 hex digits.
11401# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
11402test_ip_packet() {
11403 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
11404 local exp_ip_chksum=$8 exp_icmp_chksum=$9
11405 shift 9
11406
11407 local ip_ttl=ff
11408 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
11409
11410 local reply_icmp_ttl=ff
11411 local icmp_type_code_response=0301
11412 local icmp_data=00000000
11413 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
11414 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
11415 echo $reply >> vif$inport.expected
11416
11417 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11418}
11419
c319fabc
LB
11420# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
11421#
11422# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
11423# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
11424# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
11425test_ipv6_packet() {
11426 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
11427 shift 7
11428
11429 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
11430 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
11431
11432 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
11433 echo $reply >> vif$inport.expected
11434
11435 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11436}
11437
c20ab6aa
LB
11438# 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
11439#
11440# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
11441# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
11442# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
11443#
11444# INPORT is an lport number, e.g. 11 for vif11.
11445# HV is an hypervisor number
11446# ETH_SRC and ETH_DST are each 12 hex digits.
11447# IPV4_SRC and IPV4_DST are each 8 hex digits.
11448# TCP_SPORT and TCP_DPORT are 4 hex digits.
11449# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
11450test_tcp_syn_packet() {
11451 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
11452 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
11453 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
11454 shift 12
11455
11456 local ip_ttl=ff
11457 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
11458
11459 local tcp_rst_ttl=ff
11460 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
11461 echo $reply >> vif$inport.expected
11462
11463 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11464}
11465
4826add0
LB
11466# Create hypervisors hv[123].
11467# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
11468# Add all of the vifs to a single logical switch sw0.
11469
11470net_add n1
11471ovn-nbctl ls-add sw0
11472for i in 1 2 3; do
11473 sim_add hv$i
11474 as hv$i
11475 ovs-vsctl add-br br-phys
11476 ovn_attach n1 br-phys 192.168.0.$i
11477
11478 for j in 1 2 3; do
11479 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
11480 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
11481
11482 ovs-vsctl -- add-port br-int vif$i$j -- \
11483 set interface vif$i$j \
11484 external-ids:iface-id=sw0-p$i$j \
11485 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
11486 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
11487 ofport-request=$i$j
11488 done
11489done
11490
11491OVN_POPULATE_ARP
11492# allow some time for ovn-northd and ovn-controller to catch up.
11493sleep 1
11494
11495ip_to_hex() {
11496 printf "%02x%02x%02x%02x" "$@"
11497}
11498
11499for i in 1 2 3; do
11500 : > vif${i}1.expected
11501done
11502
11503ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
11504ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
11505ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
732965bc
HZ
11506
11507# Allow some time for ovn-northd and ovn-controller to catch up.
11508ovn-nbctl --timeout=3 --wait=hv sync
4826add0
LB
11509
11510test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
11511test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
11512test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
11513
c319fabc
LB
11514test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
11515
c20ab6aa
LB
11516test_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
11517test_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
11518test_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
11519
4826add0
LB
11520for i in 1 2 3; do
11521 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
11522done
11523
11524OVN_CLEANUP([hv1], [hv2], [hv3])
11525AT_CLEANUP
689829d5
HZ
11526
11527AT_SETUP([ovn -- Port Groups])
11528AT_KEYWORDS([ovnpg])
11529AT_SKIP_IF([test $HAVE_PYTHON = no])
11530ovn_start
11531
11532# Logical network:
11533#
11534# Three logical switches ls1, ls2, ls3.
11535# One logical router lr0 connected to ls[123],
11536# with nine subnets, three per logical switch:
11537#
11538# lrp11 on ls1 for subnet 192.168.11.0/24
11539# lrp12 on ls1 for subnet 192.168.12.0/24
11540# lrp13 on ls1 for subnet 192.168.13.0/24
11541# ...
11542# lrp33 on ls3 for subnet 192.168.33.0/24
11543#
11544# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
11545# digits are the subnet and the last digit distinguishes the VIF.
11546#
11547# This test will create two port groups and uses them in ACL.
11548
11549get_lsp_uuid () {
11550 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
11551}
11552
11553pg1_ports=
11554pg2_ports=
11555for i in 1 2 3; do
11556 ovn-nbctl ls-add ls$i
11557 for j in 1 2 3; do
11558 for k in 1 2 3; do
11559 ovn-nbctl \
11560 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
11561 -- lsp-set-addresses lp$i$j$k \
11562 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
689829d5
HZ
11563 # logical ports lp[12]?1 belongs to port group pg1
11564 if test $i != 3 && test $k == 1; then
11565 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
11566 fi
11567 # logical ports lp[23]?2 belongs to port group pg2
11568 if test $i != 1 && test $k == 2; then
11569 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
11570 fi
11571 done
11572 done
11573done
11574
11575ovn-nbctl lr-add lr0
11576for i in 1 2 3; do
11577 for j in 1 2 3; do
11578 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
11579 ovn-nbctl \
11580 -- lsp-add ls$i lrp$i$j-attachment \
11581 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
11582 options:router-port=lrp$i$j \
11583 addresses='"00:00:00:00:ff:'$i$j'"'
11584 done
11585done
11586
11587ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
11588ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
11589
11590# create ACLs on all lswitches to drop traffic from pg2 to pg1
11591ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11592ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11593ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11594
11595# Physical network:
11596#
11597# Three hypervisors hv[123].
11598# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
11599# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
11600# lp?3[123] all on hv3.
11601
11602# Given the name of a logical port, prints the name of the hypervisor
11603# on which it is located.
11604vif_to_hv() {
11605 case $1 in dnl (
11606 ?11) echo 1 ;; dnl (
11607 ?12 | ?21 | ?22) echo 2 ;; dnl (
11608 ?13 | ?23 | ?3?) echo 3 ;;
11609 esac
11610}
11611
11612# Given the name of a logical port, prints the name of its logical router
11613# port, e.g. "vif_to_lrp 123" yields 12.
11614vif_to_lrp() {
11615 echo ${1%?}
11616}
11617
11618# Given the name of a logical port, prints the name of its logical
11619# switch, e.g. "vif_to_ls 123" yields 1.
11620vif_to_ls() {
11621 echo ${1%??}
11622}
11623
11624net_add n1
11625for i in 1 2 3; do
11626 sim_add hv$i
11627 as hv$i
11628 ovs-vsctl add-br br-phys
11629 ovn_attach n1 br-phys 192.168.0.$i
11630done
11631for i in 1 2 3; do
11632 for j in 1 2 3; do
11633 for k in 1 2 3; do
11634 hv=`vif_to_hv $i$j$k`
11635 as hv$hv ovs-vsctl \
11636 -- add-port br-int vif$i$j$k \
11637 -- set Interface vif$i$j$k \
11638 external-ids:iface-id=lp$i$j$k \
11639 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
11640 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
11641 ofport-request=$i$j$k
11642 done
11643 done
11644done
11645
11646# Pre-populate the hypervisors' ARP tables so that we don't lose any
11647# packets for ARP resolution (native tunneling doesn't queue packets
11648# for ARP resolution).
11649OVN_POPULATE_ARP
11650
11651# Allow some time for ovn-northd and ovn-controller to catch up.
11652# XXX This should be more systematic.
11653sleep 1
11654
11655# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11656#
11657# This shell function causes a packet to be received on INPORT. The packet's
11658# content has Ethernet destination DST and source SRC (each exactly 12 hex
11659# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
11660# more) list the VIFs on which the packet should be received. INPORT and the
11661# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
11662for i in 1 2 3; do
11663 for j in 1 2 3; do
11664 for k in 1 2 3; do
11665 : > $i$j$k.expected
11666 done
11667 done
11668done
11669test_ip() {
11670 # This packet has bad checksums but logical L3 routing doesn't check.
11671 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11672 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
11673 shift; shift; shift; shift; shift
11674 hv=hv`vif_to_hv $inport`
11675 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
11676 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
11677 in_ls=`vif_to_ls $inport`
11678 in_lrp=`vif_to_lrp $inport`
11679 for outport; do
11680 out_ls=`vif_to_ls $outport`
11681 if test $in_ls = $out_ls; then
11682 # Ports on the same logical switch receive exactly the same packet.
11683 echo $packet
11684 else
11685 # Routing decrements TTL and updates source and dest MAC
11686 # (and checksum).
11687 out_lrp=`vif_to_lrp $outport`
11688 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
11689 fi >> $outport.expected
11690 done
11691}
11692
11693as hv1 ovs-vsctl --columns=name,ofport list interface
11694as hv1 ovn-sbctl list port_binding
11695as hv1 ovn-sbctl list datapath_binding
11696as hv1 ovn-sbctl list port_group
11697as hv1 ovn-sbctl list address_set
11698as hv1 ovn-sbctl dump-flows
11699as hv1 ovs-ofctl dump-flows br-int
11700
11701# Send IP packets between all pairs of source and destination ports,
11702# packets matches ACL (pg2 to pg1) should be dropped
11703ip_to_hex() {
11704 printf "%02x%02x%02x%02x" "$@"
11705}
11706for is in 1 2 3; do
11707 for js in 1 2 3; do
11708 for ks in 1 2 3; do
11709 bcast=
11710 s=$is$js$ks
11711 smac=f00000000$s
11712 sip=`ip_to_hex 192 168 $is$js $ks`
11713 for id in 1 2 3; do
11714 for jd in 1 2 3; do
11715 for kd in 1 2 3; do
11716 d=$id$jd$kd
11717 dip=`ip_to_hex 192 168 $id$jd $kd`
11718 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
11719 if test $d != $s; then unicast=$d; else unicast=; fi
11720
11721 # packets matches ACL should be dropped
11722 if test $id != 3 && test $kd == 1; then
11723 if test $is != 1 && test $ks == 2; then
11724 unicast=
11725 fi
11726 fi
11727 test_ip $s $smac $dmac $sip $dip $unicast #1
11728 done
11729 done
11730 done
11731 done
11732 done
11733done
11734
11735# Allow some time for packet forwarding.
11736# XXX This can be improved.
11737sleep 1
11738
11739# Now check the packets actually received against the ones expected.
11740for i in 1 2 3; do
11741 for j in 1 2 3; do
11742 for k in 1 2 3; do
11743 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11744 [$i$j$k.expected])
11745 done
11746 done
11747done
11748
11749# Gracefully terminate daemons
11750OVN_CLEANUP([hv1], [hv2], [hv3])
11751AT_CLEANUP
1beb60af
HZ
11752
11753AT_SETUP([ovn -- ACLs on Port Groups])
11754AT_KEYWORDS([ovnpg_acl])
11755AT_SKIP_IF([test $HAVE_PYTHON = no])
11756ovn_start
11757
11758# Logical network:
11759#
11760# Three logical switches ls1, ls2, ls3.
11761# One logical router lr0 connected to ls[123],
11762# with nine subnets, three per logical switch:
11763#
11764# lrp11 on ls1 for subnet 192.168.11.0/24
11765# lrp12 on ls1 for subnet 192.168.12.0/24
11766# lrp13 on ls1 for subnet 192.168.13.0/24
11767# ...
11768# lrp33 on ls3 for subnet 192.168.33.0/24
11769#
11770# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
11771# digits are the subnet and the last digit distinguishes the VIF.
11772#
11773# This test will create two port groups and ACLs will be applied on them.
11774
11775get_lsp_uuid () {
11776 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
11777}
11778
11779pg1_ports=
11780pg2_ports=
11781for i in 1 2 3; do
11782 ovn-nbctl ls-add ls$i
11783 for j in 1 2 3; do
11784 for k in 1 2 3; do
11785 ovn-nbctl \
11786 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
11787 -- lsp-set-addresses lp$i$j$k \
11788 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
1beb60af
HZ
11789 # logical ports lp[12]?1 belongs to port group pg1
11790 if test $i != 3 && test $k == 1; then
11791 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
11792 fi
11793 # logical ports lp[23]?2 belongs to port group pg2
11794 if test $i != 1 && test $k == 2; then
11795 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
11796 fi
11797 done
11798 done
11799done
11800
11801ovn-nbctl lr-add lr0
11802for i in 1 2 3; do
11803 for j in 1 2 3; do
11804 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
11805 ovn-nbctl \
11806 -- lsp-add ls$i lrp$i$j-attachment \
11807 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
11808 options:router-port=lrp$i$j \
11809 addresses='"00:00:00:00:ff:'$i$j'"'
11810 done
11811done
11812
d87e0897 11813ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
1beb60af
HZ
11814ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
11815
11816# create ACLs on pg1 to drop traffic from pg2 to pg1
d87e0897
HZ
11817ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
11818ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
cdc9a84a 11819 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
1beb60af
HZ
11820
11821# Physical network:
11822#
11823# Three hypervisors hv[123].
11824# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
11825# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
11826# lp?3[123] all on hv3.
11827
11828# Given the name of a logical port, prints the name of the hypervisor
11829# on which it is located.
11830vif_to_hv() {
11831 case $1 in dnl (
11832 ?11) echo 1 ;; dnl (
11833 ?12 | ?21 | ?22) echo 2 ;; dnl (
11834 ?13 | ?23 | ?3?) echo 3 ;;
11835 esac
11836}
11837
11838# Given the name of a logical port, prints the name of its logical router
11839# port, e.g. "vif_to_lrp 123" yields 12.
11840vif_to_lrp() {
11841 echo ${1%?}
11842}
11843
11844# Given the name of a logical port, prints the name of its logical
11845# switch, e.g. "vif_to_ls 123" yields 1.
11846vif_to_ls() {
11847 echo ${1%??}
11848}
11849
11850net_add n1
11851for i in 1 2 3; do
11852 sim_add hv$i
11853 as hv$i
11854 ovs-vsctl add-br br-phys
11855 ovn_attach n1 br-phys 192.168.0.$i
11856done
11857for i in 1 2 3; do
11858 for j in 1 2 3; do
11859 for k in 1 2 3; do
11860 hv=`vif_to_hv $i$j$k`
11861 as hv$hv ovs-vsctl \
11862 -- add-port br-int vif$i$j$k \
11863 -- set Interface vif$i$j$k \
11864 external-ids:iface-id=lp$i$j$k \
11865 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
11866 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
11867 ofport-request=$i$j$k
11868 done
11869 done
11870done
11871
11872# Pre-populate the hypervisors' ARP tables so that we don't lose any
11873# packets for ARP resolution (native tunneling doesn't queue packets
11874# for ARP resolution).
11875OVN_POPULATE_ARP
11876
11877# Allow some time for ovn-northd and ovn-controller to catch up.
11878# XXX This should be more systematic.
11879sleep 1
11880
cdc9a84a
HZ
11881lsp_to_mac() {
11882 echo f0:00:00:00:0${1:0:1}:${1:1:2}
11883}
11884
11885lrp_to_mac() {
11886 echo 00:00:00:00:ff:$1
11887}
11888
11889# test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
1beb60af 11890#
cdc9a84a
HZ
11891# This shell function causes a ICMP packet to be received on INPORT.
11892# The OUTPORTs (zero or more) list the VIFs on which the packet should
11893# be received. INPORT and the OUTPORTs are specified as logical switch
11894# port numbers, e.g. 123 for vif123.
1beb60af
HZ
11895for i in 1 2 3; do
11896 for j in 1 2 3; do
11897 for k in 1 2 3; do
11898 : > $i$j$k.expected
11899 done
11900 done
11901done
cdc9a84a
HZ
11902
11903test_icmp() {
11904 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
11905 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
11906 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
11907 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
11908 icmp4.code==0"
11909 shift; shift; shift; shift; shift; shift
1beb60af 11910 hv=hv`vif_to_hv $inport`
cdc9a84a 11911 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
1beb60af
HZ
11912 in_ls=`vif_to_ls $inport`
11913 in_lrp=`vif_to_lrp $inport`
11914 for outport; do
11915 out_ls=`vif_to_ls $outport`
11916 if test $in_ls = $out_ls; then
11917 # Ports on the same logical switch receive exactly the same packet.
cdc9a84a 11918 echo $packet | ovstest test-ovn expr-to-packets
1beb60af
HZ
11919 else
11920 # Routing decrements TTL and updates source and dest MAC
11921 # (and checksum).
11922 out_lrp=`vif_to_lrp $outport`
cdc9a84a
HZ
11923 exp_smac=`lrp_to_mac $out_lrp`
11924 exp_dmac=`lsp_to_mac $outport`
11925 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
11926 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
11927 icmp4.type==$icmp_type && icmp4.code==0"
11928 echo $exp_packet | ovstest test-ovn expr-to-packets
11929
1beb60af
HZ
11930 fi >> $outport.expected
11931 done
11932}
11933
11934as hv1 ovs-vsctl --columns=name,ofport list interface
11935as hv1 ovn-sbctl list port_binding
11936as hv1 ovn-sbctl list datapath_binding
11937as hv1 ovn-sbctl list port_group
11938as hv1 ovn-sbctl list address_set
11939as hv1 ovn-sbctl dump-flows
11940as hv1 ovs-ofctl dump-flows br-int
11941
11942# Send IP packets between all pairs of source and destination ports,
11943# packets matches ACL1 but not ACL2 should be dropped
11944ip_to_hex() {
11945 printf "%02x%02x%02x%02x" "$@"
11946}
11947for is in 1 2 3; do
11948 for js in 1 2 3; do
11949 for ks in 1 2 3; do
11950 bcast=
11951 s=$is$js$ks
cdc9a84a
HZ
11952 slsp_mac=`lsp_to_mac $s`
11953 slrp_mac=`lrp_to_mac $is$js`
11954 sip=192.168.$is$js.$ks
1beb60af
HZ
11955 for id in 1 2 3; do
11956 for jd in 1 2 3; do
11957 for kd in 1 2 3; do
11958 d=$id$jd$kd
cdc9a84a
HZ
11959 dlsp_mac=`lsp_to_mac $d`
11960 dlrp_mac=`lrp_to_mac $id$jd`
11961 dip=192.168.$id$jd.$kd
11962 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
1beb60af
HZ
11963 if test $d != $s; then unicast=$d; else unicast=; fi
11964
11965 # packets matches ACL1 but not ACL2 should be dropped
11966 if test $id != 3 && test $kd == 1; then
11967 if test $is == 1 || test $ks != 2; then
11968 unicast=
11969 fi
11970 fi
cdc9a84a
HZ
11971 # icmp request (type = 8)
11972 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
11973
11974 # if packets are not dropped, test the return traffic (icmp echo)
11975 # to make sure stateful works, too.
11976 if test x$unicast != x; then
11977 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
11978 # icmp echo (type = 0)
11979 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
11980 fi
1beb60af
HZ
11981 done
11982 done
11983 done
11984 done
11985 done
11986done
11987
11988# Allow some time for packet forwarding.
11989# XXX This can be improved.
11990sleep 1
11991
11992# Now check the packets actually received against the ones expected.
11993for i in 1 2 3; do
11994 for j in 1 2 3; do
11995 for k in 1 2 3; do
11996 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11997 [$i$j$k.expected])
11998 done
11999 done
12000done
12001
12002# Gracefully terminate daemons
12003OVN_CLEANUP([hv1], [hv2], [hv3])
12004AT_CLEANUP
55b25947 12005
2342c266
JS
12006AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
12007ovn_start
12008
12009ovn-nbctl ls-add ls1
12010
12011ovn-nbctl lsp-add ls1 lp1
12012ovn-nbctl lsp-add ls1 lp2
12013ovn-nbctl lsp-add ls1 lp3
12014
12015ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
12016ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
12017ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
12018
12019ovn-nbctl create Port_Group name=pg1
12020ovn-nbctl create Port_Group name=pg2
12021
12022ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
12023ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
12024ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
12025ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
12026
12027ovn-nbctl --wait=sb sync
12028
12029dnl Check if port group address sets were populated with ports' addresses
12030AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12031 [0], [[["10.0.0.1", "10.0.0.2"]]
12032])
12033AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
12034 [0], [[["10.0.0.2", "10.0.0.3"]]
12035])
12036AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12037 [0], [[["2001:db8::1", "2001:db8::2"]]
12038])
12039AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
12040 [0], [[["2001:db8::2", "2001:db8::3"]]
12041])
12042
12043ovn-nbctl --wait=sb lsp-set-addresses lp1 \
12044 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
12045
12046dnl Check if updated address got propagated to the port group address sets
12047AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12048 [0], [[["10.0.0.11", "10.0.0.2"]]
12049])
12050AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12051 [0], [[["2001:db8::11", "2001:db8::2"]]
12052])
12053
12054AT_CLEANUP
12055
984c7d5e
JS
12056AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
12057ovn_start
12058
12059ovn-nbctl ls-add ls1
12060ovn-nbctl ls-add ls2
12061ovn-nbctl ls-add ls3
12062
12063ovn-nbctl set Logical_Switch ls1 \
12064 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
12065ovn-nbctl set Logical_Switch ls2 \
12066 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
12067ovn-nbctl set Logical_Switch ls3 \
12068 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
12069
12070ovn-nbctl lsp-add ls1 lp1
12071ovn-nbctl lsp-add ls2 lp2
12072ovn-nbctl lsp-add ls3 lp3
12073
12074ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
12075ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
12076ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
12077
12078ovn-nbctl create Port_Group name=pg1
12079ovn-nbctl create Port_Group name=pg2
12080
12081ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
12082ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
12083ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
12084ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
12085
12086ovn-nbctl --wait=sb sync
12087
12088dnl Check if port group address sets were populated with ports' addresses
12089AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12090 [0], [[["10.1.0.2", "10.2.0.2"]]
12091])
12092AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
12093 [0], [[["10.2.0.2", "10.3.0.2"]]
12094])
12095AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12096 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
12097])
12098AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
12099 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
12100])
12101
abf11558 12102ovn-nbctl --wait=sb set Logical_Switch ls1 \
984c7d5e
JS
12103 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
12104
12105dnl Check if updated address got propagated to the port group address sets
12106AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
451624fe 12107 [0], [[["10.11.0.2", "10.2.0.2"]]
984c7d5e
JS
12108])
12109AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
451624fe 12110 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
984c7d5e
JS
12111])
12112
12113AT_CLEANUP
12114
55b25947
NS
12115AT_SETUP([ovn -- ACL conjunction])
12116ovn_start
12117
12118ovn-nbctl ls-add ls1
12119
12120ovn-nbctl lsp-add ls1 ls1-lp1 \
12121-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
12122
12123ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
12124
12125ovn-nbctl lsp-add ls1 ls1-lp2 \
12126-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
12127
12128ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
12129
12130net_add n1
12131sim_add hv1
12132
12133as hv1
12134ovs-vsctl add-br br-phys
12135ovn_attach n1 br-phys 192.168.0.1
12136ovs-vsctl -- add-port br-int hv1-vif1 -- \
12137 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
12138 options:tx_pcap=hv1/vif1-tx.pcap \
12139 options:rxq_pcap=hv1/vif1-rx.pcap \
12140 ofport-request=1
12141
12142ovs-vsctl -- add-port br-int hv1-vif2 -- \
12143 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
12144 options:tx_pcap=hv1/vif2-tx.pcap \
12145 options:rxq_pcap=hv1/vif2-rx.pcap \
12146 ofport-request=2
12147
12148ovn-nbctl create Address_Set name=set1 \
12149addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
12150ovn-nbctl create Address_Set name=set2 \
12151addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
12152ovn-nbctl acl-add ls1 to-lport 1002 \
12153'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
12154ovn-nbctl acl-add ls1 to-lport 1001 \
12155'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
12156
12157# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
12158#
12159# This shell function causes an ip packet to be received on INPORT.
12160# The packet's content has Ethernet destination DST and source SRC
12161# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
12162# The OUTPORTs (zero or more) list the VIFs on which the packet should
12163# be received. INPORT and the OUTPORTs are specified as logical switch
12164# port numbers, e.g. 11 for vif11.
12165test_ip() {
12166 # This packet has bad checksums but logical L3 routing doesn't check.
12167 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
12168 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
12169${dst_ip}0035111100080000
12170 shift; shift; shift; shift; shift
12171 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
12172 for outport; do
12173 echo $packet >> $outport.expected
12174 done
12175}
12176
12177ip_to_hex() {
12178 printf "%02x%02x%02x%02x" "$@"
12179}
12180
12181reset_pcap_file() {
12182 local iface=$1
12183 local pcap_file=$2
12184 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
12185options:rxq_pcap=dummy-rx.pcap
12186 rm -f ${pcap_file}*.pcap
12187 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
12188options:rxq_pcap=${pcap_file}-rx.pcap
12189}
12190
12191
12192sip=`ip_to_hex 10 0 0 4`
12193dip=`ip_to_hex 10 0 0 6`
12194
12195test_ip 1 f00000000001 f00000000002 $sip $dip 2
12196
12197cat 2.expected > expout
12198$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
12199AT_CHECK([cat 2.packets], [0], [expout])
12200
12201# There should be total of 12 flows present with conjunction action and 2 flows
12202# with conj match. Eg.
12203# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
12204# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
12205# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
12206# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
12207# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
12208# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
12209# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
12210# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
12211# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
12212# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
12213# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
12214# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
12215# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
12216# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
12217
12218OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
12219grep conjunction | wc -l`])
12220OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
12221grep conj_id | wc -l`])
12222
12223as hv1 ovs-ofctl dump-flows br-int
12224
12225# Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
12226ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
12227ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
12228
12229reset_pcap_file hv1-vif2 hv1/vif2
12230
12231rm -f 2.packets
12232
12233sip=`ip_to_hex 10 0 0 4`
12234dip=`ip_to_hex 10 0 0 7`
12235
12236test_ip 1 f00000000001 f00000000002 $sip $dip
12237$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
12238AT_CHECK([cat 2.packets], [0], [])
12239
12240AT_CLEANUP
0e2751ed
LB
12241
12242AT_SETUP([ovn -- TTL exceeded])
12243AT_KEYWORDS([ttl-exceeded])
12244AT_SKIP_IF([test $HAVE_PYTHON = no])
12245ovn_start
12246
12247# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
12248#
12249# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
12250# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
12251# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
12252# generated by OVN logical router
12253#
12254# INPORT is a lport number, e.g. 11 for vif11.
12255# HV is a hypervisor number
12256# ETH_SRC and ETH_DST are each 12 hex digits.
12257# IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
12258# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
12259test_ip_packet() {
12260 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
12261 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
12262 shift 10
12263
12264 local ip_ttl=01
12265 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
12266
12267 local reply_icmp_ttl=fe
12268 local icmp_type_code_response=0b00
12269 local icmp_data=00000000
12270 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
12271 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
12272 echo $reply >> vif$inport.expected
12273
12274 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12275}
12276
e6a84e1e
LB
12277# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
12278#
12279# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
12280# packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
12281# IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
12282# packet sent by OVN logical router
12283test_ip6_packet() {
12284 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
12285 shift 8
12286
12287 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
12288 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
12289
12290 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
12291 echo $reply >> vif$inport.expected
12292
12293 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12294}
12295
0e2751ed
LB
12296ip_to_hex() {
12297 printf "%02x%02x%02x%02x" "$@"
12298}
12299
12300for i in 1 2; do
12301 net_add n$i
12302 ovn-nbctl ls-add sw$i
12303
12304 sim_add hv$i
12305 as hv$i
12306 ovs-vsctl add-br br-phys
12307 ovn_attach n$i br-phys 192.168.$i.1
12308
12309 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
e6a84e1e 12310 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
12311
12312 ovs-vsctl -- add-port br-int vif$i -- \
12313 set interface vif$i \
12314 external-ids:iface-id=sw$i-p${i}0 \
12315 options:tx_pcap=hv$i/vif$i-tx.pcap \
12316 options:rxq_pcap=hv$i/vif$i-rx.pcap \
12317 ofport-request=$i
12318done
12319
12320ovn-nbctl lr-add lr0
12321for i in 1 2; do
e6a84e1e 12322 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
12323 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
12324 -- set Logical_Switch_Port lrp$i-attachment type=router \
e6a84e1e 12325 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
0e2751ed
LB
12326done
12327
12328OVN_POPULATE_ARP
12329# allow some time for ovn-northd and ovn-controller to catch up.
12330ovn-nbctl --wait=hv sync
12331
12332test_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 12333test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
0e2751ed
LB
12334OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
12335
12336OVN_CLEANUP([hv1], [hv2])
12337AT_CLEANUP
86558ac2
LB
12338
12339AT_SETUP([ovn -- router port unreachable])
12340AT_KEYWORDS([router-port-unreachable])
12341AT_SKIP_IF([test $HAVE_PYTHON = no])
12342ovn_start
12343
12344# 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
12345#
12346# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
12347# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
12348# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
12349# EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
12350#
12351# INPORT is a lport number, e.g. 11 for vif11.
12352# HV is a hypervisor number
12353# ETH_SRC and ETH_DST are each 12 hex digits.
12354# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
12355# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
12356test_ip_packet() {
12357 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
12358 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
12359 shift 11
12360
12361 local ip_ttl=ff
12362 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
12363
12364 local reply_icmp_ttl=fe
12365 local icmp_data=00000000
12366 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
12367 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
12368 echo $reply >> vif$inport.expected
12369
12370 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12371}
12372
159932c9
LB
12373# 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
12374#
12375# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
12376# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
12377# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
12378#
12379# INPORT is an lport number, e.g. 11 for vif11.
12380# HV is an hypervisor number
12381# ETH_SRC and ETH_DST are each 12 hex digits.
12382# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
12383# TCP_SPORT and TCP_DPORT are 4 hex digits.
12384# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
12385test_tcp_syn_packet() {
12386 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
12387 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
12388 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
12389 shift 12
12390
12391 local ip_ttl=ff
12392 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
12393
12394 local tcp_rst_ttl=fe
12395 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
12396 echo $reply >> vif$inport.expected
12397
12398 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12399}
12400
98af55fc
LB
12401# test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
12402#
12403# Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
12404# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
12405# EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
12406test_tcp6_packet() {
12407 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
12408 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
12409 local exp_tcp_rst_chksum=${10}
12410 shift 10
12411
12412 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
12413 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
12414
12415 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
12416 echo $reply >> vif$inport.expected
12417
12418 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12419}
12420
4c25c3b8
LB
12421# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
12422#
12423# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
12424# packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
12425# EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
12426test_ip6_packet() {
12427 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
12428 local exp_icmp_code=${10} exp_icmp_chksum=${11}
12429 shift 11
12430
12431 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
12432 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
12433
12434 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
12435 echo $reply >> vif$inport.expected
12436
12437 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12438}
12439
86558ac2
LB
12440ip_to_hex() {
12441 printf "%02x%02x%02x%02x" "$@"
12442}
12443
12444for i in 1 2; do
12445 net_add n$i
12446 ovn-nbctl ls-add sw$i
12447
12448 sim_add hv$i
12449 as hv$i
12450 ovs-vsctl add-br br-phys
12451 ovn_attach n$i br-phys 192.168.$i.1
12452
12453 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
4c25c3b8 12454 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
12455
12456 ovs-vsctl -- add-port br-int vif$i -- \
12457 set interface vif$i \
12458 external-ids:iface-id=sw$i-p${i}0 \
12459 options:tx_pcap=hv$i/vif$i-tx.pcap \
12460 options:rxq_pcap=hv$i/vif$i-rx.pcap \
12461 ofport-request=$i
12462done
12463
12464ovn-nbctl lr-add lr0
12465for i in 1 2; do
4c25c3b8 12466 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
12467 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
12468 -- set Logical_Switch_Port lrp$i-attachment type=router \
4c25c3b8 12469 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
86558ac2
LB
12470done
12471
12472OVN_POPULATE_ARP
12473# allow some time for ovn-northd and ovn-controller to catch up.
12474ovn-nbctl --wait=hv sync
12475
12476test_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 12477test_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 12478test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
86558ac2
LB
12479OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
12480
159932c9 12481test_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 12482test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
98af55fc 12483test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
159932c9
LB
12484OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
12485
86558ac2
LB
12486OVN_CLEANUP([hv1], [hv2])
12487AT_CLEANUP
96ea0ecb
MM
12488
12489AT_SETUP([ovn -- ovn-controller exit])
12490AT_SKIP_IF([test $HAVE_PYTHON = no])
12491ovn_start
12492# Logical network:
12493# One Logical Router: ro, with two logical switches sw1 and sw2.
12494# sw1 is for subnet 10.0.0.0/8
12495# sw2 is for subnet 20.0.0.0/8
12496# sw1 has a single port bound on hv1
12497# sw2 has a single port bound on hv2
12498
12499ovn-nbctl lr-add ro
12500ovn-nbctl ls-add sw1
12501ovn-nbctl ls-add sw2
12502
12503sw1_ro_mac=00:00:10:00:00:01
12504sw1_ro_ip=10.0.0.1
12505sw2_ro_mac=00:00:20:00:00:01
12506sw2_ro_ip=20.0.0.1
12507sw1_p1_mac=00:00:10:00:00:02
12508sw1_p1_ip=10.0.0.2
12509sw2_p1_mac=00:00:20:00:00:02
12510sw2_p1_ip=20.0.0.2
12511
12512ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
12513ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
12514ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
12515 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
12516ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
12517 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
12518
12519ovn-nbctl lsp-add sw1 sw1-p1 \
12520-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
12521
12522ovn-nbctl lsp-add sw2 sw2-p1 \
12523-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
12524
12525net_add n1
12526
12527sim_add hv1
12528as hv1
12529ovs-vsctl add-br br-phys
12530ovn_attach n1 br-phys 192.168.0.1
12531ovs-vsctl -- add-port br-int hv1-vif1 -- \
12532 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
12533 options:tx_pcap=hv1/vif1-tx.pcap \
12534 options:rxq_pcap=hv1/vif1-rx.pcap \
12535 ofport-request=1
12536
12537sim_add hv2
12538as hv2
12539ovs-vsctl add-br br-phys
12540ovn_attach n1 br-phys 192.168.0.2
12541ovs-vsctl -- add-port br-int hv2-vif1 -- \
12542 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
12543 options:tx_pcap=hv2/vif1-tx.pcap \
12544 options:rxq_pcap=hv2/vif1-rx.pcap \
12545 ofport-request=1
12546
12547OVN_POPULATE_ARP
12548
12549sleep 1
12550
12551packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
12552 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
12553 udp && udp.src==53 && udp.dst==4369"
12554
12555# Start by Sending the packet and make sure it makes it there as expected
12556as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
12557
12558# Expected packet has TTL decreased by 1
12559expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
12560 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
12561 udp && udp.src==53 && udp.dst==4369"
12562echo $expected | ovstest test-ovn expr-to-packets > expected
12563
12564OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
12565
12566# Stop ovn-controller on hv2
12567as hv2 ovs-appctl -t ovn-controller exit
12568
12569# Now send the packet again. This time, it should not arrive.
12570as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
12571
12572OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
12573
12574# Start ovn-controller again just so OVN_CLEANUP doesn't complain
12575as hv2 start_daemon ovn-controller
12576
12577OVN_CLEANUP([hv1],[hv2])
12578AT_CLEANUP
12579
96080083
NS
12580AT_SETUP([ovn -- external logical port])
12581AT_SKIP_IF([test $HAVE_PYTHON = no])
12582ovn_start
12583
12584net_add n1
12585sim_add hv1
12586sim_add hv2
12587sim_add hv3
12588
12589ovn-nbctl ls-add ls1
12590ovn-nbctl lsp-add ls1 ls1-lp1 \
12591-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
12592
12593# Add a couple of external logical port
12594ovn-nbctl lsp-add ls1 ls1-lp_ext1 \
12595-- lsp-set-addresses ls1-lp_ext1 "f0:00:00:00:00:03 10.0.0.6 ae70::6"
12596ovn-nbctl lsp-set-port-security ls1-lp_ext1 \
12597"f0:00:00:00:00:03 10.0.0.6 ae70::6"
12598ovn-nbctl lsp-set-type ls1-lp_ext1 external
12599
12600ovn-nbctl lsp-add ls1 ls1-lp_ext2 \
12601-- lsp-set-addresses ls1-lp_ext2 "f0:00:00:00:00:04 10.0.0.7 ae70::7"
12602ovn-nbctl lsp-set-port-security ls1-lp_ext2 \
12603"f0:00:00:00:00:04 10.0.0.7 ae70::8"
12604ovn-nbctl lsp-set-type ls1-lp_ext2 external
12605
12606d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
12607options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
12608\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
12609
12610d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
12611options="\"server_id\"=\"00:00:00:10:00:01\"")"
12612
12613ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
12614ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext1 ${d1}
12615ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext2 ${d1}
12616
12617ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d2}
12618ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext1 ${d2}
12619ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext2 ${d2}
12620
12621# Create a logical router and connect it to ls1
12622ovn-nbctl lr-add lr0
12623ovn-nbctl lrp-add lr0 lr0-ls1 a0:10:00:00:00:01 10.0.0.1/24
12624ovn-nbctl lsp-add ls1 ls1-lr0
12625ovn-nbctl set Logical_Switch_Port ls1-lr0 type=router \
12626 options:router-port=lr0-ls1 addresses=router
12627
12628# Create HA chassis group
12629ovn-nbctl ha-chassis-group-add hagrp1
12630ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
12631
12632hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name="hagrp1"`
12633
12634# There should be 1 HA_Chassis rows with chassis sets
12635OVS_WAIT_UNTIL([ovn-sbctl list ha_chassis | grep chassis | awk '{print $3}' \
12636| grep '-' | wc -l ], [0], [1
12637])
12638
12639as hv1
12640ovs-vsctl add-br br-phys
12641ovn_attach n1 br-phys 192.168.0.1
12642ovs-vsctl -- add-port br-phys hv1-ext1 -- \
12643 set interface hv1-ext1 options:tx_pcap=hv1/ext1-tx.pcap \
12644 options:rxq_pcap=hv1/ext1-rx.pcap \
12645 ofport-request=2
12646ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12647
12648as hv2
12649ovs-vsctl add-br br-phys
12650ovn_attach n1 br-phys 192.168.0.2
12651ovs-vsctl -- add-port br-phys hv2-ext2 -- \
12652 set interface hv2-ext2 options:tx_pcap=hv2/ext2-tx.pcap \
12653 options:rxq_pcap=hv2/ext2-rx.pcap \
12654 ofport-request=2
12655ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12656
12657as hv3
12658ovs-vsctl add-br br-phys
12659ovn_attach n1 br-phys 192.168.0.3
12660ovs-vsctl -- add-port br-phys hv3-ext3 -- \
12661 set interface hv3-ext3 options:tx_pcap=hv3/ext3-tx.pcap \
12662 options:rxq_pcap=hv3/ext3-rx.pcap \
12663 ofport-request=2
12664ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12665
12666# No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and
12667# hv2 as ha-chassis-group is not set and no localnet port added to ls1.
12668AT_CHECK([ovn-sbctl dump-flows ls1 | grep "offerip = 10.0.0.6" | \
12669wc -l], [0], [0
12670])
12671AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12672grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12673])
12674AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12675grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12676])
12677AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12678grep controller | grep tp_src=546 | grep \
12679"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12680])
12681AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12682grep controller | grep tp_src=546 | grep \
12683"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12684])
12685
12686hv1_uuid=$(ovn-sbctl list chassis hv1 | grep uuid | awk '{print $3}')
12687hv2_uuid=$(ovn-sbctl list chassis hv2 | grep uuid | awk '{print $3}')
12688hv3_uuid=$(ovn-sbctl list chassis hv3 | grep uuid | awk '{print $3}')
12689
12690# The port_binding row for ls1-lp_ext1 should have empty chassis
12691chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12692logical_port=ls1-lp_ext1`
12693
12694AT_CHECK([test x$chassis == x], [0], [])
12695
12696# Associate hagrp1 ha-chassis-group to ls1-lp_ext1
12697ovn-nbctl --wait=hv set Logical_Switch_Port ls1-lp_ext1 \
12698ha-chassis-group=$hagrp1_uuid
12699
12700# Get the hagrp1 uuid in SB DB.
12701sb_hagrp1_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group \
12702name="hagrp1"`
12703
12704# Wait till ls1-lp_ext1 port_binding has ha_chassis_group set
12705OVS_WAIT_UNTIL(
12706 [sb_pb_hagrp=`ovn-sbctl --bare --columns ha_chassis_group find \
12707port_binding logical_port=ls1-lp_ext1`
12708 test "$sb_pb_hagrp" = "$sb_hagrp1_uuid"])
12709
12710# No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and hv2
12711# as no localnet port added to ls1 yet.
12712AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12713grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12714])
12715AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12716grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12717])
12718AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12719grep controller | grep tp_src=546 | grep \
12720"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12721])
12722AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12723grep controller | grep tp_src=546 | grep \
12724"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12725])
12726
12727# Add the localnet port to the logical switch ls1
12728ovn-nbctl lsp-add ls1 ln-public
12729ovn-nbctl lsp-set-addresses ln-public unknown
12730ovn-nbctl lsp-set-type ln-public localnet
12731ovn-nbctl --wait=hv lsp-set-options ln-public network_name=phys
12732
12733ln_public_key=$(ovn-sbctl list port_binding ln-public | grep tunnel_key | \
12734awk '{print $3}')
12735
12736# The ls1-lp_ext1 should be bound to hv1 as only hv1 is part of the
12737# ha chassis group.
12738OVS_WAIT_UNTIL(
12739 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12740logical_port=ls1-lp_ext1`
12741 test "$chassis" = "$hv1_uuid"])
12742
12743# There should be DHCPv4/v6 OF flows for the ls1-lp_ext1 port in hv1
12744AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12745grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
12746wc -l], [0], [3
12747])
12748AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12749grep controller | grep tp_src=546 | grep \
12750"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
12751grep reg14=0x$ln_public_key | wc -l], [0], [1
12752])
12753
12754# There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv2
12755AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12756grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12757])
12758AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12759grep controller | grep tp_src=546 | grep \
12760"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12761])
12762
12763# No DHCPv4/v6 flows for the external port - ls1-lp_ext2 - 10.0.0.7 in hv1 and
12764# hv2 as requested-chassis option is not set.
12765AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12766grep controller | grep "0a.00.00.07" | wc -l], [0], [0
12767])
12768AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12769grep controller | grep "0a.00.00.07" | wc -l], [0], [0
12770])
12771AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12772grep controller | grep tp_src=546 | grep \
12773"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
12774])
12775AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12776grep controller | grep tp_src=546 | grep \
12777"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
12778])
12779
12780as hv1
12781ovs-vsctl show
12782
12783# This shell function sends a DHCP request packet
12784# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
12785test_dhcp() {
12786 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
12787 shift; shift; shift; shift; shift;
12788 if test $use_ip != 0; then
12789 src_ip=$1
12790 dst_ip=$2
12791 shift; shift;
12792 else
12793 src_ip=`ip_to_hex 0 0 0 0`
12794 dst_ip=`ip_to_hex 255 255 255 255`
12795 fi
12796 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
12797 # udp header and dhcp header
12798 request=${request}0044004300fc0000
12799 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
12800 # client hardware padding
12801 request=${request}00000000000000000000
12802 # server hostname
12803 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12804 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12805 # boot file name
12806 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12807 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12808 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12809 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12810 # dhcp magic cookie
12811 request=${request}63825363
12812 # dhcp message type
12813 request=${request}3501${dhcp_type}ff
12814
12815 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
12816 # total IP length will be the IP length of the request packet
12817 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
12818 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
12819 udp_len=`expr $ip_len - 20`
12820 ip_len=$(printf "%x" $ip_len)
12821 udp_len=$(printf "%x" $udp_len)
12822 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
12823 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
12824 # udp header and dhcp header.
12825 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
12826 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
12827 # your ip address
12828 reply=${reply}${offer_ip}
12829 # next server ip address, relay agent ip address, client mac address
12830 reply=${reply}0000000000000000${src_mac}
12831 # client hardware padding
12832 reply=${reply}00000000000000000000
12833 # server hostname
12834 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12835 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12836 # boot file name
12837 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12838 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12839 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12840 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12841 # dhcp magic cookie
12842 reply=${reply}63825363
12843 # dhcp message type
12844 local dhcp_reply_type=02
12845 if test $dhcp_type = 03; then
12846 dhcp_reply_type=05
12847 fi
12848 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
12849 echo $reply >> ext1_v4.expected
12850
12851 as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
12852}
12853
12854
12855trim_zeros() {
12856 sed 's/\(00\)\{1,\}$//'
12857}
12858
12859# This shell function sends a DHCPv6 request packet
12860# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
12861# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
12862# packet should be received twice (one from ovn-controller and the other
12863# from the "ovs-ofctl monitor br-int resume"
12864test_dhcpv6() {
12865 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
12866 local req_pkt_in_expected=$6
12867 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
12868 # dst ip ff02::1:2
12869 request=${request}ff020000000000000000000000010002
12870 # udp header and dhcpv6 header
12871 request=${request}02220223002affff${msg_code}010203
12872 # Client identifier
12873 request=${request}0001000a00030001${src_mac}
12874 # IA-NA (Identity Association for Non Temporary Address)
12875 request=${request}0003000c0102030400000e1000001518
12876 shift; shift; shift; shift; shift;
12877
12878 local server_mac=000000100001
12879 local server_lla=fe80000000000000020000fffe100001
12880 local reply_code=07
12881 if test $msg_code = 01; then
12882 reply_code=02
12883 fi
12884 local msg_len=54
12885 if test $offer_ip = 1; then
12886 msg_len=28
12887 fi
12888 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101
12889 reply=${reply}${server_lla}${src_lla}
12890
12891 # udp header and dhcpv6 header
12892 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
12893 # Client identifier
12894 reply=${reply}0001000a00030001${src_mac}
12895 # IA-NA
12896 if test $offer_ip != 1; then
12897 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}
12898 reply=${reply}ffffffffffffffff
12899 fi
12900 # Server identifier
12901 reply=${reply}0002000a00030001${server_mac}
12902
12903 echo $reply | trim_zeros >> ext${inport}_v6.expected
12904 # The inport also receives the request packet since it is connected
12905 # to the br-phys.
12906 #echo $request >> ext${inport}_v6.expected
12907
12908 as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
12909}
12910
12911reset_pcap_file() {
12912 local iface=$1
12913 local pcap_file=$2
12914 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
12915options:rxq_pcap=dummy-rx.pcap
12916 rm -f ${pcap_file}*.pcap
12917 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
12918options:rxq_pcap=${pcap_file}-rx.pcap
12919}
12920
12921ip_to_hex() {
12922 printf "%02x%02x%02x%02x" "$@"
12923}
12924
12925AT_CAPTURE_FILE([ofctl_monitor0_hv1.log])
12926as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
12927--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv1.log
12928
12929AT_CAPTURE_FILE([ofctl_monitor0_hv2.log])
12930as hv2 ovs-ofctl monitor br-int resume --detach --no-chdir \
12931--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv2.log
12932
12933AT_CAPTURE_FILE([ofctl_monitor0_hv3.log])
12934as hv3 ovs-ofctl monitor br-int resume --detach --no-chdir \
12935--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv3.log
12936
12937as hv1
12938reset_pcap_file hv1-ext1 hv1/ext1
12939
12940# Send DHCPDISCOVER.
12941offer_ip=`ip_to_hex 10 0 0 6`
12942server_ip=`ip_to_hex 10 0 0 1`
12943server_mac=ff1000000001
12944expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
12945test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
12946$expected_dhcp_opts
12947
12948# NXT_RESUMEs should be 1 in hv1.
12949OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12950
12951# NXT_RESUMEs should be 0 in hv2.
12952OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12953
12954$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
12955cat ext1_v4.expected | cut -c -48 > expout
12956AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
12957# Skipping the IPv4 checksum.
12958cat ext1_v4.expected | cut -c 53- > expout
12959AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
12960
12961# ovs-ofctl also resumes the packets and this causes other ports to receive
12962# the DHCP request packet. So reset the pcap files so that its easier to test.
12963as hv1
12964reset_pcap_file hv1-ext1 hv1/ext1
12965
12966rm -f ext1_v4.expected
12967rm -f ext1_v4.packets
12968
12969# Send DHCPv6 request
12970src_mac=f00000000003
12971src_lla=fe80000000000000f20000fffe000003
12972offer_ip=ae700000000000000000000000000006
12973test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
12974
12975# NXT_RESUMEs should be 2 in hv1.
12976OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12977
12978# NXT_RESUMEs should be 0 in hv2.
12979OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12980
12981$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
12982sort > ext1_v6.packets
12983cat ext1_v6.expected | cut -c -120 > expout
12984AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
12985# Skipping the UDP checksum
12986cat ext1_v6.expected | cut -c 125- > expout
12987AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
12988
12989rm -f ext1_v6.expected
12990rm -f ext1_v6.packets
12991
12992as hv1
12993reset_pcap_file hv1-ext1 hv1/ext1
12994
12995# Delete the ha-chassis hv1.
12996ovn-nbctl ha-chassis-group-remove-chassis hagrp1 hv1
12997OVS_WAIT_UNTIL(
12998 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12999logical_port=ls1-lp_ext1`
13000 test "$chassis" = ""])
13001
13002# Add hv2 to the ha chassis group
13003ovn-nbctl --wait=hv ha-chassis-group-add-chassis hagrp1 hv2 20
13004
13005ovn-sbctl list ha_chassis_group
13006ovn-sbctl list ha_chassis
13007
13008ovn-sbctl find port_binding logical_port=ls1-lp_ext1
13009
13010# The ls1-lp_ext1 should be bound to hv2
13011OVS_WAIT_UNTIL(
13012 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13013logical_port=ls1-lp_ext1`
13014 test "$chassis" = "$hv2_uuid"])
13015
13016# There should be OF flows for DHCP4/v6 for the ls1-lp_ext1 port in hv2
13017AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
13018grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
13019wc -l], [0], [3
13020])
13021AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
13022grep controller | grep tp_src=546 | grep \
13023"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
13024grep reg14=0x$ln_public_key | wc -l], [0], [1
13025])
13026
13027# There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv1
13028AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
13029grep controller | grep "0a.00.00.06" | wc -l], [0], [0
13030])
13031AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
13032grep controller | grep tp_src=546 | grep \
13033"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
13034grep reg14=0x$ln_public_key | wc -l], [0], [0
13035])
13036
13037# Send DHCPDISCOVER again for hv1/ext1. The DHCP response should come from
13038# hv2 ovn-controller.
13039offer_ip=`ip_to_hex 10 0 0 6`
13040server_ip=`ip_to_hex 10 0 0 1`
13041server_mac=ff1000000001
13042expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13043test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13044$expected_dhcp_opts
13045
13046# NXT_RESUMEs should be 2 in hv1.
13047OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13048
13049# NXT_RESUMEs should be 1 in hv2.
13050OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13051
13052$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13053cat ext1_v4.expected | cut -c -48 > expout
13054AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13055# Skipping the IPv4 checksum.
13056cat ext1_v4.expected | cut -c 53- > expout
13057AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13058
13059# ovs-ofctl also resumes the packets and this causes other ports to receive
13060# the DHCP request packet. So reset the pcap files so that its easier to test.
13061as hv1
13062reset_pcap_file hv1-ext1 hv1/ext1
13063
13064rm -f ext1_v4.expected
13065
13066# Send DHCPv6 request again
13067src_mac=f00000000003
13068src_lla=fe80000000000000f20000fffe000003
13069offer_ip=ae700000000000000000000000000006
13070test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip 1
13071
13072# NXT_RESUMEs should be 2 in hv1.
13073OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13074
13075# NXT_RESUMEs should be 2 in hv2.
13076OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13077
13078$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13079sort > ext1_v6.packets
13080cat ext1_v6.expected | cut -c -120 > expout
13081AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13082# Skipping the UDP checksum
13083cat ext1_v6.expected | cut -c 125- > expout
13084AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13085
13086rm -f ext1_v6.expected
13087rm -f ext1_v6.packets
13088
13089as hv1
13090ovs-vsctl show
13091reset_pcap_file hv1-ext1 hv1/ext1
13092reset_pcap_file br-phys_n1 hv1/br-phys_n1
13093reset_pcap_file br-phys hv1/br-phys
13094
13095as hv2
13096ovs-vsctl show
13097reset_pcap_file hv2-ext2 hv2/ext2
13098reset_pcap_file br-phys_n1 hv2/br-phys_n1
13099reset_pcap_file br-phys hv2/br-phys
13100
13101# From ls1-lp_ext1, send ARP request for the router ip. The ARP
13102# response should come from the router pipeline of hv2.
13103ext1_mac=f00000000003
13104router_mac=a01000000001
13105ext1_ip=`ip_to_hex 10 0 0 6`
13106router_ip=`ip_to_hex 10 0 0 1`
13107arp_request=ffffffffffff${ext1_mac}08060001080006040001${ext1_mac}${ext1_ip}000000000000${router_ip}
13108
13109as hv1 ovs-appctl netdev-dummy/receive hv1-ext1 $arp_request
13110expected_response=${src_mac}${router_mac}08060001080006040002${router_mac}${router_ip}${ext1_mac}${ext1_ip}
13111echo $expected_response > expout
13112$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_arp_resp
13113AT_CHECK([cat ext1_arp_resp], [0], [expout])
13114
13115# Verify that the response came from hv2
13116$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap > ext1_arp_resp
13117AT_CHECK([cat ext1_arp_resp], [0], [expout])
13118
13119# Now add 3 ha chassis to the ha chassis group
13120ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
13121ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv2 20
13122ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 10
13123
13124# hv1 should be master and claim ls1-lp_ext1
13125OVS_WAIT_UNTIL(
13126 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13127logical_port=ls1-lp_ext1`
13128 test "$chassis" = "$hv1_uuid"])
13129
13130as hv1
13131ovs-vsctl show
13132reset_pcap_file hv1-ext1 hv1/ext1
13133reset_pcap_file br-phys_n1 hv1/br-phys_n1
13134reset_pcap_file br-phys hv1/br-phys
13135
13136as hv2
13137ovs-vsctl show
13138reset_pcap_file hv2-ext2 hv2/ext2
13139reset_pcap_file br-phys_n1 hv2/br-phys_n1
13140reset_pcap_file br-phys hv2/br-phys
13141
13142as hv3
13143ovs-vsctl show
13144reset_pcap_file hv3-ext3 hv3/ext3
13145reset_pcap_file br-phys_n1 hv3/br-phys_n1
13146reset_pcap_file br-phys hv3/br-phys
13147
13148# Send DHCPDISCOVER.
13149offer_ip=`ip_to_hex 10 0 0 6`
13150server_ip=`ip_to_hex 10 0 0 1`
13151server_mac=ff1000000001
13152expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13153test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13154$expected_dhcp_opts
13155
13156# NXT_RESUMEs should be 3 in hv1.
13157OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13158
13159# NXT_RESUMEs should be 2 in hv2.
13160OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13161
13162$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13163cat ext1_v4.expected | cut -c -48 > expout
13164AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13165# Skipping the IPv4 checksum.
13166cat ext1_v4.expected | cut -c 53- > expout
13167AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13168
13169# ovs-ofctl also resumes the packets and this causes other ports to receive
13170# the DHCP request packet. So reset the pcap files so that its easier to test.
13171as hv1
13172reset_pcap_file hv1-ext1 hv1/ext1
13173
13174rm -f ext1_v4.expected
13175rm -f ext1_v4.packets
13176
13177# Send DHCPv6 request
13178src_mac=f00000000003
13179src_lla=fe80000000000000f20000fffe000003
13180offer_ip=ae700000000000000000000000000006
13181test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
13182
13183# NXT_RESUMEs should be 4 in hv1.
13184OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13185
13186# NXT_RESUMEs should be 2 in hv2.
13187OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13188
13189$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13190sort > ext1_v6.packets
13191cat ext1_v6.expected | cut -c -120 > expout
13192AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13193# Skipping the UDP checksum
13194cat ext1_v6.expected | cut -c 125- > expout
13195AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13196
13197rm -f ext1_v6.expected
13198rm -f ext1_v6.packets
13199as hv1 reset_pcap_file hv1-ext1 hv1/ext1
13200
13201# Now increase the priority of hv3 so it becomes master.
13202ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 50
13203
13204# hv3 should be master and claim ls1-lp_ext1
13205OVS_WAIT_UNTIL(
13206 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13207logical_port=ls1-lp_ext1`
13208 test "$chassis" = "$hv3_uuid"])
13209
13210as hv1
13211ovs-vsctl show
13212reset_pcap_file hv1-ext1 hv1/ext1
13213reset_pcap_file br-phys_n1 hv1/br-phys_n1
13214reset_pcap_file br-phys hv1/br-phys
13215
13216as hv2
13217ovs-vsctl show
13218reset_pcap_file hv2-ext2 hv2/ext2
13219reset_pcap_file br-phys_n1 hv2/br-phys_n1
13220reset_pcap_file br-phys hv2/br-phys
13221
13222as hv2
13223ovs-vsctl show
13224reset_pcap_file hv3-ext3 hv3/ext3
13225reset_pcap_file br-phys_n1 hv3/br-phys_n1
13226reset_pcap_file br-phys hv3/br-phys
13227
13228# Send DHCPDISCOVER.
13229offer_ip=`ip_to_hex 10 0 0 6`
13230server_ip=`ip_to_hex 10 0 0 1`
13231server_mac=ff1000000001
13232expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13233test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13234$expected_dhcp_opts
13235
13236# NXT_RESUMEs should be 4 in hv1.
13237OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13238
13239# NXT_RESUMEs should be 2 in hv2.
13240OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13241
13242# NXT_RESUMEs should be 1 in hv3.
13243OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
13244
13245$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13246cat ext1_v4.expected | cut -c -48 > expout
13247AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13248# Skipping the IPv4 checksum.
13249cat ext1_v4.expected | cut -c 53- > expout
13250AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13251
13252# ovs-ofctl also resumes the packets and this causes other ports to receive
13253# the DHCP request packet. So reset the pcap files so that its easier to test.
13254as hv1
13255reset_pcap_file hv1-ext1 hv1/ext1
13256
13257rm -f ext1_v4.expected
13258rm -f ext1_v4.packets
13259
13260# Send DHCPv6 request
13261src_mac=f00000000003
13262src_lla=fe80000000000000f20000fffe000003
13263offer_ip=ae700000000000000000000000000006
13264test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
13265
13266# NXT_RESUMEs should be 4 in hv1.
13267OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13268
13269# NXT_RESUMEs should be 2 in hv2.
13270OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13271
13272# NXT_RESUMEs should be 2 in hv3.
13273OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
13274
13275$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13276sort > ext1_v6.packets
13277cat ext1_v6.expected | cut -c -120 > expout
13278AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13279# Skipping the UDP checksum
13280cat ext1_v6.expected | cut -c 125- > expout
13281AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13282
13283# disconnect hv3 from the network, hv1 should take over
13284as hv3
13285port=${sandbox}_br-phys
13286as main ovs-vsctl del-port n1 $port
13287
13288# hv1 should be master and claim ls1-lp_ext1
13289OVS_WAIT_UNTIL(
13290 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13291logical_port=ls1-lp_ext1`
13292 test "$chassis" = "$hv1_uuid"])
13293
13294OVN_CLEANUP([hv1],[hv2],[hv3])
13295AT_CLEANUP
13296
37c951b2
HZ
13297AT_SETUP([ovn -- Address Set Incremental Processing])
13298AT_KEYWORDS([ovn_as_inc])
13299AT_SKIP_IF([test $HAVE_PYTHON = no])
13300ovn_start
13301
13302net_add n1
13303sim_add hv1
13304as hv1
13305ovs-vsctl add-br br-phys
13306ovn_attach n1 br-phys 192.168.0.10
13307
13308ovn-nbctl ls-add ls1
13309for i in 1 2; do
13310 ovn-nbctl lsp-add ls1 lp$i \
13311 -- lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.1.$i"
13312 as hv1 ovs-vsctl \
13313 -- add-port br-int vif$i \
13314 -- set Interface vif$i \
13315 external-ids:iface-id=lp$i
13316done
13317
13318for i in 1 2 3; do
13319 as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
13320 as2_uuid=`ovn-nbctl --wait=hv create addr name=as2`
13321 ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
13322 'outport=="lp1" && ip4 && ip4.src == {$as1, $as2}' allow-related
13323 ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10"
13324 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [0], [ignore])
13325
13326 # Update address set as1
13327 ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10 10.1.2.11"
13328 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.11"], [0], [ignore])
13329
13330 # Update address set as2
13331 ovn-nbctl --wait=hv set addr as2 addresses="10.1.2.12 10.1.2.13"
13332 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
13333
13334 # Add another ACL referencing as1
13335 n_flows_before=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13336 ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
13337 'outport=="lp2" && ip4 && ip4.src == $as1' allow-related
13338 n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13339 AT_CHECK([test $(expr $n_flows_before \* 2) = $n_flows_after], [0], [ignore])
13340
13341 # Remove an ACL
13342 ovn-nbctl --wait=hv acl-del ls1 to-lport 200 \
13343 'outport=="lp2" && ip4 && ip4.src == $as1'
13344 n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13345 AT_CHECK([test $n_flows_before = $n_flows_after], [0], [ignore])
13346
13347 # Remove as1 while it is still used by an ACL, the lflows should be reparsed and
13348 # parsing should fail.
13349 echo "before del as1"
13350 ovn-nbctl list addr | grep as1
13351 ovn-nbctl --wait=hv destroy addr $as1_uuid
13352 echo "after del as1"
13353 ovn-nbctl list addr | grep as1
13354 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [1], [ignore])
13355 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
13356
13357 # Recreate as1
13358 as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
13359 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
13360
13361 # Remove ACLs and address sets
13362 ovn-nbctl --wait=hv destroy addr $as1_uuid -- destroy addr $as2_uuid
13363 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
13364
13365 ovn-nbctl --wait=hv acl-del ls1
13366done
13367
13368# Gracefully terminate daemons
13369OVN_CLEANUP([hv1])
13370AT_CLEANUP
13371
96ea0ecb
MM
13372AT_SETUP([ovn -- ovn-controller restart])
13373AT_SKIP_IF([test $HAVE_PYTHON = no])
13374ovn_start
13375
13376# Logical network:
13377# One Logical Router: ro, with two logical switches sw1 and sw2.
13378# sw1 is for subnet 10.0.0.0/8
13379# sw2 is for subnet 20.0.0.0/8
13380# sw1 has a single port bound on hv1
13381# sw2 has a single port bound on hv2
13382
13383ovn-nbctl lr-add ro
13384ovn-nbctl ls-add sw1
13385ovn-nbctl ls-add sw2
13386
13387sw1_ro_mac=00:00:10:00:00:01
13388sw1_ro_ip=10.0.0.1
13389sw2_ro_mac=00:00:20:00:00:01
13390sw2_ro_ip=20.0.0.1
13391sw1_p1_mac=00:00:10:00:00:02
13392sw1_p1_ip=10.0.0.2
13393sw2_p1_mac=00:00:20:00:00:02
13394sw2_p1_ip=20.0.0.2
13395
13396ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
13397ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
13398ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
13399 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
13400ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
13401 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
13402
13403ovn-nbctl lsp-add sw1 sw1-p1 \
13404-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
13405
13406ovn-nbctl lsp-add sw2 sw2-p1 \
13407-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
13408
13409net_add n1
13410
13411sim_add hv1
13412as hv1
13413ovs-vsctl add-br br-phys
13414ovn_attach n1 br-phys 192.168.0.1
13415ovs-vsctl -- add-port br-int hv1-vif1 -- \
13416 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
13417 options:tx_pcap=hv1/vif1-tx.pcap \
13418 options:rxq_pcap=hv1/vif1-rx.pcap \
13419 ofport-request=1
13420
13421sim_add hv2
13422as hv2
13423ovs-vsctl add-br br-phys
13424ovn_attach n1 br-phys 192.168.0.2
13425ovs-vsctl -- add-port br-int hv2-vif1 -- \
13426 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
13427 options:tx_pcap=hv2/vif1-tx.pcap \
13428 options:rxq_pcap=hv2/vif1-rx.pcap \
13429 ofport-request=1
13430
13431OVN_POPULATE_ARP
13432
13433sleep 1
13434
13435packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
13436 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
13437 udp && udp.src==53 && udp.dst==4369"
13438
13439# Start by Sending the packet and make sure it makes it there as expected
13440as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
13441
13442# Expected packet has TTL decreased by 1
13443expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
13444 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
13445 udp && udp.src==53 && udp.dst==4369"
13446echo $expected | ovstest test-ovn expr-to-packets > expected
13447
13448OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13449
13450# Stop ovn-controller on hv2 with --restart flag
13451as hv2 ovs-appctl -t ovn-controller exit --restart
13452
13453# Now send the packet again. This time, it should still arrive
13454as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
13455
13456cat expected expected > expected2
13457
13458OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
13459
13460# Start ovn-controller again just so OVN_CLEANUP doesn't complain
13461as hv2 start_daemon ovn-controller
13462
13463OVN_CLEANUP([hv1],[hv2])
13464
ba11e162 13465
96ea0ecb 13466AT_CLEANUP
863fb61f
MM
13467
13468AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
13469ovn_start
13470
13471# Set up a switch with some switch ports of varying address types
13472ovn-nbctl ls-add sw1
13473ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
13474
13475ovn-nbctl lsp-add sw1 sw1-p1
13476ovn-nbctl lsp-add sw1 sw1-p2
13477ovn-nbctl lsp-add sw1 sw1-p3
13478ovn-nbctl lsp-add sw1 sw1-p4
13479
13480ovn-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"
13481ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
13482ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
13483ovn-nbctl lsp-set-addresses sw1-p4 "router"
13484ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
13485
13486ovn-nbctl list logical_switch_port
13487
13488# Now try to add duplicate addresses on a new port. These should all fail
abf11558 13489ovn-nbctl --wait=sb lsp-add sw1 sw1-p5
863fb61f
MM
13490AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
13491[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
13492])
13493AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
13494[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
13495])
13496AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
13497[ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
13498])
13499AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
13500[ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
13501])
13502AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
13503[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
13504])
13505AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
13506[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
13507])
13508
13509# Now try re-setting sw1-p1. This should succeed
13510AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
13511
13512# Now create a new switch and try setting IP addresses the same as the
13513# first switch. This should succeed.
13514ovn-nbctl ls-add sw2
13515ovn-nbctl lsp-add sw2 sw2-p1
13516
13517AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
13518AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
13519AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
13520AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
13521
13522AT_CLEANUP
d7abfe39 13523
ba11e162
NS
13524AT_SETUP([ovn -- router - check packet length - icmp defrag])
13525AT_KEYWORDS([check packet length])
13526AT_SKIP_IF([test $HAVE_PYTHON = no])
13527ovn_start
13528
13529ovn-nbctl ls-add sw0
13530ovn-nbctl lsp-add sw0 sw0-port1
13531ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:01 10.0.0.3"
13532
13533ovn-nbctl lr-add lr0
13534ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
13535ovn-nbctl lsp-add sw0 sw0-lr0
13536ovn-nbctl lsp-set-type sw0-lr0 router
13537ovn-nbctl lsp-set-addresses sw0-lr0 router
13538ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
13539
13540ovn-nbctl ls-add public
13541ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
13542ovn-nbctl lsp-add public public-lr0
13543ovn-nbctl lsp-set-type public-lr0 router
13544ovn-nbctl lsp-set-addresses public-lr0 router
13545ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
13546
13547# localnet port
13548ovn-nbctl lsp-add public ln-public
13549ovn-nbctl lsp-set-type ln-public localnet
13550ovn-nbctl lsp-set-addresses ln-public unknown
13551ovn-nbctl lsp-set-options ln-public network_name=phys
13552
13553ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
13554ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
13555
13556net_add n1
13557
13558sim_add hv1
13559as hv1
13560ovs-vsctl add-br br-phys
13561ovn_attach n1 br-phys 192.168.0.1
13562ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
13563ovs-vsctl -- add-port br-int hv1-vif1 -- \
13564 set interface hv1-vif1 external-ids:iface-id=sw0-port1 \
13565 options:tx_pcap=hv1/vif1-tx.pcap \
13566 options:rxq_pcap=hv1/vif1-rx.pcap \
13567 ofport-request=1
13568
13569reset_pcap_file() {
13570 local iface=$1
13571 local pcap_file=$2
13572 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
13573 options:rxq_pcap=dummy-rx.pcap
13574 rm -f ${pcap_file}*.pcap
13575 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
13576 options:rxq_pcap=${pcap_file}-rx.pcap
13577}
13578
13579ip_to_hex() {
13580 printf "%02x%02x%02x%02x" "$@"
13581}
13582
13583test_ip_packet_larger() {
13584 local icmp_pmtu_reply_expected=$1
13585
13586 # Send ip packet from sw0-port1 to outside
13587 src_mac="505400000001" # sw-port1 mac
13588 dst_mac="00000000ff01" # sw0-lr0 mac (internal router leg)
13589 src_ip=`ip_to_hex 10 0 0 3`
13590 dst_ip=`ip_to_hex 172 168 0 3`
13591 # Set the packet length to 100.
13592 pkt_len=0064
13593 packet=${dst_mac}${src_mac}08004500${pkt_len}0000000040010000
13594 orig_packet_l3=${src_ip}${dst_ip}0304000000000000
13595 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13596 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13597 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13598 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13599 packet=${packet}${orig_packet_l3}
13600
fbe67a7d
NS
13601 gw_ip_garp=ffffffffffff00002020121308060001080006040001000020201213aca80064000000000000aca80064
13602
ba11e162
NS
13603 # If icmp_pmtu_reply_expected is 0, it means the packet is lesser than
13604 # the gateway mtu and should be delivered to the provider bridge via the
13605 # localnet port.
13606 # If icmp_pmtu_reply_expected is 1, it means the packet is larger than
13607 # the gateway mtu and ovn-controller should drop the packet and instead
13608 # generate ICMPv4 Destination Unreachable message with pmtu set to 42.
13609 if test $icmp_pmtu_reply_expected = 0; then
13610 # Packet to expect at br-phys.
13611 src_mac="000020201213"
13612 dst_mac="00000012af11"
13613 src_ip=`ip_to_hex 10 0 0 3`
13614 dst_ip=`ip_to_hex 172 168 0 3`
13615 expected=${dst_mac}${src_mac}08004500${pkt_len}000000003f010100
13616 expected=${expected}${src_ip}${dst_ip}0304000000000000
13617 expected=${expected}000000000000000000000000000000000000
13618 expected=${expected}000000000000000000000000000000000000
13619 expected=${expected}000000000000000000000000000000000000
13620 expected=${expected}000000000000000000000000000000000000
13621 echo $expected > br_phys_n1.expected
fbe67a7d 13622 echo $gw_ip_garp >> br_phys_n1.expected
ba11e162
NS
13623 else
13624 # MTU would be 100 - 18 = 82 (hex 0052)
13625 mtu=0052
13626 src_ip=`ip_to_hex 10 0 0 1`
13627 dst_ip=`ip_to_hex 10 0 0 3`
13628 # pkt len should be 128 (28 (icmp packet) + 100 (orig ip + payload))
13629 reply_pkt_len=0080
13630 ip_csum=bd91
13631 icmp_reply=${src_mac}${dst_mac}08004500${reply_pkt_len}00004000fe016879
13632 icmp_reply=${icmp_reply}${src_ip}${dst_ip}0304${ip_csum}0000${mtu}
13633 icmp_reply=${icmp_reply}4500${pkt_len}000000003f010100
13634 icmp_reply=${icmp_reply}${orig_packet_l3}
13635 echo $icmp_reply > hv1-vif1.expected
13636 fi
13637
13638 as hv1 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13639 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
13640
13641 # Send packet from sw0-port1 to outside
13642 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
13643
13644 if test $icmp_pmtu_reply_expected = 0; then
13645 OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [br_phys_n1.expected])
fbe67a7d
NS
13646 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > pkts
13647 # hv1/vif1-tx.pcap can receive the GARP packet generated by ovn-controller
13648 # for the gateway router port. So ignore this packet.
13649 cat pkts | grep -v $gw_ip_garp > packets
ba11e162
NS
13650 AT_CHECK([cat packets], [0], [])
13651 else
13652 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [hv1-vif1.expected])
13653 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap > \
fbe67a7d
NS
13654 pkts
13655 # hv1/br-phys_n1-tx.pcap can receive the GARP packet generated by ovn-controller
13656 # for the gateway router port. So ignore this packet.
13657 cat pkts | grep -v $gw_ip_garp > packets
ba11e162
NS
13658 AT_CHECK([cat packets], [0], [])
13659 fi
13660}
13661
13662ovn-nbctl show
13663ovn-sbctl show
13664
13665AT_CHECK([as hv1 ovs-ofctl dump-flows br-int \
13666| grep "check_pkt_larger" | wc -l], [0], [[0
13667]])
13668dp_uuid=$(ovn-sbctl find datapath_binding | grep sw0 -B2 | grep _uuid | \
13669awk '{print $3}')
13670ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
13671logical_port=lr0-public mac="00\:00\:00\:12\:af\:11"
13672
13673# Set the gateway mtu to 100. If the packet length is > 100, ovn-controller
13674# should send icmp host not reachable with pmtu set to 100.
13675ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=100
13676as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
13677OVS_WAIT_UNTIL([
13678 test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(100)" | \
13679 wc -l` -eq 1
13680])
13681
13682icmp_reply_expected=1
13683test_ip_packet_larger $icmp_reply_expected
13684
13685# Set the gateway mtu to 500.
13686ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=500
13687as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
13688OVS_WAIT_UNTIL([
13689 test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(500)" | \
13690 wc -l` -eq 1
13691])
13692
13693# Now the packet should be sent via the localnet port to br-phys.
13694icmp_reply_expected=0
13695test_ip_packet_larger $icmp_reply_expected
13696OVN_CLEANUP([hv1])
13697AT_CLEANUP
13698
d7abfe39
LB
13699AT_SETUP([ovn -- IP packet buffering])
13700AT_KEYWORDS([ip-buffering])
13701AT_SKIP_IF([test $HAVE_PYTHON = no])
13702ovn_start
13703
13704# Logical network:
13705# One LR lr0 that has switches sw0 (192.168.1.0/24) and
13706# sw1 (172.16.1.0/24) connected to it.
13707#
13708# Physical network:
13709# Tw0 hypervisors hv[12].
13710# hv1 hosts vif sw0-p0.
13711# hv1 hosts vif sw1-p0.
13712
13713send_icmp_packet() {
13714 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
13715 shift 8
13716
13717 local ip_ttl=ff
13718 local ip_len=001c
13719 local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
13720 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
13721}
13722
13723send_icmp6_packet() {
13724 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
13725 shift 8
13726
13727 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
13728 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
13729
13730 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
13731}
13732
13733get_arp_req() {
13734 local eth_src=$1 spa=$2 tpa=$3
13735 local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
13736 echo $request
13737}
13738
13739send_arp_reply() {
13740 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
13741 local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
13742 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
13743}
13744
13745send_na() {
13746 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
13747 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
13748 local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
13749
13750 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
13751}
13752
13753get_nd() {
13754 local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
13755 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
13756 request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
13757
13758 echo $request
13759}
13760
13761net_add n1
13762
13763sim_add hv1
13764as hv1
13765ovs-vsctl add-br br-phys
13766ovn_attach n1 br-phys 192.168.0.1
13767ovs-vsctl -- add-port br-int hv1-vif1 -- \
13768 set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
13769 options:tx_pcap=hv1/vif1-tx.pcap \
13770 options:rxq_pcap=hv1/vif1-rx.pcap \
13771 ofport-request=1
13772
13773sim_add hv2
13774as hv2
13775ovs-vsctl add-br br-phys
13776ovn_attach n1 br-phys 192.168.0.2
13777ovs-vsctl -- add-port br-int hv2-vif1 -- \
13778 set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
13779 options:tx_pcap=hv2/vif1-tx.pcap \
13780 options:rxq_pcap=hv2/vif1-rx.pcap \
13781 ofport-request=1
13782
13783ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
13784ovn-nbctl ls-add sw0
13785ovn-nbctl ls-add sw1
13786
409f7245 13787ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001:0:0:0:0:0:0:1/64
d7abfe39
LB
13788ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
13789 type=router options:router-port=sw0 \
13790 -- lsp-set-addresses rp-sw0 router
13791
409f7245 13792ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002:0:0:0:0:0:0:1/64
d7abfe39
LB
13793ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
13794 type=router options:router-port=sw1 \
13795 -- lsp-set-addresses rp-sw1 router
13796
13797ovn-nbctl lsp-add sw0 sw0-p0 \
13798 -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
13799
13800ovn-nbctl lsp-add sw1 sw1-p0 \
13801 -- lsp-set-addresses sw1-p0 unknown
13802
13803OVN_POPULATE_ARP
13804ovn-nbctl --wait=hv sync
13805
13806ip_to_hex() {
13807 printf "%02x%02x%02x%02x" "$@"
13808}
13809
13810src_mac=f00000010203
13811src_ip=$(ip_to_hex 192 168 1 2)
13812src_ip6=20010000000000000000000000000002
13813
13814router_mac0=000001010203
13815router_mac1=000002010203
13816router_ip=$(ip_to_hex 172 16 1 1)
13817router_ip6=20020000000000000000000000000001
13818
13819dst_mac=001122334455
13820dst_ip=$(ip_to_hex 172 16 1 10)
13821dst_ip6=20020000000000000000000000000010
13822
13823data=0800bee4391a0001
13824
13825send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
13826send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
13827echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
13828echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
13829
13830OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13831
13832nd_ip=ff0200000000000000000001ff000010
13833ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
13834
13835send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
13836echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
13837echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
13838send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
13839
13840OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13841
13842OVN_CLEANUP([hv1],[hv2])
13843AT_CLEANUP
81e92852
DA
13844
13845AT_SETUP([ovn -- neighbor update on same HV])
13846AT_SKIP_IF([test $HAVE_PYTHON = no])
13847ovn_start
13848
13849# Logical network:
13850# A public switch (pub) with a localnet port connected to two LRs (lr0 and lr1)
13851# each with a distributed gateway port.
13852# Two VMs: lp0 on sw0 connected to lr0
13853# lp1 on sw1 connected to lr1
13854#
13855# This test adds a floating IP to each VM so when they are bound to the same
13856# hypervisor, it checks that the GARP sent by ovn-controller causes the
13857# MAC_Binding entries to be updated properly on each logical router.
13858# It will also capture packets on the physical interface to make sure that the
13859# GARPs have been sent out to the external network as well.
13860
13861# Create logical switches
13862ovn-nbctl ls-add sw0
13863ovn-nbctl ls-add sw1
13864ovn-nbctl ls-add pub
13865
13866# Created localnet port on public switch
13867ovn-nbctl lsp-add pub ln-pub
13868ovn-nbctl lsp-set-type ln-pub localnet
13869ovn-nbctl lsp-set-addresses ln-pub unknown
13870ovn-nbctl lsp-set-options ln-pub network_name=phys
13871
13872# Create logical routers and connect them to public switch
13873ovn-nbctl create Logical_Router name=lr0
13874ovn-nbctl create Logical_Router name=lr1
13875
13876ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
13877ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
13878 type=router options:router-port=lr0-pub options:nat-addresses="router" addresses="router"
13879ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
13880ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
13881 type=router options:router-port=lr1-pub options:nat-addresses="router" addresses="router"
13882
13883ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
13884ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
13885
13886# Connect sw0 and sw1 to lr0 and lr1
13887ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
13888ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
13889 options:router-port=lr0-sw0 addresses="router"
13890ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
13891ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
13892 options:router-port=lr1-sw1 addresses="router"
13893
13894
13895# Add SNAT rules
13896ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
13897ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
13898
13899net_add n1
13900sim_add hv1
13901as hv1
13902ovs-vsctl add-br br-phys
13903ovn_attach n1 br-phys 172.24.4.1
13904ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
13905
13906ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
13907ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
13908
13909ovn-nbctl lsp-add sw0 lp0
13910ovn-nbctl lsp-add sw1 lp1
13911ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
13912ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
13913
13914OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp0` = xup])
13915OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
13916
13917# Create two floating IPs, one for each VIF
13918ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
13919ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
13920
13921# Check that the MAC_Binding entries have been properly created
13922OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr0-pub" ip="172.24.4.200" | wc -l` -gt 0])
13923OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr1-pub" ip="172.24.4.100" | wc -l` -gt 0])
13924
13925# Check that the GARPs went also to the external physical network
13926# Wait until at least 4 packets have arrived and copy them to a separate file as
13927# more GARPs are expected in the capture in order to avoid race conditions.
13928OVS_WAIT_UNTIL([test `$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | wc -l` -gt 4])
13929$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | head -n4 > hv1/br-phys-tx4.pcap
13930
13931# GARP for lp0 172.24.4.100 on lr0-pub MAC (f0:00:00:00:00:01)
13932echo "fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464" > expout
13933# GARP for 172.24.4.220 on lr0-pub (f0:00:00:00:00:01)
13934echo "fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc" >> expout
13935# GARP for lp1 172.24.4.200 on lr1-pub MAC (f0:00:00:00:01:01)
13936echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8" >> expout
13937# GARP for 172.24.4.221 on lr1-pub (f0:00:00:00:01:01)
13938echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd" >> expout
13939AT_CHECK([sort hv1/br-phys-tx4.pcap], [0], [expout])
13940#OVN_CHECK_PACKETS([hv1/br-phys-tx4.pcap], [br-phys.expected])
13941
13942OVN_CLEANUP([hv1])
13943AT_CLEANUP
dcad4473
MM
13944
13945AT_SETUP([ovn -- ipam to non-ipam])
13946ovn_start
13947
f1301a25 13948ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
dcad4473
MM
13949ovn-nbctl ls-add sw0
13950ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
13951ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
13952
13953AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
13954 ["0a:00:00:a8:01:03 192.168.1.2"
13955])
13956
abf11558 13957ovn-nbctl --wait=sb lsp-set-addresses p0 router
dcad4473
MM
13958
13959ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses
13960
13961AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0], [[[]]
13962])
13963AT_CLEANUP
6f5cc61c
MM
13964
13965AT_SETUP([ovn -- ipam router ports])
13966ovn_start
13967
13968ovn-nbctl ls-add sw
13969ovn-nbctl set logical_switch sw other-config:subnet=192.168.1.0/24
13970
13971for i in 2 3 4; do
13972 ovn-nbctl lr-add ro$i
13973 ovn-nbctl lsp-add sw swp$i
13974 ovn-nbctl --wait=sb lsp-set-addresses swp$i "02:00:00:00:00:0$i dynamic"
13975 cidr=$(ovn-nbctl get logical_switch_port swp$i dynamic_addresses |cut -f2 -d' '|cut -f1 -d\")
13976 ovn-nbctl lrp-add ro$i rop$i 02:00:00:00:00:0$i $cidr/24 -- set logical_switch_port swp$i type=router options:router-port=rop$i addresses=router;
13977 AT_CHECK_UNQUOTED([ovn-nbctl get logical_router_port rop$i networks], [0], [[["192.168.1.$i/24"]]
13978])
13979done
13980
13981ovn-nbctl list logical_switch_port
13982ovn-nbctl list logical_router_port
13983
13984AT_CLEANUP
3bb479d9
LAG
13985
13986AT_SETUP([ovn -- test transport zones])
13987ovn_start
13988
13989net_add n1
13990for i in 1 2 3 4 5; do
13991 sim_add hv$i
13992 as hv$i
13993 ovs-vsctl add-br br-phys
13994 ovn_attach n1 br-phys 192.168.$i.1
13995done
13996
13997dnl Wait for the changes to be propagated
13998ovn-nbctl --wait=sb --timeout=3 sync
13999ovn-nbctl --wait=hv --timeout=3 sync
14000
14001dnl Assert that each Chassis has a tunnel formed to every other Chassis
14002as hv1
14003AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14004[[ovn-hv2-0
14005ovn-hv3-0
14006ovn-hv4-0
14007ovn-hv5-0
14008]])
14009
14010as hv2
14011AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14012[[ovn-hv1-0
14013ovn-hv3-0
14014ovn-hv4-0
14015ovn-hv5-0
14016]])
14017
14018as hv3
14019AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14020[[ovn-hv1-0
14021ovn-hv2-0
14022ovn-hv4-0
14023ovn-hv5-0
14024]])
14025
14026as hv4
14027AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14028[[ovn-hv1-0
14029ovn-hv2-0
14030ovn-hv3-0
14031ovn-hv5-0
14032]])
14033
14034as hv5
14035AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14036[[ovn-hv1-0
14037ovn-hv2-0
14038ovn-hv3-0
14039ovn-hv4-0
14040]])
14041
14042dnl Let's now add some Chassis to different transport zones
14043dnl * hv1: Will be part of two transport zones: tz1 and tz2 so it
14044dnl should have tunnels formed between the other two Chassis (hv2 and hv3)
14045dnl
14046dnl * hv2: Will be part of one transport zone: tz1. It should have a tunnel
14047dnl to hv1 but not to hv3
14048dnl
14049dnl * hv3: Will be part of one transport zone: tz2. It should have a tunnel
14050dnl to hv1 but not to hv2
14051dnl
14052dnl * hv4 and hv5: Will not have any TZ set so they will keep the tunnels
14053dnl between themselves and remove the tunnels to other Chassis which now
14054dnl belongs to some TZs
14055dnl
14056as hv1
14057ovs-vsctl set open . external-ids:ovn-transport-zones=tz1,tz2
14058
14059as hv2
14060ovs-vsctl set open . external-ids:ovn-transport-zones=tz1
14061
14062as hv3
14063ovs-vsctl set open . external-ids:ovn-transport-zones=tz2
14064
14065dnl Wait for the changes to be propagated
14066ovn-nbctl --wait=sb --timeout=3 sync
14067ovn-nbctl --wait=hv --timeout=3 sync
14068
14069as hv1
14070AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14071[[ovn-hv2-0
14072ovn-hv3-0
14073]])
14074
14075as hv2
14076AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14077[[ovn-hv1-0
14078]])
14079
14080as hv3
14081AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14082[[ovn-hv1-0
14083]])
14084
14085as hv4
14086AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14087[[ovn-hv5-0
14088]])
14089
14090as hv5
14091AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14092[[ovn-hv4-0
14093]])
14094
14095dnl Removing the transport zones should make all Chassis to create
14096dnl tunnels between every other Chassis again
14097for i in 1 2 3; do
14098 as hv$i
14099 ovs-vsctl remove open . external-ids ovn-transport-zones
14100done
14101
14102dnl Wait for the changes to be propagated
14103ovn-nbctl --wait=sb --timeout=3 sync
14104ovn-nbctl --wait=hv --timeout=3 sync
14105
14106as hv1
14107AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14108[[ovn-hv2-0
14109ovn-hv3-0
14110ovn-hv4-0
14111ovn-hv5-0
14112]])
14113
14114as hv2
14115AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14116[[ovn-hv1-0
14117ovn-hv3-0
14118ovn-hv4-0
14119ovn-hv5-0
14120]])
14121
14122as hv3
14123AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14124[[ovn-hv1-0
14125ovn-hv2-0
14126ovn-hv4-0
14127ovn-hv5-0
14128]])
14129
14130as hv4
14131AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14132[[ovn-hv1-0
14133ovn-hv2-0
14134ovn-hv3-0
14135ovn-hv5-0
14136]])
14137
14138as hv5
14139AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14140[[ovn-hv1-0
14141ovn-hv2-0
14142ovn-hv3-0
14143ovn-hv4-0
14144]])
14145
14146OVN_CLEANUP([hv1], [hv2], [hv3])
14147AT_CLEANUP
795d7f24
AS
14148
14149AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR chassis mac])
14150ovn_start
14151
14152
14153# In this test cases we create 2 switches, all connected to same
14154# physical network (through br-phys on each HV). Each switch has
14155# 1 VIF. Each HV has 1 VIF port. The first digit
14156# of VIF port name indicates the hypervisor it is bound to, e.g.
14157# lp23 means VIF 3 on hv2.
14158#
14159# Each switch's VLAN tag and their logical switch ports are:
14160# - ls1:
14161# - tagged with VLAN 101
14162# - ports: lp11
14163# - ls2:
14164# - tagged with VLAN 201
14165# - ports: lp22
14166#
14167# Note: a localnet port is created for each switch to connect to
14168# physical network.
14169
14170for i in 1 2; do
14171 ls_name=ls$i
14172 ovn-nbctl ls-add $ls_name
14173 ln_port_name=ln$i
14174 if test $i -eq 1; then
14175 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
14176 elif test $i -eq 2; then
14177 ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
14178 fi
14179 ovn-nbctl lsp-set-addresses $ln_port_name unknown
14180 ovn-nbctl lsp-set-type $ln_port_name localnet
14181 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
14182done
14183
14184# lsp_to_ls LSP
14185#
14186# Prints the name of the logical switch that contains LSP.
14187lsp_to_ls () {
14188 case $1 in dnl (
14189 lp?[[11]]) echo ls1 ;; dnl (
14190 lp?[[12]]) echo ls2 ;; dnl (
14191 *) AT_FAIL_IF([:]) ;;
14192 esac
14193}
14194
14195vif_to_ls () {
14196 case $1 in dnl (
14197 vif?[[11]]) echo ls1 ;; dnl (
14198 vif?[[12]]) echo ls2 ;; dnl (
14199 *) AT_FAIL_IF([:]) ;;
14200 esac
14201}
14202
14203hv_to_num () {
14204 case $1 in dnl (
14205 hv1) echo 1 ;; dnl (
14206 hv2) echo 2 ;; dnl (
14207 *) AT_FAIL_IF([:]) ;;
14208 esac
14209}
14210
14211vif_to_num () {
14212 case $1 in dnl (
14213 vif22) echo 22 ;; dnl (
14214 vif21) echo 21 ;; dnl (
14215 *) AT_FAIL_IF([:]) ;;
14216 esac
14217}
14218
14219vif_to_hv () {
14220 case $1 in dnl (
14221 vif[[1]]?) echo hv1 ;; dnl (
14222 vif[[2]]?) echo hv2 ;; dnl (
14223 *) AT_FAIL_IF([:]) ;;
14224 esac
14225}
14226
14227vif_to_lrp () {
14228 echo router-to-`vif_to_ls $1`
14229}
14230
14231hv_to_chassis_mac () {
14232 case $1 in dnl (
14233 hv[[1]]) echo aa:bb:cc:dd:ee:11 ;; dnl (
14234 hv[[2]]) echo aa:bb:cc:dd:ee:22 ;; dnl (
14235 *) AT_FAIL_IF([:]) ;;
14236 esac
14237}
14238
14239ip_to_hex() {
14240 printf "%02x%02x%02x%02x" "$@"
14241}
14242
14243net_add n1
14244for i in 1 2; do
14245 sim_add hv$i
14246 as hv$i
14247 ovs-vsctl add-br br-phys
14248 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
14249 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
14250 ovn_attach n1 br-phys 192.168.0.$i
14251
14252 ovs-vsctl add-port br-int vif$i$i -- \
14253 set Interface vif$i$i external-ids:iface-id=lp$i$i \
14254 options:tx_pcap=hv$i/vif$i$i-tx.pcap \
14255 options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
14256 ofport-request=$i$i
14257
14258 lsp_name=lp$i$i
14259 ls_name=$(lsp_to_ls $lsp_name)
14260
14261 ovn-nbctl lsp-add $ls_name $lsp_name
14262 ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
14263 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
14264
14265 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
14266
14267done
14268
14269ovn-nbctl lr-add router
14270ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
14271ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
14272
14273ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
14274ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
14275
14276ovn-nbctl --wait=sb sync
14277#ovn-sbctl dump-flows
14278
14279ovn-nbctl show
14280ovn-sbctl show
14281
14282OVN_POPULATE_ARP
14283
14284test_ip() {
14285 # This packet has bad checksums but logical L3 routing doesn't check.
14286 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
14287 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
14288 shift; shift; shift; shift; shift
14289 hv=`vif_to_hv $inport`
14290 hv_num=`hv_to_num $hv`
14291 chassis_mac=`hv_to_chassis_mac $hv`
14292 as $hv ovs-appctl netdev-dummy/receive $inport $packet
14293 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
14294 in_ls=`vif_to_ls $inport`
14295 in_lrp=`vif_to_lrp $inport`
14296 for outport; do
14297 out_ls=`vif_to_ls $outport`
14298 if test $in_ls = $out_ls; then
14299 # Ports on the same logical switch receive exactly the same packet.
14300 echo $packet
14301 else
14302 # Routing decrements TTL and updates source and dest MAC
14303 # (and checksum).
14304 outport_num=`vif_to_num $outport`
14305 out_lrp=`vif_to_lrp $outport`
14306 echo f000000000${outport_num}aabbccddee${hv_num}${hv_num}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
14307 fi >> $outport.expected
14308 done
14309}
14310
14311# Dump a bunch of info helpful for debugging if there's a failure.
14312
14313echo "------ OVN dump ------"
14314ovn-nbctl show
14315ovn-sbctl show
14316
14317echo "------ hv1 dump ------"
14318as hv1 ovs-vsctl show
14319as hv1 ovs-vsctl list Open_Vswitch
14320
14321echo "------ hv2 dump ------"
14322as hv2 ovs-vsctl show
14323as hv2 ovs-vsctl list Open_Vswitch
14324
14325echo "Send traffic"
14326sip=`ip_to_hex 192 168 1 1`
14327dip=`ip_to_hex 192 168 2 2`
14328test_ip vif11 f00000000011 000001010203 $sip $dip vif22
14329
14330echo "----------- Post Traffic hv1 dump -----------"
14331as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
14332as hv1 ovs-appctl fdb/show br-phys
14333
14334echo "----------- Post Traffic hv2 dump -----------"
14335as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
14336as hv2 ovs-appctl fdb/show br-phys
14337
14338OVN_CHECK_PACKETS([hv2/vif22-tx.pcap], [vif22.expected])
14339
14340OVN_CLEANUP([hv1],[hv2])
14341
14342AT_CLEANUP
2a9679e3
DA
14343
14344# Run ovn-nbctl in daemon mode, change to a backup database and verify that
14345# an insert operation is not allowed.
14346AT_SETUP([ovn -- can't write to a backup database server instance])
14347ovn_start
14348on_exit 'kill $(cat ovn-nbctl.pid)'
14349export OVN_NB_DAEMON=$(ovn-nbctl --pidfile --detach)
14350
14351AT_CHECK([ovn-nbctl ls-add sw0])
14352as ovn-nb
14353AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/sync-status | grep active | wc -l], [0], [1
14354])
14355ovs-appctl -t ovsdb-server ovsdb-server/set-active-ovsdb-server tcp:192.0.2.2:6641
14356ovs-appctl -t ovsdb-server ovsdb-server/connect-active-ovsdb-server
14357AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/sync-status | grep -c backup], [0], [1
14358])
14359AT_CHECK([ovn-nbctl ls-add sw1], [1], [ignore],
14360[ovn-nbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
14361])
14362
14363AT_CLEANUP
821e1e54
LB
14364
14365AT_SETUP([ovn -- controller event])
14366AT_KEYWORDS([ovn_controller_event])
14367ovn_start
14368
14369# Create hypervisors hv[12].
14370# Add vif1[12] to hv1, vif2[12] to hv2
14371# Add all of the vifs to a single logical switch sw0.
14372
14373net_add n1
14374ovn-nbctl ls-add sw0
14375for i in 1 2; do
14376 sim_add hv$i
14377 as hv$i
14378 ovs-vsctl add-br br-phys
14379 ovn_attach n1 br-phys 192.168.0.$i
14380
14381 for j in 1 2; do
14382 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
14383 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
14384
14385 ovs-vsctl -- add-port br-int vif$i$j -- \
14386 set interface vif$i$j \
14387 external-ids:iface-id=sw0-p$i$j \
14388 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
14389 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
14390 ofport-request=$i$j
14391 done
14392done
14393
14394ovn-nbctl --wait=hv set NB_Global . options:controller_event=true
14395ovn-nbctl lb-add lb0 192.168.1.100:80 ""
14396ovn-nbctl ls-lb-add sw0 lb0
14397uuid_lb=$(ovn-nbctl --bare --columns=_uuid find load_balancer name=lb0)
14398
14399OVN_POPULATE_ARP
14400ovn-nbctl --timeout=3 --wait=hv sync
14401ovn-sbctl lflow-list
14402as hv1 ovs-ofctl dump-flows br-int
14403
14404packet="inport==\"sw0-p11\" && eth.src==00:00:00:00:00:11 && eth.dst==00:00:00:00:00:21 &&
14405 ip4 && ip.ttl==64 && ip4.src==192.168.1.11 && ip4.dst==192.168.1.100 &&
14406 tcp && tcp.src==10000 && tcp.dst==80"
14407as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
14408
14409ovn-sbctl list controller_event
14410uuid=$(ovn-sbctl list controller_event | awk '/_uuid/{print $3}')
14411AT_CHECK([ovn-sbctl get controller_event $uuid event_type], [0], [dnl
14412empty_lb_backends
14413])
14414AT_CHECK([ovn-sbctl get controller_event $uuid event_info:vip], [0], [dnl
14415"192.168.1.100:80"
14416])
14417AT_CHECK([ovn-sbctl get controller_event $uuid event_info:protocol], [0], [dnl
14418tcp
14419])
14420AT_CHECK_UNQUOTED([ovn-sbctl get controller_event $uuid event_info:load_balancer], [0], [dnl
14421"$uuid_lb"
14422])
14423AT_CHECK([ovn-sbctl get controller_event $uuid seq_num], [0], [dnl
144241
14425])
14426
14427OVN_CLEANUP([hv1], [hv2])
14428AT_CLEANUP