]> git.proxmox.com Git - mirror_ovs.git/blame - tests/ovn.at
ofproto: Support packet_outs in bundles.
[mirror_ovs.git] / tests / ovn.at
CommitLineData
49d7c759
BP
1# OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2#
3# This compares packets read from PCAP, in pcap format, to those read
4# from EXPECTED, which is a text file containing packets as hex
5# strings, one per line. If PCAP contains fewer packets than
6# EXPECTED, it waits up to 10 seconds for more packets to appear.
7#
8# The implementation is an m4 macro that is mostly implemented in
9# terms of a shell function. This reduces the size of the generated
10# testsuite file since the shell function is only emitted once even
11# when this macro is invoked many times.
12m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
20 ovs_wait_cond () {
abb37b6b
FF
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
49d7c759
BP
24 }
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
26
e4543cfe 27 sort $exp_text > expout
49d7c759
BP
28 }
29])
30m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
33
f295c17b 34AT_BANNER([OVN components])
10b1662b
BP
35
36AT_SETUP([ovn -- lexer])
37dnl For lines without =>, input and expected output are identical.
38dnl For lines with =>, input precedes => and expected output follows =>.
39AT_DATA([test-cases.txt], [dnl
40foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41"abc\u0020def" => "abc def"
42" => error("Input ends inside quoted string.")dnl "
43
2c5cbb15
RB
44$foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45$1 => error("`$' must be followed by a valid identifier.") 1
46
10b1662b
BP
47a/*b*/c => a c
48a//b c => a
49a/**/b => a b
50a/*/b => a error("`/*' without matching `*/'.")
51a/*/**/b => a b
52a/b => a error("`/' is only valid as part of `//' or `/*'.") b
53
540 1 12345 18446744073709551615
5518446744073709551616 => error("Decimal constants must be less than 2**64.")
569999999999999999999999 => error("Decimal constants must be less than 2**64.")
5701 => error("Decimal constants must not have leading zeros.")
58
590/0
600/1
611/0 => error("Value contains unmasked 1-bits.")
621/1
63128/384
641/3
651/ => error("Integer constant expected.")
66
671/0x123 => error("Value and mask have incompatible formats.")
68
690x1234
700x01234 => 0x1234
710x0 => 0
720x000 => 0
730xfedcba9876543210
740XFEDCBA9876543210 => 0xfedcba9876543210
750xfedcba9876543210fedcba9876543210
10b1662b
BP
760x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
770x => error("Hex digits expected following 0x.")
780X => error("Hex digits expected following 0X.")
790x0/0x0 => 0/0
800x0/0x1 => 0/0x1
810x1/0x0 => error("Value contains unmasked 1-bits.")
820xffff/0x1ffff
830x. => error("Invalid syntax in hexadecimal constant.")
84
85192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86256.1.2.3 => error("Invalid numeric constant.")
87192.168.0.0/16
88192.168.0.0/255.255.0.0 => 192.168.0.0/16
89192.168.0.0/255.255.255.0 => 192.168.0.0/24
90192.168.0.0/255.255.0.255
91192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
92192.168.0.0/32
93192.168.0.0/255.255.255.255 => 192.168.0.0/32
52c0fc39 941.2.3.4:5 => 1.2.3.4 : 5
10b1662b
BP
95
96::
97::1
98ff00::1234 => ff00::1234
992001:db8:85a3::8a2e:370:7334
1002001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
1012001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
102::ffff:192.0.2.128
103::ffff:c000:0280 => ::ffff:192.0.2.128
104::1/::1
105::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
106::1/128
107ff00::/8
108ff00::/ff00:: => ff00::/8
109
11001:23:45:67:ab:cd
11101:23:45:67:AB:CD => 01:23:45:67:ab:cd
112fe:dc:ba:98:76:54
113FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
11401:00:00:00:00:00/01:00:00:00:00:00
115ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118fe:x => error("Invalid numeric constant.")
11900:01:02:03:04:x => error("Invalid numeric constant.")
120
a20c96c6 121# Test that operators are tokenized as expected, even without white space.
52c0fc39 122(){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
10b1662b
BP
123& => error("`&' is only valid as part of `&&'.")
124| => error("`|' is only valid as part of `||'.")
56091efe 125- => error("`-' is only valid as part of `--'.")
10b1662b
BP
126
127^ => error("Invalid character `^' in input.")
128])
129AT_CAPTURE_FILE([input.txt])
130sed 's/ =>.*//' test-cases.txt > input.txt
131sed 's/.* => //' test-cases.txt > expout
132AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
133AT_CLEANUP
e0840f11 134
7700eea0
BP
135dnl The OVN expression parser needs to know what fields overlap with one
136dnl another. This test therefore verifies that all the smaller registers
137dnl are defined as terms of subfields of the larger ones.
138dnl
139dnl When we add or remove registers this test needs to be updated, of course.
140AT_SETUP([ovn -- registers])
141AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142[[reg0 = xxreg0[96..127]
143reg1 = xxreg0[64..95]
144reg2 = xxreg0[32..63]
145reg3 = xxreg0[0..31]
146reg4 = xxreg1[96..127]
147reg5 = xxreg1[64..95]
148reg6 = xxreg1[32..63]
149reg7 = xxreg1[0..31]
150reg8 = xreg4[32..63]
151reg9 = xreg4[0..31]
152xreg0 = xxreg0[64..127]
153xreg1 = xxreg0[0..63]
154xreg2 = xxreg1[64..127]
155xreg3 = xxreg1[0..63]
156xreg4 = OXM_OF_PKT_REG4
157xxreg0 = NXM_NX_XXREG0
158xxreg1 = NXM_NX_XXREG1
159]])
160AT_CLEANUP
161
2277b860
BP
162dnl Check that the OVN conntrack field definitions are correct.
163AT_SETUP([ovn -- conntrack fields])
164AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
165[[ct.est = ct_state[1]
166ct.inv = ct_state[4]
167ct.new = ct_state[0]
168ct.rel = ct_state[2]
169ct.rpl = ct_state[3]
170ct.trk = ct_state[5]
171ct_label = NXM_NX_CT_LABEL
172ct_mark = NXM_NX_CT_MARK
173ct_state = NXM_NX_CT_STATE
174]])
175AT_CLEANUP
176
e0840f11
BP
177AT_SETUP([ovn -- expression parser])
178dnl For lines without =>, input and expected output are identical.
179dnl For lines with =>, input precedes => and expected output follows =>.
180AT_DATA([test-cases.txt], [[
181eth.type == 0x800
182eth.type==0x800 => eth.type == 0x800
183eth.type[0..15] == 0x800 => eth.type == 0x800
184
185vlan.present
186vlan.present == 1 => vlan.present
187!(vlan.present == 0) => vlan.present
188!(vlan.present != 1) => vlan.present
189!vlan.present
190vlan.present == 0 => !vlan.present
191vlan.present != 1 => !vlan.present
192!(vlan.present == 1) => !vlan.present
193!(vlan.present != 0) => !vlan.present
194
195eth.dst[0]
196eth.dst[0] == 1 => eth.dst[0]
197eth.dst[0] != 0 => eth.dst[0]
198!(eth.dst[0] == 0) => eth.dst[0]
199!(eth.dst[0] != 1) => eth.dst[0]
200
201!eth.dst[0]
202eth.dst[0] == 0 => !eth.dst[0]
203eth.dst[0] != 1 => !eth.dst[0]
204!(eth.dst[0] == 1) => !eth.dst[0]
205!(eth.dst[0] != 0) => !eth.dst[0]
206
207vlan.tci[12..15] == 0x3
208vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
209vlan.tci[12..15] != 0x3
210vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
211
212!vlan.pcp => vlan.pcp == 0
213!(vlan.pcp) => vlan.pcp == 0
214vlan.pcp == 0x4
215vlan.pcp != 0x4
216vlan.pcp > 0x4
217vlan.pcp >= 0x4
218vlan.pcp < 0x4
219vlan.pcp <= 0x4
220!(vlan.pcp != 0x4) => vlan.pcp == 0x4
221!(vlan.pcp == 0x4) => vlan.pcp != 0x4
222!(vlan.pcp <= 0x4) => vlan.pcp > 0x4
223!(vlan.pcp < 0x4) => vlan.pcp >= 0x4
224!(vlan.pcp >= 0x4) => vlan.pcp < 0x4
225!(vlan.pcp > 0x4) => vlan.pcp <= 0x4
2260x4 == vlan.pcp => vlan.pcp == 0x4
2270x4 != vlan.pcp => vlan.pcp != 0x4
2280x4 < vlan.pcp => vlan.pcp > 0x4
2290x4 <= vlan.pcp => vlan.pcp >= 0x4
2300x4 > vlan.pcp => vlan.pcp < 0x4
2310x4 >= vlan.pcp => vlan.pcp <= 0x4
232!(0x4 != vlan.pcp) => vlan.pcp == 0x4
233!(0x4 == vlan.pcp) => vlan.pcp != 0x4
234!(0x4 >= vlan.pcp) => vlan.pcp > 0x4
235!(0x4 > vlan.pcp) => vlan.pcp >= 0x4
236!(0x4 <= vlan.pcp) => vlan.pcp < 0x4
237!(0x4 < vlan.pcp) => vlan.pcp <= 0x4
238
2391 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
2401 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2411 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
2421 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
2431 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2444 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
2454 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
2464 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
2474 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
248!(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
249!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
250!(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
251!(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
252!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
253!(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
254!(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
255!(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
256!(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
257
258vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
259vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
260
261vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
262vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
263
264vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
265vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
266vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
267
268ip4.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
269ip6.src == ::1 => ip6.src == 0x1
270
271ip4.src == 1.2.3.4 => ip4.src == 0x1020304
272ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
273ip6.src == ::1 => ip6.src == 0x1
274
2751
2760
277!1 => 0
278!0 => 1
279
280inport == "eth0"
281!(inport != "eth0") => inport == "eth0"
282
3b7cb7e1
BP
283ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
284inport == 1 => String field inport is not compatible with integer constant.
76da94b5 285ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
e0840f11
BP
286
287ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
288eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
289vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
290
291inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
292!(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
293eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
294!(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
76da94b5 295inport = "eth0" => Syntax error at `=' expecting relational operator.
e0840f11
BP
296
297123 == 123 => Syntax error at `123' expecting field name.
298
2c5cbb15
RB
299$name => Syntax error at `$name' expecting address set name.
300
e0840f11
BP
301123 == xyzzy => Syntax error at `xyzzy' expecting field name.
302xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
303
304inport[1] == 1 => Cannot select subfield of string field inport.
305
306eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
307eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
308eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
309
310eth.type[5!] => Syntax error at `!' expecting `@:>@'.
311
312eth.type[5..1] => Invalid bit range 5 to 1.
313
314eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
315
316eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
317
318eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
319
320!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
321
322123 => Syntax error at end of input expecting relational operator.
323
324123 x => Syntax error at `x' expecting relational operator.
325
326{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
327
328eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
329
330(1 x) => Syntax error at `x' expecting `)'.
331
332!0x800 != eth.type => Missing parentheses around operand of !.
333
334eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
335
336eth.dst == {} => Syntax error at `}' expecting constant.
337
338eth.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).
339
3b7cb7e1 340ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
e0840f11
BP
341
3421 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
8b34ccda 343
9aef3c1b 344eth.dst[40] x => Syntax error at `x' expecting end of input.
ea382567
RB
345
346ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
347eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
e0840f11
BP
348]])
349sed 's/ =>.*//' test-cases.txt > input.txt
350sed 's/.* => //' test-cases.txt > expout
351AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
352AT_CLEANUP
353
354AT_SETUP([ovn -- expression annotation])
355dnl Input precedes =>, expected output follows =>.
356AT_DATA([test-cases.txt], [[
357ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
358ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
359ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
360ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
361ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
362
363ip => eth.type == 0x800 || eth.type == 0x86dd
364ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
365ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
366ip > 0 => Only == and != operators may be used with nominal field ip.
367!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
368ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
369
370vlan.present => vlan.tci[12]
371!vlan.present => !vlan.tci[12]
372
373!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
374vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
7700eea0 375!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
e0840f11
BP
376
377ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
378!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
379ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
380
381bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
382self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
383mutual_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'.
384mutual_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'.
385]])
386sed 's/ =>.*//' test-cases.txt > input.txt
387sed 's/.* => //' test-cases.txt > expout
388AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
389AT_CLEANUP
390
9d4aecca 391AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 392AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 393 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
394])
395AT_CLEANUP
396
9d4aecca 397AT_SETUP([ovn -- 2-term expression conversion])
e0840f11 398AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
9d4aecca 399 [Tested converting 570 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
400])
401AT_CLEANUP
402
9d4aecca 403AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 404AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
9d4aecca 405 [Tested converting 62418 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
406])
407AT_CLEANUP
408
9d4aecca
BP
409AT_SETUP([ovn -- 3-term numeric expression simplification])
410AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
411 [Tested simplifying 477138 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
412])
413AT_CLEANUP
414
9d4aecca
BP
415AT_SETUP([ovn -- 4-term string expression simplification])
416AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
417 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
418])
419AT_CLEANUP
420
9d4aecca
BP
421AT_SETUP([ovn -- 3-term mixed expression simplification])
422AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
423 [Tested simplifying 124410 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
424])
425AT_CLEANUP
426
9d4aecca
BP
427AT_SETUP([ovn -- 4-term numeric expression normalization])
428AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
429 [Tested normalizing 1207162 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
430])
431AT_CLEANUP
432
9d4aecca
BP
433AT_SETUP([ovn -- 4-term string expression normalization])
434AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
435 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
436])
437AT_CLEANUP
438
439AT_SETUP([ovn -- 4-term mixed expression normalization])
440AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
441 [Tested normalizing 128282 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
442])
443AT_CLEANUP
444
445AT_SETUP([ovn -- 5-term numeric expression normalization])
446AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
447 [Tested normalizing 368550 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
448])
449AT_CLEANUP
450
451AT_SETUP([ovn -- 5-term string expression normalization])
452AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
453 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
454])
455AT_CLEANUP
456
457AT_SETUP([ovn -- 5-term mixed expression normalization])
458AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
459 [Tested normalizing 116550 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
460])
461AT_CLEANUP
462
463AT_SETUP([ovn -- 4-term numeric expressions to flows])
464AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
465 [Tested converting to flows 128282 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
466])
467AT_CLEANUP
468
469AT_SETUP([ovn -- 4-term string expressions to flows])
470AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
471 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
472])
473AT_CLEANUP
474
475AT_SETUP([ovn -- 4-term mixed expressions to flows])
476AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
477 [Tested converting to flows 37994 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
478])
479AT_CLEANUP
480
481AT_SETUP([ovn -- 3-term numeric expressions to flows])
482AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
483 [Tested converting to flows 38394 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
484])
485AT_CLEANUP
f386a8a7
BP
486
487AT_SETUP([ovn -- converting expressions to flows -- string fields])
488expr_to_flow () {
489 echo "$1" | ovstest test-ovn expr-to-flows | sort
490}
cc5e28d8 491AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 492])
cc5e28d8 493AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
494])
495AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
496])
497AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
498ip,reg14=0x5
499ipv6,reg14=0x5
f386a8a7
BP
500])
501AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
502ip,reg14=0x6
503ipv6,reg14=0x6
f386a8a7
BP
504])
505AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
506])
507AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
508[reg14=0x5
509reg14=0x6
510reg14=0xfffe
f386a8a7
BP
511])
512AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
513ip,reg14=0x5
514ip,reg14=0x6
515ipv6,reg14=0x5
516ipv6,reg14=0x6
f386a8a7 517])
9d4aecca
BP
518AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
519(no flows)
520])
f386a8a7 521AT_CLEANUP
3b7cb7e1 522
2c5cbb15
RB
523AT_SETUP([ovn -- converting expressions to flows -- address sets])
524expr_to_flow () {
525 echo "$1" | ovstest test-ovn expr-to-flows | sort
526}
527AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
528ip,nw_src=10.0.0.1
529ip,nw_src=10.0.0.2
530ip,nw_src=10.0.0.3
531])
532AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
533ip,nw_src=10.0.0.1
534ip,nw_src=10.0.0.2
535ip,nw_src=10.0.0.3
536])
537AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
538ip,nw_src=1.2.3.4
539ip,nw_src=10.0.0.1
540ip,nw_src=10.0.0.2
541ip,nw_src=10.0.0.3
542])
543AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
544ip,nw_src=1.2.0.0/20
545ip,nw_src=10.0.0.1
546ip,nw_src=10.0.0.2
547ip,nw_src=10.0.0.3
548ip,nw_src=5.5.5.0/24
549])
550AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
551ipv6,ipv6_src=::1
552ipv6,ipv6_src=::2
553ipv6,ipv6_src=::3
554])
555AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
556ipv6,ipv6_src=::1
557ipv6,ipv6_src=::2
558ipv6,ipv6_src=::3
559ipv6,ipv6_src=::4
560])
561AT_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
562dl_src=00:00:00:00:00:01
563dl_src=00:00:00:00:00:02
564dl_src=00:00:00:00:00:03
565])
566AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
567dl_src=00:00:00:00:00:01
568dl_src=00:00:00:00:00:02
569dl_src=00:00:00:00:00:03
570])
ea382567
RB
571AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
572dl_src=00:00:00:00:00:01
573dl_src=00:00:00:00:00:02
574dl_src=00:00:00:00:00:03
575dl_src=ba:be:be:ef:de:ad
576])
2c5cbb15
RB
577AT_CLEANUP
578
3b7cb7e1 579AT_SETUP([ovn -- action parsing])
d5a76da4
BP
580dnl Unindented text is input (a set of OVN logical actions).
581dnl Indented text is expected output.
582AT_DATA([test-cases.txt],
583[[# drop
584drop;
585 encodes as drop
586drop; next;
587 Syntax error at `next' expecting end of input.
588next; drop;
589 Syntax error at `drop' expecting action.
5f822129
BP
590
591# output
d5a76da4
BP
592output;
593 encodes as resubmit(,64)
5f822129
BP
594
595# next
d5a76da4
BP
596next;
597 formats as next(11);
598 encodes as resubmit(,27)
599next(11);
600 encodes as resubmit(,27)
601next(0);
602 encodes as resubmit(,16)
603next(15);
604 encodes as resubmit(,31)
605
606next();
607 Syntax error at `)' expecting small integer.
608next(10;
609 Syntax error at `;' expecting `)'.
610next(16);
611 "next" argument must be in range 0 to 15.
5f822129
BP
612
613# Loading a constant value.
d5a76da4
BP
614tcp.dst=80;
615 formats as tcp.dst = 80;
616 encodes as set_field:80->tcp_dst
617 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
618eth.dst[40] = 1;
619 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
620vlan.pcp = 2;
621 encodes as set_field:0x4000/0xe000->vlan_tci
622 has prereqs vlan.tci[12]
623vlan.tci[13..15] = 2;
624 encodes as set_field:0x4000/0xe000->vlan_tci
625inport = "";
626 encodes as set_field:0->reg14
627ip.ttl=4;
628 formats as ip.ttl = 4;
629 encodes as set_field:4->nw_ttl
630 has prereqs eth.type == 0x800 || eth.type == 0x86dd
631outport="eth0"; next; outport="LOCAL"; next;
632 formats as outport = "eth0"; next(11); outport = "LOCAL"; next(11);
633 encodes as set_field:0x5->reg15,resubmit(,27),set_field:0xfffe->reg15,resubmit(,27)
634
635inport[1] = 1;
636 Cannot select subfield of string field inport.
637ip.proto[1] = 1;
638 Cannot select subfield of nominal field ip.proto.
639eth.dst[40] == 1;
640 Syntax error at `==' expecting `=' or `<->'.
641ip = 1;
642 Predicate symbol ip used where lvalue required.
643ip.proto = 6;
644 Field ip.proto is not modifiable.
645inport = {"a", "b"};
646 Syntax error at `{' expecting constant.
647inport = {};
648 Syntax error at `{' expecting constant.
649bad_prereq = 123;
650 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
651self_recurse = 123;
652 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'.
653vlan.present = 0;
654 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
655
656# Moving one field into another.
d5a76da4
BP
657reg0=reg1;
658 formats as reg0 = reg1;
659 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
660vlan.pcp = reg0[0..2];
661 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
662 has prereqs vlan.tci[12]
663reg0[10] = vlan.pcp[1];
664 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
665 has prereqs vlan.tci[12]
666outport = inport;
667 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
668
669reg0[0] = vlan.present;
670 Predicate symbol vlan.present used where lvalue required.
671reg0 = reg1[0..10];
672 Can't assign 11-bit value to 32-bit destination.
673inport = reg0;
674 Can't assign integer field (reg0) to string field (inport).
675inport = big_string;
676 String fields inport and big_string are incompatible for assignment.
677ip.proto = reg0[0..7];
678 Field ip.proto is not modifiable.
5f822129
BP
679
680# Exchanging fields.
d5a76da4
BP
681reg0 <-> reg1;
682 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]
683vlan.pcp <-> reg0[0..2];
684 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]
685 has prereqs vlan.tci[12]
686reg0[10] <-> vlan.pcp[1];
687 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
688 has prereqs vlan.tci[12]
689outport <-> inport;
690 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
691
692reg0[0] <-> vlan.present;
693 Predicate symbol vlan.present used where lvalue required.
694reg0 <-> reg1[0..10];
695 Can't exchange 32-bit field with 11-bit field.
696inport <-> reg0;
697 Can't exchange string field (inport) with integer field (reg0).
698inport <-> big_string;
699 String fields inport and big_string are incompatible for exchange.
700ip.proto <-> reg0[0..7];
701 Field ip.proto is not modifiable.
702reg0[0..7] <-> ip.proto;
703 Field ip.proto is not modifiable.
5f822129
BP
704
705# TTL decrement.
d5a76da4
BP
706ip.ttl--;
707 encodes as dec_ttl
708 has prereqs ip
709ip.ttl
710 Syntax error at end of input expecting `--'.
5f822129 711
467085fd 712# load balancing.
d5a76da4
BP
713ct_lb;
714 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
715 has prereqs ip
716ct_lb();
717 formats as ct_lb;
718 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
719 has prereqs ip
720ct_lb(192.168.1.2:80, 192.168.1.3:80);
721 encodes as group:1
722 has prereqs ip
723ct_lb(192.168.1.2, 192.168.1.3, );
724 formats as ct_lb(192.168.1.2, 192.168.1.3);
725 encodes as group:2
726 has prereqs ip
727
728ct_lb(192.168.1.2:);
729 Syntax error at `)' expecting port number.
730ct_lb(192.168.1.2:123456);
731 Syntax error at `123456' expecting port number.
732ct_lb(foo);
733 Syntax error at `foo' expecting IPv4 address.
734
735# ct_next
736ct_next;
737 encodes as ct(table=27,zone=NXM_NX_REG13[0..15])
738 has prereqs ip
739
740# ct_commit
741ct_commit;
742 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
743 has prereqs ip
744ct_commit();
745 formats as ct_commit;
746 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
747 has prereqs ip
748ct_commit(ct_mark=1);
749 formats as ct_commit(ct_mark=0x1);
750 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
751 has prereqs ip
752ct_commit(ct_mark=1/1);
753 formats as ct_commit(ct_mark=0x1/0x1);
754 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
755 has prereqs ip
756ct_commit(ct_label=1);
757 formats as ct_commit(ct_label=0x1);
758 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
759 has prereqs ip
760ct_commit(ct_label=1/1);
761 formats as ct_commit(ct_label=0x1/0x1);
762 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
763 has prereqs ip
764ct_commit(ct_mark=1, ct_label=2);
765 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
766 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
767 has prereqs ip
768
769ct_commit(ct_label=0x01020304050607080910111213141516);
770 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
771 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
772 has prereqs ip
773ct_commit(ct_label=0x181716151413121110090807060504030201);
774 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
775 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
776 has prereqs ip
777ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
778 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
779 has prereqs ip
780ct_commit(ct_label=18446744073709551615);
781 formats as ct_commit(ct_label=0xffffffffffffffff);
782 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
783 has prereqs ip
784ct_commit(ct_label=18446744073709551616);
785 Decimal constants must be less than 2**64.
786
787# ct_dnat
788ct_dnat;
789 encodes as ct(table=27,zone=NXM_NX_REG11[0..15],nat)
790 has prereqs ip
791ct_dnat(192.168.1.2);
792 encodes as ct(commit,table=27,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
793 has prereqs ip
794
795ct_dnat(192.168.1.2, 192.168.1.3);
796 Syntax error at `,' expecting `)'.
797ct_dnat(foo);
798 Syntax error at `foo' expecting IPv4 address.
799ct_dnat(foo, bar);
800 Syntax error at `foo' expecting IPv4 address.
801ct_dnat();
802 Syntax error at `)' expecting IPv4 address.
803
804# ct_snat
805ct_snat;
806 encodes as ct(zone=NXM_NX_REG12[0..15],nat)
807 has prereqs ip
808ct_snat(192.168.1.2);
809 encodes as ct(commit,table=27,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
810 has prereqs ip
811
812ct_snat(192.168.1.2, 192.168.1.3);
813 Syntax error at `,' expecting `)'.
814ct_snat(foo);
815 Syntax error at `foo' expecting IPv4 address.
816ct_snat(foo, bar);
817 Syntax error at `foo' expecting IPv4 address.
818ct_snat();
819 Syntax error at `)' expecting IPv4 address.
de297547 820
6335d074 821# arp
d5a76da4
BP
822arp { eth.dst = ff:ff:ff:ff:ff:ff; output; };
823 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)
824 has prereqs ip4
6335d074 825
0bac7164 826# get_arp
d5a76da4
BP
827get_arp(outport, ip4.dst);
828 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[]
829 has prereqs eth.type == 0x800
830get_arp(inport, reg0);
831 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[]
832
833get_arp;
834 Syntax error at `;' expecting `('.
835get_arp();
836 Syntax error at `)' expecting field name.
837get_arp(inport);
838 Syntax error at `)' expecting `,'.
839get_arp(inport ip4.dst);
840 Syntax error at `ip4.dst' expecting `,'.
841get_arp(inport, ip4.dst;
842 Syntax error at `;' expecting `)'.
843get_arp(inport, eth.dst);
844 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
845get_arp(inport, outport);
846 Cannot use string field outport where numeric field is required.
847get_arp(reg0, ip4.dst);
848 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
849
850# put_arp
d5a76da4
BP
851put_arp(inport, arp.spa, arp.sha);
852 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[]
853 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 854
42814145 855# put_dhcp_opts
d5a76da4
BP
856reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
857 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)
858reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
859 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain = "ovn.org");
860 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67,pause)
861reg0[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);
862 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);
863 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00,pause)
864
865reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
866 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
867reg1[0] = put_dhcp_opts();
868 put_dhcp_opts requires offerip to be specified.
869reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
870 Syntax error at `x' expecting DHCPv4 option name.
871reg1[0] = put_dhcp_opts(router = 10.0.0.1);
872 put_dhcp_opts requires offerip to be specified.
873reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
874 Syntax error at `"hi"'.
875reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
876 Syntax error at `xyzzy' expecting DHCPv4 option name.
877reg1[0] = put_dhcp_opts(offerip="xyzzy");
878 DHCPv4 option offerip requires numeric value.
879reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
880 DHCPv4 option domain requires string value.
42814145 881
f8a8db39 882# nd_na
d5a76da4
BP
883nd_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; };
884 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
885 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)
886 has prereqs nd_ns
e75451fe 887
c34a87b6 888# get_nd
d5a76da4
BP
889get_nd(outport, ip6.dst);
890 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[]
891 has prereqs eth.type == 0x86dd
892get_nd(inport, xxreg0);
893 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[]
894get_nd;
895 Syntax error at `;' expecting `('.
896get_nd();
897 Syntax error at `)' expecting field name.
898get_nd(inport);
899 Syntax error at `)' expecting `,'.
900get_nd(inport ip6.dst);
901 Syntax error at `ip6.dst' expecting `,'.
902get_nd(inport, ip6.dst;
903 Syntax error at `;' expecting `)'.
904get_nd(inport, eth.dst);
905 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
906get_nd(inport, outport);
907 Cannot use string field outport where numeric field is required.
908get_nd(xxreg0, ip6.dst);
909 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
910
911# put_nd
d5a76da4
BP
912put_nd(inport, nd.target, nd.sll);
913 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[]
914 has prereqs ((icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd)) || (icmp6.type == 0x88 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd))) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
c34a87b6 915
01cfdb2f 916# put_dhcpv6_opts
d5a76da4
BP
917reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
918 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.05.00.10.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.02.00.06.00.00.00.00.00.10.02,pause)
919reg1[0] = put_dhcpv6_opts();
920 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
921reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
922 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
923 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.17.00.20.00.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
924reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
925 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
926 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.02.00.06.00.12.34.56.78.9a.bc.17.00.20.00.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
BP
927reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
928 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.18.00.07.00.6f.76.6e.2e.6f.72.67,pause)
929reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
930 Syntax error at `x' expecting DHCPv6 option name.
931reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
932 Syntax error at `"hi"'.
933reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
934 Syntax error at `xyzzy' expecting DHCPv6 option name.
935reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
936 DHCPv6 option ia_addr requires numeric value.
937reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
938 DHCPv6 option domain_search requires string value.
01cfdb2f 939
5f822129 940# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
941ip4.src = ip6.src[0..31];
942 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
943 has prereqs eth.type == 0x800 && eth.type == 0x86dd
944ip4.src <-> ip6.src[0..31];
945 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[]
946 has prereqs eth.type == 0x800 && eth.type == 0x86dd
947
948# Miscellaneous negative tests.
949;
950 Syntax error at `;'.
951xyzzy;
952 Syntax error at `xyzzy' expecting action.
953next; 123;
954 Syntax error at `123'.
955next; xyzzy;
956 Syntax error at `xyzzy' expecting action.
957next
9aef3c1b 958 Syntax error at end of input expecting `;'.
3b7cb7e1 959]])
d5a76da4
BP
960sed '/^[[ ]]/d' test-cases.txt > input.txt
961cp test-cases.txt expout
3b7cb7e1
BP
962AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
963AT_CLEANUP
f295c17b
BP
964
965AT_BANNER([OVN end-to-end tests])
966
9975d7be
BP
967# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
968AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 969AT_KEYWORDS([ovnarp])
f295c17b
BP
970AT_SKIP_IF([test $HAVE_PYTHON = no])
971ovn_start
972
973# Create hypervisors hv[123].
9975d7be 974# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
975# Add all of the vifs to a single logical switch lsw0.
976# Turn on port security on all the vifs except vif[123]1.
977# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
978# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 979ovn-nbctl ls-add lsw0
f295c17b
BP
980net_add n1
981for i in 1 2 3; do
982 sim_add hv$i
983 as hv$i
984 ovs-vsctl add-br br-phys
985 ovn_attach n1 br-phys 192.168.0.$i
986
987 for j in 1 2 3; do
988 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 989 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 990 if test $j = 1; then
31ed1192 991 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 992 else
7dc88496
NS
993 if test $j = 3; then
994 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
995 else
996 ip_addrs="192.168.0.$i$j"
997 fi
31ed1192
JP
998 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
999 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1000 fi
1001 done
1002done
1003ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1004ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1005ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1006ovn-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\"
1007ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b
BP
1008
1009# Pre-populate the hypervisors' ARP tables so that we don't lose any
1010# packets for ARP resolution (native tunneling doesn't queue packets
1011# for ARP resolution).
1012ovn_populate_arp
1013
1014# Allow some time for ovn-northd and ovn-controller to catch up.
1015# XXX This should be more systematic.
1016sleep 1
611099dc 1017
57d143eb
HZ
1018# Given the name of a logical port, prints the name of the hypervisor
1019# on which it is located.
1020vif_to_hv() {
1021 echo hv${1%?}
1022}
1023
f295c17b
BP
1024# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1025#
1026# This shell function causes a packet to be received on INPORT. The packet's
1027# content has Ethernet destination DST and source SRC (each exactly 12 hex
1028# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1029# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1030# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1031for i in 1 2 3; do
1032 for j in 1 2 3; do
1033 : > $i$j.expected
1034 done
1035done
1036test_packet() {
1037 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1038 hv=`vif_to_hv $inport`
f295c17b
BP
1039 vif=vif$inport
1040 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1041 for outport; do
e4543cfe 1042 echo $packet >> $outport.expected
f295c17b
BP
1043 done
1044}
1045
57d143eb
HZ
1046# test_arp INPORT SHA SPA TPA [REPLY_HA]
1047#
1048# Causes a packet to be received on INPORT. The packet is an ARP
1049# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1050# it should be the hardware address of the target to expect to receive in an
1051# ARP reply; otherwise no reply is expected.
1052#
31ed1192 1053# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1054# SHA and REPLY_HA are each 12 hex digits.
1055# SPA and TPA are each 8 hex digits.
1056test_arp() {
1057 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1058 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1059 hv=`vif_to_hv $inport`
1060 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1061
92f9822b 1062 if test X$reply_ha = X; then
57d143eb
HZ
1063 # Expect to receive the broadcast ARP on the other logical switch ports
1064 # if no reply is expected.
1065 local i j
1066 for i in 1 2 3; do
1067 for j in 1 2 3; do
1068 if test $i$j != $inport; then
1069 echo $request >> $i$j.expected
1070 fi
1071 done
1072 done
1073 else
1074 # Expect to receive the reply, if any.
1075 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1076 echo $reply >> $inport.expected
1077 fi
1078}
1079
1080ip_to_hex() {
1081 printf "%02x%02x%02x%02x" "$@"
1082}
1083
f295c17b
BP
1084# Send packets between all pairs of source and destination ports:
1085#
31ed1192
JP
1086# 1. Unicast packets are delivered to exactly one logical switch port
1087# (except that packets destined to their input ports are dropped).
f295c17b 1088#
31ed1192
JP
1089# 2. Broadcast and multicast are delivered to all logical switch ports
1090# except the input port.
f295c17b 1091#
ea46a4e9 1092# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1093# MAC address.
1094#
ea46a4e9 1095# 4. The switch drops all packets with a VLAN tag.
f295c17b 1096#
ea46a4e9 1097# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1098# affects behavior when port security is turned off, since otherwise port
1099# security would drop the packet anyway.)
1100#
ea46a4e9 1101# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1102# switch ports with "unknown" among their MAC addresses (and port
1103# security disabled).
f295c17b 1104#
ea46a4e9 1105# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1106#
ea46a4e9 1107# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb
HZ
1108#
1109# 9. ARP requests to known IPs are responded directly.
1110#
1111# 10. No response to ARP requests for unknown IPs.
4acd1e87 1112
f295c17b
BP
1113for is in 1 2 3; do
1114 for js in 1 2 3; do
1115 s=$is$js
1116 bcast=
4d5c43d5
JP
1117 unknown=
1118 bacl2=
1119 bacl3=
f295c17b
BP
1120 for id in 1 2 3; do
1121 for jd in 1 2 3; do
1122 d=$id$jd
1123
1124 if test $d != $s; then unicast=$d; else unicast=; fi
1125 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1126
1127 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1128 impersonate=$d
1129 else
1130 impersonate=
1131 fi
f295c17b
BP
1132 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1133
4d5c43d5
JP
1134 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1135 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1136 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1137 # Source of 11, 21, or 31 and dest of 33 should be dropped
1138 # due to the 4th ACL that uses address_set(set1).
1139 acl4=
1140 else
1141 acl4=$d
1142 fi
f295c17b
BP
1143 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1144 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1145 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1146 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
f295c17b
BP
1147
1148 test_packet $s f000000000$d f00000000055 810000091234 #4
1149 test_packet $s f000000000$d 0100000000$s $s$d #5
1150
4d5c43d5
JP
1151 if test $d != $s && test $jd = 1; then
1152 unknown="$unknown $d"
1153 fi
f295c17b
BP
1154 bcast="$bcast $unicast"
1155 bacl2="$bacl2 $acl2"
1156 bacl3="$bacl3 $acl3"
57d143eb
HZ
1157
1158 sip=`ip_to_hex 192 168 0 $i$j`
1159 tip=`ip_to_hex 192 168 0 $id$jd`
1160 tip_unknown=`ip_to_hex 11 11 11 11`
1161 test_arp $s f000000000$s $sip $tip f000000000$d #9
1162 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1163
1164 if test $jd = 3; then
31ed1192 1165 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496
NS
1166 tip=`ip_to_hex 192 169 0 $id$jd`
1167 test_arp $s f000000000$s $sip $tip f000000000$d #9
1168 fi
f295c17b
BP
1169 done
1170 done
1171
4d5c43d5 1172 # Broadcast and multicast.
f295c17b
BP
1173 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1174 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1175 if test $js = 1; then
f295c17b
BP
1176 bcast_impersonate=$bcast
1177 else
4d5c43d5
JP
1178 bcast_impersonate=
1179 fi
f295c17b
BP
1180 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1181
1182 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1183
1184 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1185 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1186 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1187 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1188 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1189 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1190 done
1191done
1192
7dc88496
NS
1193# set address for lp13 with invalid characters.
1194# lp13 should be configured with only 192.168.0.13.
31ed1192 1195ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1196
1197# Allow some time for ovn-northd and ovn-controller to catch up.
1198# XXX This should be more systematic.
1199sleep 1
1200
7dc88496
NS
1201sip=`ip_to_hex 192 168 0 11`
1202tip=`ip_to_hex 192 168 0 13`
1203test_arp 11 f00000000011 $sip $tip f00000000013
1204
1205tip=`ip_to_hex 192 169 0 13`
1206#arp request for 192.169.0.13 should be flooded
1207test_arp 11 f00000000011 $sip $tip
1208
91125642 1209# dump information and flows with counters
bb0c41d3
RM
1210ovn-sbctl dump-flows -- list multicast_group
1211
1212echo "------ hv1 dump ------"
1213as hv1 ovs-vsctl show
1214as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1215
1216echo "------ hv2 dump ------"
1217as hv2 ovs-vsctl show
1218as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1219
1220echo "------ hv3 dump ------"
1221as hv3 ovs-vsctl show
1222as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1223
f295c17b
BP
1224# Now check the packets actually received against the ones expected.
1225for i in 1 2 3; do
1226 for j in 1 2 3; do
49d7c759 1227 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1228 done
1229done
fcde56f5 1230
7a8f15e0 1231OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1232
f295c17b 1233AT_CLEANUP
eb6b08eb 1234
4acd1e87
BP
1235AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1236AT_SKIP_IF([test $HAVE_PYTHON = no])
1237ovn_start
1238
1239# Create a logical switch and some logical ports.
1240# Turn on port security on all lports except ls1.
1241# Make ls1 a destination for unknown MACs.
1242# Add some ACLs for Ethertypes 1234, 1235, 1236.
1243ovn-nbctl ls-add lsw0
1244ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1245for i in 1 2 3; do
1246 ovn-nbctl lsp-add lsw0 lp$i
1247 ovn-sbctl lsp-bind lp$i hv0
1248 if test $i = 1; then
abb37b6b 1249 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1250 else
abb37b6b
FF
1251 if test $i = 3; then
1252 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1253 else
1254 ip_addrs="192.168.0.$i"
1255 fi
1256 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1257 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
4acd1e87
BP
1258 fi
1259done
1260ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1261ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1262ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1263ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1264ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1265
1266ovn-nbctl --wait=sb sync
1267on_exit 'kill `cat ovn-trace.pid`'
1268ovn-trace --detach --pidfile --no-chdir
1269
1270# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1271#
1272# This shell function causes a packet to be received on INPORT. The packet's
1273# content has Ethernet destination DST and source SRC (each exactly 12 hex
1274# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1275# more) list the VIFs on which the packet should be received. INPORT and the
1276# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1277test_packet() {
1278 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1279 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1280 while :; do
abb37b6b
FF
1281 case $1 in # (
1282 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1283 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1284 *) break ;;
1285 esac
4acd1e87
BP
1286 done
1287 for outport; do
abb37b6b 1288 echo "output(\"lp$outport\");"
4acd1e87
BP
1289 done > expout
1290
1291 AT_CAPTURE_FILE([trace])
1292 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1293}
1294
1295# test_arp INPORT SHA SPA TPA [REPLY_HA]
1296#
1297# Causes a packet to be received on INPORT. The packet is an ARP
1298# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1299# it should be the hardware address of the target to expect to receive in an
1300# ARP reply; otherwise no reply is expected.
1301#
1302# INPORT is an logical switch port number, e.g. 11 for vif11.
1303# SHA and REPLY_HA are each 12 hex digits.
1304# SPA and TPA are each 8 hex digits.
1305test_arp() {
1306 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1307
1308 local request="inport == \"lp$inport\"
1309 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1310 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1311 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1312
1313 if test -z "$reply_ha"; then
1314 reply=
abb37b6b
FF
1315 local i
1316 for i in 1 2 3; do
1317 if test $i != $inport; then
1318 reply="${reply}output(\"lp$i\");
4acd1e87 1319"
abb37b6b
FF
1320 fi
1321 done
4acd1e87
BP
1322 else
1323 reply="\
1324eth.dst = $sha;
1325eth.src = $reply_ha;
1326arp.op = 2;
1327arp.tha = $sha;
1328arp.sha = $reply_ha;
1329arp.tpa = $spa;
1330arp.spa = $tpa;
1331output(\"lp$inport\");
1332"
1333 fi
1334
1335 AT_CAPTURE_FILE([trace])
1336 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1337}
1338
1339# Send packets between all pairs of source and destination ports:
1340#
1341# 1. Unicast packets are delivered to exactly one logical switch port
1342# (except that packets destined to their input ports are dropped).
1343#
1344# 2. Broadcast and multicast are delivered to all logical switch ports
1345# except the input port.
1346#
1347# 3. When port security is turned on, the switch drops packets from the wrong
1348# MAC address.
1349#
1350# 4. The switch drops all packets with a VLAN tag.
1351#
1352# 5. The switch drops all packets with a multicast source address. (This only
1353# affects behavior when port security is turned off, since otherwise port
1354# security would drop the packet anyway.)
1355#
1356# 6. The switch delivers packets with an unknown destination to logical
1357# switch ports with "unknown" among their MAC addresses (and port
1358# security disabled).
1359#
1360# 7. The switch drops unicast packets that violate an ACL.
1361#
1362# 8. The switch drops multicast and broadcast packets that violate an ACL.
1363#
1364# 9. ARP requests to known IPs are responded directly.
1365#
1366# 10. No response to ARP requests for unknown IPs.
1367
1368for s in 1 2 3; do
1369 bcast=
1370 unknown=
1371 bacl2=
1372 bacl3=
1373 for d in 1 2 3; do
abb37b6b
FF
1374 echo
1375 echo "lp$s -> lp$d"
1376 if test $d != $s; then unicast=$d; else unicast=; fi
1377 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1378
1379 if test $d != $s && test $s = 1; then
1380 impersonate=$d
1381 else
1382 impersonate=
1383 fi
1384 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1385
1386 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1387 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1388 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1389 # Source of 1 or 2 and dest of 3 should be dropped
1390 # due to the 4th ACL that uses address_set(set1).
1391 acl4=
1392 else
1393 acl4=$d
1394 fi
1395
1396 #7, acl1 to acl4:
1397 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1398 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1399 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1400 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1401
1402 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1403 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1404
1405 if test $d != $s && test $d = 1; then
1406 unknown="$unknown $d"
1407 fi
1408 bcast="$bcast $unicast"
1409 bacl2="$bacl2 $acl2"
1410 bacl3="$bacl3 $acl3"
1411
1412 sip=192.168.0.$s
1413 tip=192.168.0.$d
1414 tip_unknown=11.11.11.11
1415 test_arp $s f0:00:00:00:00:0$s $sip $tip f0:00:00:00:00:0$d #9
1416 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1417
1418 if test $d = 3; then
1419 # lp3 has an additional ip 192.169.0.[123]3.
1420 tip=192.169.0.$d
1421 test_arp $s f0:00:00:00:00:0$s $sip $tip f0:00:00:00:00:0$d #9
1422 fi
4acd1e87
BP
1423 done
1424
1425 # Broadcast and multicast.
1426 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1427 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1428 if test $s = 1; then
abb37b6b 1429 bcast_impersonate=$bcast
4acd1e87 1430 else
abb37b6b 1431 bcast_impersonate=
4acd1e87
BP
1432 fi
1433 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1434
1435 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1436
1437 #8, acl1 to acl3:
1438 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1439 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1440 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1441
1442 #8, acl1 to acl3:
1443 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1444 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1445 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1446done
1447
1448AT_CLEANUP
1449
7277bc83
RB
1450# 2 hypervisors, 4 logical ports per HV
1451# 2 locally attached networks (one flat, one vlan tagged over same device)
1452# 2 ports per HV on each network
e90aeb57 1453AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1454AT_KEYWORDS([ovn-localnet])
1455AT_SKIP_IF([test $HAVE_PYTHON = no])
1456ovn_start
1457
ea46a4e9
JP
1458# In this test cases we create 3 switches, all connected to same
1459# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1460# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1461# of VIF port name indicates the hypervisor it is bound to, e.g.
1462# lp23 means VIF 3 on hv2.
1463#
ea46a4e9 1464# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1465# - ls1:
1466# - untagged
ea46a4e9 1467# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1468#
1469# - ls2:
1470# - tagged with VLAN 101
ea46a4e9 1471# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1472# - ls3:
1473# - untagged
ea46a4e9 1474# - ports: lp15, lp25
0ee7f7f1 1475#
ea46a4e9 1476# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1477# physical network.
1478
1479for i in 1 2 3; do
ea46a4e9
JP
1480 ls_name=ls$i
1481 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1482 ln_port_name=ln$i
1483 if test $i -eq 2; then
ea46a4e9 1484 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1485 else
ea46a4e9 1486 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1487 fi
31ed1192
JP
1488 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1489 ovn-nbctl lsp-set-type $ln_port_name localnet
1490 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1491done
d79fc5f4
RB
1492
1493net_add n1
1494for i in 1 2; do
1495 sim_add hv$i
1496 as hv$i
1497 ovs-vsctl add-br br-phys
1498 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1499 ovn_attach n1 br-phys 192.168.0.$i
1500
0ee7f7f1 1501 for j in 1 2 3 4 5; do
d79fc5f4
RB
1502 ovs-vsctl add-port br-int vif$i$j -- \
1503 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1504 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1505 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1506 ofport-request=$i$j
1507
31ed1192 1508 lsp_name=lp$i$j
7277bc83 1509 if test $j -le 2; then
ea46a4e9 1510 ls_name=ls1
0ee7f7f1 1511 elif test $j -le 4; then
ea46a4e9 1512 ls_name=ls2
d79fc5f4 1513 else
ea46a4e9 1514 ls_name=ls3
d79fc5f4 1515 fi
d79fc5f4 1516
ea46a4e9 1517 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1518 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1519 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1520
31ed1192 1521 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1522 done
1523done
1524
1525ovn_populate_arp
1526
1527# XXX This is now the 3rd copy of these functions in this file ...
1528
1529# Given the name of a logical port, prints the name of the hypervisor
1530# on which it is located.
1531vif_to_hv() {
1532 echo hv${1%?}
1533}
1534#
1535# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1536#
1537# This shell function causes a packet to be received on INPORT. The packet's
1538# content has Ethernet destination DST and source SRC (each exactly 12 hex
1539# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1540# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1541# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
d79fc5f4 1542for i in 1 2; do
0ee7f7f1 1543 for j in 1 2 3 4 5; do
d79fc5f4
RB
1544 : > $i$j.expected
1545 done
1546done
1547test_packet() {
1548 local inport=$1 src=$2 dst=$3 eth=$4; shift; shift; shift; shift
1549 local packet=${src}${dst}${eth}
1550 hv=`vif_to_hv $inport`
1551 vif=vif$inport
1552 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1553 for outport; do
e4543cfe 1554 echo $packet >> $outport.expected
d79fc5f4
RB
1555 done
1556}
1557
7277bc83
RB
1558# lp11 and lp21 are on the same network (phys, untagged)
1559# and on different hypervisors
d79fc5f4
RB
1560test_packet 11 f00000000021 f00000000011 1121 21
1561test_packet 21 f00000000011 f00000000021 2111 11
1562
7277bc83
RB
1563# lp11 and lp12 are on the same network (phys, untagged)
1564# and on the same hypervisor
e90aeb57
RB
1565test_packet 11 f00000000012 f00000000011 1112 12
1566test_packet 12 f00000000011 f00000000012 1211 11
7277bc83
RB
1567
1568# lp13 and lp23 are on the same network (phys, VLAN 101)
1569# and on different hypervisors
1570test_packet 13 f00000000023 f00000000013 1323 23
1571test_packet 23 f00000000013 f00000000023 2313 13
1572
1573# lp13 and lp14 are on the same network (phys, VLAN 101)
1574# and on the same hypervisor
e90aeb57
RB
1575test_packet 13 f00000000014 f00000000013 1314 14
1576test_packet 14 f00000000013 f00000000014 1413 13
d79fc5f4 1577
0ee7f7f1 1578# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 1579# same hypervisor, and on different switches
0ee7f7f1
HZ
1580test_packet 11 f00000000015 f00000000011 1115 15
1581test_packet 15 f00000000011 f00000000015 1511 11
1582
1583# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 1584# different hypervisors, and on different switches
0ee7f7f1
HZ
1585test_packet 11 f00000000025 f00000000011 1125 25
1586test_packet 25 f00000000011 f00000000025 2511 11
1587
d79fc5f4 1588# Ports that should not be able to communicate
7277bc83
RB
1589test_packet 11 f00000000013 f00000000011 1113
1590test_packet 11 f00000000023 f00000000011 1123
1591test_packet 21 f00000000013 f00000000021 2113
1592test_packet 21 f00000000023 f00000000021 2123
1593test_packet 13 f00000000011 f00000000013 1311
1594test_packet 13 f00000000021 f00000000013 1321
1595test_packet 23 f00000000011 f00000000023 2311
1596test_packet 23 f00000000021 f00000000023 2321
d79fc5f4 1597
d79fc5f4
RB
1598# Dump a bunch of info helpful for debugging if there's a failure.
1599
1600echo "------ OVN dump ------"
1601ovn-nbctl show
1602ovn-sbctl show
1603
1604echo "------ hv1 dump ------"
1605as hv1 ovs-vsctl show
1606as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1607
1608echo "------ hv2 dump ------"
1609as hv2 ovs-vsctl show
1610as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1611
1612# Now check the packets actually received against the ones expected.
1613for i in 1 2; do
0ee7f7f1 1614 for j in 1 2 3 4 5; do
49d7c759 1615 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
1616 done
1617done
1618
7a8f15e0 1619OVN_CLEANUP([hv1],[hv2])
d9c8c57c 1620
d79fc5f4
RB
1621AT_CLEANUP
1622
91125642
FF
1623AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1624AT_KEYWORDS([vtep])
eb6b08eb
JP
1625AT_SKIP_IF([test $HAVE_PYTHON = no])
1626ovn_start
1627
1628# Configure the Northbound database
ea46a4e9 1629ovn-nbctl ls-add lsw0
eb6b08eb 1630
31ed1192
JP
1631ovn-nbctl lsp-add lsw0 lp1
1632ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 1633
31ed1192
JP
1634ovn-nbctl lsp-add lsw0 lp2
1635ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 1636
31ed1192
JP
1637ovn-nbctl lsp-add lsw0 lp-vtep
1638ovn-nbctl lsp-set-type lp-vtep vtep
1639ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1640ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb
JP
1641
1642net_add n1 # Network to connect hv1, hv2, and vtep
1643net_add n2 # Network to connect vtep and hv3
1644
1645# Create hypervisor hv1 connected to n1
1646sim_add hv1
1647as hv1
1648ovs-vsctl add-br br-phys
1649ovn_attach n1 br-phys 192.168.0.1
1650ovs-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
1651
1652# Create hypervisor hv2 connected to n1
1653sim_add hv2
1654as hv2
1655ovs-vsctl add-br br-phys
1656ovn_attach n1 br-phys 192.168.0.2
1657ovs-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
1658
1659
1660# Start the vtep emulator with a leg in both networks
1661sim_add vtep
1662as vtep
1663
1664ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1665ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1666
1667ovs-vsctl add-br br-phys
1668net_attach n1 br-phys
1669
1670mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1671arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1672ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1673ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1674
1675ovs-vsctl add-br br-vtep
1676net_attach n2 br-vtep
1677
1678vtep-ctl add-ps br-vtep
1679vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1680vtep-ctl add-ls lsw0
1681
1682start_daemon ovs-vtep br-vtep
1683start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1684
1685sleep 1
1686
1687vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0
1688
475f0a2c
DB
1689OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1690 grep -- source`"])
1691# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
1692sleep 1
1693
1694# Add hv3 on the other side of the vtep
1695sim_add hv3
1696as hv3
1697ovs-vsctl add-br br-phys
1698net_attach n2 br-phys
1699
1700ovs-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
1701
1702# Pre-populate the hypervisors' ARP tables so that we don't lose any
1703# packets for ARP resolution (native tunneling doesn't queue packets
1704# for ARP resolution).
1705ovn_populate_arp
1706
1707# Allow some time for ovn-northd and ovn-controller to catch up.
1708# XXX This should be more systematic.
1709sleep 1
6977df72 1710
eb6b08eb
JP
1711# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1712#
1713# This shell function causes a packet to be received on INPORT. The packet's
1714# content has Ethernet destination DST and source SRC (each exactly 12 hex
1715# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1716# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1717# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
1718for i in 1 2 3; do
1719 : > $i.expected
1720done
1721test_packet() {
1722 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1723 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1724 hv=hv$inport
1725 vif=vif$inport
1726 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1727 for outport; do
e4543cfe 1728 echo $packet >> $outport.expected
eb6b08eb
JP
1729 done
1730}
1731
1732# Send packets between all pairs of source and destination ports:
1733#
31ed1192
JP
1734# 1. Unicast packets are delivered to exactly one logical switch port
1735# (except that packets destined to their input ports are dropped).
eb6b08eb 1736#
31ed1192
JP
1737# 2. Broadcast and multicast are delivered to all logical switch ports
1738# except the input port.
eb6b08eb 1739#
ea46a4e9 1740# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1741# switch ports with "unknown" among their MAC addresses (and port
1742# security disabled).
eb6b08eb
JP
1743for s in 1 2 3; do
1744 bcast=
1745 unknown=
1746 for d in 1 2 3; do
1747 if test $d != $s; then unicast=$d; else unicast=; fi
1748 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1749
1750 # The vtep (vif3) is the only one configured for "unknown"
1751 if test $d != $s && test $d = 3; then
1752 unknown="$unknown $d"
1753 fi
1754 bcast="$bcast $unicast"
1755 done
1756
1757 # Broadcast and multicast.
46ed1382
DB
1758 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1759 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
1760
1761 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1762done
1763
bb0c41d3
RM
1764# dump information with counters
1765echo "------ OVN dump ------"
1766ovn-nbctl show
1767ovn-sbctl show
1768
1769echo "------ hv1 dump ------"
1770as hv1 ovs-vsctl show
6195e2e7 1771as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
1772as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1773
1774echo "------ hv2 dump ------"
1775as hv2 ovs-vsctl show
6195e2e7 1776as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
1777as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1778
1779echo "------ hv3 dump ------"
1780as hv3 ovs-vsctl show
6754e92d
FF
1781# note: hv3 has no logical port bind, thus it should not have br-int
1782AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
1783[ovs-ofctl: br-int is not a bridge or a socket
1784])
bb0c41d3 1785
eb6b08eb
JP
1786# Now check the packets actually received against the ones expected.
1787for i in 1 2 3; do
49d7c759 1788 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 1789done
fcde56f5
LR
1790
1791# Gracefully terminate daemons
7a8f15e0
LR
1792OVN_CLEANUP([hv1],[hv2],[vtep])
1793OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 1794
eb6b08eb 1795AT_CLEANUP
9975d7be 1796
184bc3ca
RB
1797# Similar test to "hardware GW"
1798AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
1799AT_SKIP_IF([test $HAVE_PYTHON = no])
1800ovn_start
1801
1802# Configure the Northbound database
1803ovn-nbctl ls-add lsw0
1804
1805ovn-nbctl lsp-add lsw0 lp1
1806ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1807
1808ovn-nbctl lsp-add lsw0 lp2
1809ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1810
1811ovn-nbctl lsp-add lsw0 lp-gw
1812ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 1813ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
1814ovn-nbctl lsp-set-addresses lp-gw unknown
1815
1816net_add n1 # Network to connect hv1, hv2, and gw
1817net_add n2 # Network to connect gw and hv3
1818
1819# Create hypervisor hv1 connected to n1
1820sim_add hv1
1821as hv1
1822ovs-vsctl add-br br-phys
1823ovn_attach n1 br-phys 192.168.0.1
1824ovs-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
1825
1826# Create hypervisor hv2 connected to n1
1827sim_add hv2
1828as hv2
1829ovs-vsctl add-br br-phys
1830ovn_attach n1 br-phys 192.168.0.2
1831ovs-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
1832
1833# Create hypervisor hv_gw connected to n1 and n2
1834# connect br-phys bridge to n1; connect hv-gw bridge to n2
1835sim_add hv_gw
1836as hv_gw
1837ovs-vsctl add-br br-phys
1838ovn_attach n1 br-phys 192.168.0.3
1839ovs-vsctl add-br br-phys2
1840net_attach n2 br-phys2
1841ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
1842
184bc3ca
RB
1843# Add hv3 on the other side of the GW
1844sim_add hv3
1845as hv3
1846ovs-vsctl add-br br-phys
1847net_attach n2 br-phys
1848ovs-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
1849
1850
1851# Pre-populate the hypervisors' ARP tables so that we don't lose any
1852# packets for ARP resolution (native tunneling doesn't queue packets
1853# for ARP resolution).
1854ovn_populate_arp
1855
1856# Allow some time for ovn-northd and ovn-controller to catch up.
1857# XXX This should be more systematic.
1858sleep 1
1859
1860# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1861#
1862# This shell function causes a packet to be received on INPORT. The packet's
1863# content has Ethernet destination DST and source SRC (each exactly 12 hex
1864# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1865# more) list the VIFs on which the packet should be received. INPORT and the
1866# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
1867for i in 1 2 3; do
1868 : > $i.expected
1869done
1870test_packet() {
1871 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1872 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1873 hv=hv$inport
1874 vif=vif$inport
1875 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1876 for outport; do
e4543cfe 1877 echo $packet >> $outport.expected
184bc3ca
RB
1878 done
1879}
1880
1881# Send packets between all pairs of source and destination ports:
1882#
1883# 1. Unicast packets are delivered to exactly one lport (except that packets
1884# destined to their input ports are dropped).
1885#
1886# 2. Broadcast and multicast are delivered to all lports except the input port.
1887#
1888# 3. The lswitch delivers packets with an unknown destination to lports with
1889# "unknown" among their MAC addresses (and port security disabled).
1890for s in 1 2 3 ; do
1891 bcast=
1892 unknown=
1893 for d in 1 2 3 ; do
1894 if test $d != $s; then unicast=$d; else unicast=; fi
1895 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1896
1897 # The vtep (vif3) is the only one configured for "unknown"
1898 if test $d != $s && test $d = 3; then
1899 unknown="$unknown $d"
1900 fi
1901 bcast="$bcast $unicast"
1902 done
1903
1904 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1905 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
1906 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
1907done
1908
184bc3ca
RB
1909echo "------ ovn-nbctl show ------"
1910ovn-nbctl show
1911echo "------ ovn-sbctl show ------"
1912ovn-sbctl show
1913
1914echo "------ hv1 ------"
1915as hv1 ovs-vsctl show
1916echo "------ hv1 br-int ------"
1917as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1918echo "------ hv1 br-phys ------"
1919as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1920
1921echo "------ hv2 ------"
1922as hv2 ovs-vsctl show
1923echo "------ hv2 br-int ------"
1924as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1925echo "------ hv2 br-phys ------"
1926as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1927
1928echo "------ hv_gw ------"
1929as hv_gw ovs-vsctl show
1930echo "------ hv_gw br-phys ------"
1931as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
1932echo "------ hv_gw br-phys2 ------"
1933as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
1934
1935echo "------ hv3 ------"
1936as hv3 ovs-vsctl show
1937echo "------ hv3 br-phys ------"
1938as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1939
1940# Now check the packets actually received against the ones expected.
1941for i in 1 2 3; do
49d7c759 1942 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
1943done
1944AT_CLEANUP
1945
9975d7be
BP
1946# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
1947AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
1948AT_SKIP_IF([test $HAVE_PYTHON = no])
1949ovn_start
1950
1951# Logical network:
1952#
1953# Three logical switches ls1, ls2, ls3.
86e98048
BP
1954# One logical router lr0 connected to ls[123],
1955# with nine subnets, three per logical switch:
1956#
1957# lrp11 on ls1 for subnet 192.168.11.0/24
1958# lrp12 on ls1 for subnet 192.168.12.0/24
1959# lrp13 on ls1 for subnet 192.168.13.0/24
1960# ...
1961# lrp33 on ls3 for subnet 192.168.33.0/24
1962#
1963# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
1964# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 1965for i in 1 2 3; do
ea46a4e9 1966 ovn-nbctl ls-add ls$i
9975d7be 1967 for j in 1 2 3; do
86e98048 1968 for k in 1 2 3; do
31ed1192
JP
1969 # Add "unknown" to MAC addresses for lp?11, so packets for
1970 # MAC-IP bindings discovered via ARP later have somewhere to go.
1971 if test $j$k = 11; then unknown=unknown; else unknown=; fi
1972
1973 ovn-nbctl \
1974 -- lsp-add ls$i lp$i$j$k \
1975 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
1976 192.168.$i$j.$k" $unknown
86e98048
BP
1977 done
1978 done
1979done
1980
fa2a27b2 1981ovn-nbctl lr-add lr0
86e98048
BP
1982for i in 1 2 3; do
1983 for j in 1 2 3; do
bf44c2cd 1984 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 1985 ovn-nbctl \
31ed1192 1986 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 1987 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 1988 options:router-port=lrp$i$j \
86e98048 1989 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
1990 done
1991done
1992
80f408f4 1993ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
1994 addresses='"00:00:00:00:ff:33 192.168.33.254"'
1995
9975d7be
BP
1996# Physical network:
1997#
1998# Three hypervisors hv[123].
86e98048
BP
1999# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2000# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2001# lp?3[123] all on hv3.
2002
9975d7be
BP
2003
2004# Given the name of a logical port, prints the name of the hypervisor
2005# on which it is located.
2006vif_to_hv() {
2007 case $1 in dnl (
86e98048
BP
2008 ?11) echo 1 ;; dnl (
2009 ?12 | ?21 | ?22) echo 2 ;; dnl (
2010 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2011 esac
2012}
2013
86e98048
BP
2014# Given the name of a logical port, prints the name of its logical router
2015# port, e.g. "vif_to_lrp 123" yields 12.
2016vif_to_lrp() {
2017 echo ${1%?}
2018}
2019
2020# Given the name of a logical port, prints the name of its logical
2021# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2022vif_to_ls() {
86e98048 2023 echo ${1%??}
e3393e3f
BP
2024}
2025
9975d7be
BP
2026net_add n1
2027for i in 1 2 3; do
2028 sim_add hv$i
2029 as hv$i
2030 ovs-vsctl add-br br-phys
2031 ovn_attach n1 br-phys 192.168.0.$i
2032done
2033for i in 1 2 3; do
2034 for j in 1 2 3; do
86e98048 2035 for k in 1 2 3; do
269ecccc
JP
2036 hv=`vif_to_hv $i$j$k`
2037 as hv$hv ovs-vsctl \
2038 -- add-port br-int vif$i$j$k \
2039 -- set Interface vif$i$j$k \
2040 external-ids:iface-id=lp$i$j$k \
2041 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2042 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2043 ofport-request=$i$j$k
86e98048 2044 done
9975d7be
BP
2045 done
2046done
2047
2048# Pre-populate the hypervisors' ARP tables so that we don't lose any
2049# packets for ARP resolution (native tunneling doesn't queue packets
2050# for ARP resolution).
2051ovn_populate_arp
2052
2053# Allow some time for ovn-northd and ovn-controller to catch up.
2054# XXX This should be more systematic.
2055sleep 1
2056
e3393e3f 2057# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2058#
2059# This shell function causes a packet to be received on INPORT. The packet's
2060# content has Ethernet destination DST and source SRC (each exactly 12 hex
2061# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2062# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2063# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2064for i in 1 2 3; do
2065 for j in 1 2 3; do
86e98048
BP
2066 for k in 1 2 3; do
2067 : > $i$j$k.expected
269ecccc 2068 done
9975d7be
BP
2069 done
2070done
e3393e3f 2071test_ip() {
9975d7be
BP
2072 # This packet has bad checksums but logical L3 routing doesn't check.
2073 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2074 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2075 shift; shift; shift; shift; shift
2076 hv=hv`vif_to_hv $inport`
2077 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2078 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2079 in_ls=`vif_to_ls $inport`
2080 in_lrp=`vif_to_lrp $inport`
9975d7be 2081 for outport; do
269ecccc 2082 out_ls=`vif_to_ls $outport`
86e98048 2083 if test $in_ls = $out_ls; then
9975d7be
BP
2084 # Ports on the same logical switch receive exactly the same packet.
2085 echo $packet
2086 else
2087 # Routing decrements TTL and updates source and dest MAC
2088 # (and checksum).
269ecccc 2089 out_lrp=`vif_to_lrp $outport`
86e98048 2090 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2091 fi >> $outport.expected
9975d7be
BP
2092 done
2093}
2094
e3393e3f 2095as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2096as hv1 ovn-sbctl list port_binding
2097as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2098as hv1 ovn-sbctl dump-flows
2099as hv1 ovs-ofctl dump-flows br-int
2100
e3393e3f 2101# Send IP packets between all pairs of source and destination ports:
9975d7be 2102#
31ed1192
JP
2103# 1. Unicast IP packets are delivered to exactly one logical switch port
2104# (except that packets destined to their input ports are dropped).
9975d7be 2105#
31ed1192
JP
2106# 2. Broadcast IP packets are delivered to all logical switch ports
2107# except the input port.
86e98048
BP
2108ip_to_hex() {
2109 printf "%02x%02x%02x%02x" "$@"
2110}
9975d7be 2111for is in 1 2 3; do
269ecccc
JP
2112 for js in 1 2 3; do
2113 for ks in 1 2 3; do
2114 bcast=
2115 s=$is$js$ks
2116 smac=f00000000$s
2117 sip=`ip_to_hex 192 168 $is$js $ks`
2118 for id in 1 2 3; do
2119 for jd in 1 2 3; do
2120 for kd in 1 2 3; do
2121 d=$id$jd$kd
2122 dip=`ip_to_hex 192 168 $id$jd $kd`
2123 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2124 if test $d != $s; then unicast=$d; else unicast=; fi
2125
2126 test_ip $s $smac $dmac $sip $dip $unicast #1
2127
2128 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2129 done
2130 done
9975d7be 2131 done
269ecccc
JP
2132 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2133 done
2134 done
e3393e3f
BP
2135done
2136
0bac7164
BP
2137# 3. Send an IP packet from every logical port to every other subnet,
2138# to an IP address that does not have a static IP-MAC binding.
2139# This should generate a broadcast ARP request for the destination
2140# IP address in the destination subnet.
2141for is in 1 2 3; do
269ecccc
JP
2142 for js in 1 2 3; do
2143 for ks in 1 2 3; do
2144 s=$is$js$ks
2145 smac=f00000000$s
2146 sip=`ip_to_hex 192 168 $is$js $ks`
2147 for id in 1 2 3; do
2148 for jd in 1 2 3; do
2149 if test $is$js = $id$jd; then
2150 continue
2151 fi
2152
2153 # Send the packet.
2154 dmac=00000000ff$is$js
2155 # Calculate a 4th octet for the destination that is
2156 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2157 # that have static MAC bindings, and fits in the range
2158 # 0-255.
2159 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2160 dip=`ip_to_hex 192 168 $id$jd $o4`
2161 test_ip $s $smac $dmac $sip $dip
2162
2163 # Every LP on the destination subnet's lswitch should
2164 # receive the ARP request.
2165 lrmac=00000000ff$id$jd
2166 lrip=`ip_to_hex 192 168 $id$jd 254`
2167 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2168 for jd2 in 1 2 3; do
2169 for kd in 1 2 3; do
e4543cfe 2170 echo $arp >> $id$jd2$kd.expected
0bac7164 2171 done
269ecccc 2172 done
0bac7164 2173 done
269ecccc 2174 done
0bac7164 2175 done
269ecccc 2176 done
0bac7164
BP
2177done
2178
e3393e3f
BP
2179# test_arp INPORT SHA SPA TPA [REPLY_HA]
2180#
2181# Causes a packet to be received on INPORT. The packet is an ARP
2182# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2183# it should be the hardware address of the target to expect to receive in an
2184# ARP reply; otherwise no reply is expected.
2185#
31ed1192 2186# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2187# SHA and REPLY_HA are each 12 hex digits.
2188# SPA and TPA are each 8 hex digits.
2189test_arp() {
2190 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2191 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2192 hv=hv`vif_to_hv $inport`
2193 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2194 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2195
57d143eb 2196 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2197 # IP address is not configured to the switch patch port.
e3393e3f 2198 local i=`vif_to_ls $inport`
86e98048 2199 local j k
e3393e3f 2200 for j in 1 2 3; do
86e98048 2201 for k in 1 2 3; do
ea46a4e9 2202 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2203 # so no ARP flooding expected for it.
2204 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2205 echo $request >> $i$j$k.expected
2206 fi
2207 done
e3393e3f
BP
2208 done
2209
2210 # Expect to receive the reply, if any.
2211 if test X$reply_ha != X; then
86e98048
BP
2212 lrp=`vif_to_lrp $inport`
2213 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2214 echo $reply >> $inport.expected
2215 fi
2216}
2217
2218# Test router replies to ARP requests from all source ports:
2219#
0bac7164 2220# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2221#
0bac7164 2222# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2223# in its subnet.
2224#
0bac7164 2225# 6. Router replies to query for its MAC address from another subnet.
e3393e3f 2226#
0bac7164 2227# 7. No reply to query for IP address other than router IP.
e3393e3f 2228for i in 1 2 3; do
269ecccc
JP
2229 for j in 1 2 3; do
2230 for k in 1 2 3; do
2231 smac=f00000000$i$j$k # Source MAC
2232 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2233 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2234 rmac=00000000ff$i$j # Router MAC
2235 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2236 test_arp $i$j$k $smac $sip $rip $rmac #4
2237 test_arp $i$j$k $smac $otherip $rip $rmac #5
2238 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2239 test_arp $i$j$k $smac $sip $otherip #7
0bac7164 2240 done
269ecccc 2241 done
0bac7164
BP
2242done
2243
2244# Allow some time for packet forwarding.
2245# XXX This can be improved.
2246sleep 1
2247
2248# 8. Generate an ARP reply for each of the IP addresses ARPed for
2249# earlier as #3.
2250#
2251# Here, the $s is the VIF that originated the ARP request and $d is
2252# the VIF that sends the ARP reply, which is somewhat backward but
2253# it means that $s and $d are the same as #3.
2254: > mac_bindings.expected
2255for is in 1 2 3; do
269ecccc
JP
2256 for js in 1 2 3; do
2257 for ks in 1 2 3; do
2258 s=$is$js$ks
2259 for id in 1 2 3; do
2260 for jd in 1 2 3; do
2261 if test $is$js = $id$jd; then
2262 continue
2263 fi
2264
2265 kd=1
2266 d=$id$jd$kd
2267
2268 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2269 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2270 host_mac=8000000000$o4
2271
2272 lrmac=00000000ff$id$jd
2273 lrip=`ip_to_hex 192 168 $id$jd 254`
2274
2275 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2276
2277 echo
2278 echo
2279 echo
2280 hv=hv`vif_to_hv $d`
2281 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2282 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2283 #as $hv ovs-ofctl dump-flows br-int table=19
2284
2285 host_ip_pretty=192.168.$id$jd.$o4
2286 host_mac_pretty=80:00:00:00:00:$o4
2287 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2288 done
269ecccc 2289 done
9975d7be 2290 done
269ecccc 2291 done
9975d7be 2292done
0bac7164 2293
9975d7be
BP
2294# Allow some time for packet forwarding.
2295# XXX This can be improved.
2296sleep 1
2297
0bac7164
BP
2298# 9. Send an IP packet from every logical port to every other subnet. These
2299# are the same packets already sent as #3, but now the destinations' IP-MAC
2300# bindings have been discovered via ARP, so instead of provoking an ARP
2301# request, these packets now get routed to their destinations (which don't
2302# have static MAC bindings, so they go to the port we've designated as
2303# accepting "unknown" MACs.)
2304for is in 1 2 3; do
269ecccc
JP
2305 for js in 1 2 3; do
2306 for ks in 1 2 3; do
2307 s=$is$js$ks
2308 smac=f00000000$s
2309 sip=`ip_to_hex 192 168 $is$js $ks`
2310 for id in 1 2 3; do
2311 for jd in 1 2 3; do
2312 if test $is$js = $id$jd; then
2313 continue
2314 fi
2315
2316 # Send the packet.
2317 dmac=00000000ff$is$js
2318 # Calculate a 4th octet for the destination that is
2319 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2320 # that have static MAC bindings, and fits in the range
2321 # 0-255.
2322 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2323 dip=`ip_to_hex 192 168 $id$jd $o4`
2324 test_ip $s $smac $dmac $sip $dip
2325
2326 # Expect the packet egress.
2327 host_mac=8000000000$o4
2328 outport=${id}11
2329 out_lrp=$id$jd
e4543cfe 2330 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2331 done
269ecccc 2332 done
0bac7164 2333 done
269ecccc 2334 done
0bac7164
BP
2335done
2336
0bac7164
BP
2337ovn-sbctl -f csv -d bare --no-heading \
2338 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2339
9975d7be
BP
2340# Now check the packets actually received against the ones expected.
2341for i in 1 2 3; do
2342 for j in 1 2 3; do
86e98048 2343 for k in 1 2 3; do
abb37b6b
FF
2344 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2345 [$i$j$k.expected])
86e98048 2346 done
9975d7be
BP
2347 done
2348done
fcde56f5 2349
0bac7164
BP
2350# Check the MAC bindings against those expected.
2351AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2352])
2353
fcde56f5 2354# Gracefully terminate daemons
7a8f15e0 2355OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2356
9975d7be 2357AT_CLEANUP
685f4dfe
NS
2358
2359# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2360AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2361AT_KEYWORDS([portsecurity])
2362AT_SKIP_IF([test $HAVE_PYTHON = no])
2363ovn_start
2364
2365# Create hypervisors hv[123].
2366# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2367# Add all of the vifs to a single logical switch lsw0.
2368# Turn off port security on vifs vif[123]1
2369# Turn on l2 port security on vifs vif[123]2
2370# Turn of l2 and l3 port security on vifs vif[123]3
2371# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 2372ovn-nbctl ls-add lsw0
685f4dfe
NS
2373net_add n1
2374for i in 1 2 3; do
2375 sim_add hv$i
2376 as hv$i
2377 ovs-vsctl add-br br-phys
2378 ovn_attach n1 br-phys 192.168.0.$i
2379
2380 for j in 1 2 3; do
2381 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 2382 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 2383 if test $j = 1; then
31ed1192 2384 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 2385 elif test $j = 2; then
31ed1192
JP
2386 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2387 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
2388 else
2389 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
2390 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2391 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
2392 fi
2393 done
2394done
2395
685f4dfe
NS
2396# Pre-populate the hypervisors' ARP tables so that we don't lose any
2397# packets for ARP resolution (native tunneling doesn't queue packets
2398# for ARP resolution).
2399ovn_populate_arp
2400
2401# Allow some time for ovn-northd and ovn-controller to catch up.
2402# XXX This should be more systematic.
2403sleep 1
685f4dfe
NS
2404
2405# Given the name of a logical port, prints the name of the hypervisor
2406# on which it is located.
2407vif_to_hv() {
2408 echo hv${1%?}
2409}
2410
685f4dfe
NS
2411for i in 1 2 3; do
2412 for j in 1 2 3; do
2413 : > $i$j.expected
2414 done
2415done
2416
2417# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2418#
2419# This shell function causes an ip packet to be received on INPORT.
2420# The packet's content has Ethernet destination DST and source SRC
2421# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2422# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2423# be received. INPORT and the OUTPORTs are specified as logical switch
2424# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2425test_ip() {
2426 # This packet has bad checksums but logical L3 routing doesn't check.
2427 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 2428 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
2429 shift; shift; shift; shift; shift
2430 hv=`vif_to_hv $inport`
2431 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2432 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2433 for outport; do
e4543cfe 2434 echo $packet >> $outport.expected
685f4dfe
NS
2435 done
2436}
2437
2438# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2439#
2440# Causes a packet to be received on INPORT. The packet is an ARP
2441# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2442# it should be the hardware address of the target to expect to receive in an
2443# ARP reply; otherwise no reply is expected.
2444#
31ed1192 2445# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2446# SHA and REPLY_HA are each 12 hex digits.
2447# SPA and TPA are each 8 hex digits.
2448test_arp() {
2449 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2450 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2451 hv=`vif_to_hv $inport`
2452 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2453 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2454 if test $drop != 1; then
e137131a 2455 if test X$reply_ha = X; then
685f4dfe
NS
2456 # Expect to receive the broadcast ARP on the other logical switch ports
2457 # if no reply is expected.
2458 local i j
2459 for i in 1 2 3; do
2460 for j in 1 2 3; do
2461 if test $i$j != $inport; then
2462 echo $request >> $i$j.expected
2463 fi
2464 done
2465 done
2466 else
2467 # Expect to receive the reply, if any.
2468 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2469 echo $reply >> $inport.expected
2470 fi
2471 fi
2472}
2473
2474# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2475# This function is similar to test_ip() except that it sends
2476# ipv6 packet
2477test_ipv6() {
2478 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2479 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2480 shift; shift; shift; shift; shift
2481 hv=`vif_to_hv $inport`
2482 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2483 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2484 for outport; do
e4543cfe 2485 echo $packet >> $outport.expected
685f4dfe
NS
2486 done
2487}
2488
9e687b23
DL
2489# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2490# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2491# of the test packet
2492test_icmpv6() {
2493 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2494 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2495 shift; shift; shift; shift; shift; shift
2496 hv=`vif_to_hv $inport`
2497 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2498 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2499 for outport; do
e4543cfe 2500 echo $packet >> $outport.expected
9e687b23
DL
2501 done
2502}
2503
685f4dfe
NS
2504ip_to_hex() {
2505 printf "%02x%02x%02x%02x" "$@"
2506}
2507
2508# no port security
2509sip=`ip_to_hex 192 168 0 12`
2510tip=`ip_to_hex 192 168 0 13`
2511# the arp packet should be allowed even if lp[123]1 is
2512# not configured with mac f00000000023 and ip 192.168.0.12
2513for i in 1 2 3; do
2514 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2515 for j in 1 2 3; do
2516 if test $i != $j; then
2517 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2518 fi
2519 done
2520done
2521
2522# l2 port security
2523sip=`ip_to_hex 192 168 0 12`
2524tip=`ip_to_hex 192 168 0 13`
2525
2526# arp packet should be allowed since lp22 is configured with
2527# mac f00000000022
2528test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2529
2530# arp packet should not be allowed since lp32 is not configured with
2531# mac f00000000021
2532test_arp 32 f00000000021 f00000000021 $sip $tip 1
2533
2534# arp packet with sha set to f00000000021 should not be allowed
2535# for lp12
2536test_arp 12 f00000000012 f00000000021 $sip $tip 1
2537
2538# ip packets should be allowed and received since lp[123]2 do not
2539# have l3 port security
2540sip=`ip_to_hex 192 168 0 55`
2541tip=`ip_to_hex 192 168 0 66`
2542for i in 1 2 3; do
2543 for j in 1 2 3; do
2544 if test $i != $j; then
2545 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2546 fi
2547 done
2548done
2549
2550# ipv6 packets should be received by lp[123]2
2551# lp[123]1 can send ipv6 traffic as there is no port security
2552sip=fe800000000000000000000000000000
2553tip=ff020000000000000000000000000000
2554
2555for i in 1 2 3; do
2556 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2557done
2558
2559
2560# l2 and l3 port security
2561sip=`ip_to_hex 192 168 0 13`
2562tip=`ip_to_hex 192 168 0 22`
2563# arp packet should be allowed since lp13 is configured with
2564# f00000000013 and 192.168.0.13
2565test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2566
2567# the arp packet should be dropped because lp23 is not configured
2568# with mac f00000000022
2569sip=`ip_to_hex 192 168 0 13`
2570tip=`ip_to_hex 192 168 0 22`
2571test_arp 23 f00000000022 f00000000022 $sip $tip 1
2572
2573# the arp packet should be dropped because lp33 is not configured
2574# with ip 192.168.0.55
2575spa=`ip_to_hex 192 168 0 55`
2576tpa=`ip_to_hex 192 168 0 22`
2577test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2578
2579# ip packets should not be received by lp[123]3 since
2580# l3 port security is enabled
2581sip=`ip_to_hex 192 168 0 55`
2582tip=`ip_to_hex 192 168 0 66`
2583for i in 1 2 3; do
2584 for j in 1 2 3; do
2585 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2586 done
2587done
2588
2589# ipv6 packets should be dropped for lp[123]3 since
2590# it is configured with only ipv4 address
2591sip=fe800000000000000000000000000000
2592tip=ff020000000000000000000000000000
2593
2594for i in 1 2 3; do
2595 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2596done
2597
2598# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2599# lp[123]1 can send ipv6 traffic as there is no port security
2600for i in 1 2 3; do
2601 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2602done
2603
2604# lp13 has extra port security with mac f0000000113 and ipv6 addr
2605# fe80::ea2a:eaff:fe28:0012
2606
2607# ipv4 packet should be dropped for lp13 with mac f0000000113
2608sip=`ip_to_hex 192 168 0 13`
2609tip=`ip_to_hex 192 168 0 23`
2610test_ip 13 f00000000113 f00000000023 $sip $tip
2611
2612# ipv6 packet should be received by lp[123]3 with mac f0000000{i}{i}3
2613# and ip6.dst as fe80::ea2a:eaff:fe28:0{i}{i}3.
2614# lp11 can send ipv6 traffic as there is no port security
2615sip=ee800000000000000000000000000000
2616for i in 1 2 3; do
2617 tip=fe80000000000000ea2aeafffe2800{i}3
2618 test_ipv6 11 f00000000011 f000000000{i}${i}3 $sip $tip {i}3
2619done
2620
2621
2622# ipv6 packet should not be received by lp33 with mac f0000000333
2623# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2624# configured with fe80::ea2a:eaff:fe28:0033
2625# lp11 can send ipv6 traffic as there is no port security
2626
2627sip=ee800000000000000000000000000000
2628tip=fe80000000000000ea2aeafffe280023
2629test_ipv6 11 f00000000011 f00000000333 $sip $tip
2630
2631# ipv6 packet should be allowed for lp[123]3 with mac f0000000{i}{i}3
2632# and ip6.src fe80::ea2a:eaff:fe28:0{i}{i}3 and ip6.src ::.
2633# and should be dropped for any other ip6.src
2634# lp21 can receive ipv6 traffic as there is no port security
2635
2636tip=ee800000000000000000000000000000
2637for i in 1 2 3; do
2638 sip=fe80000000000000ea2aeafffe2800${i}3
2639 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2640
9e687b23 2641 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 2642 sip=00000000000000000000000000000000
9e687b23
DL
2643 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2644 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2645 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2646 # Traffic to non-multicast traffic should be dropped
2647 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2648 # Traffic of other ICMPv6 types should be dropped
2649 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
2650
2651 # should be dropped
2652 sip=ae80000000000000ea2aeafffe2800aa
2653 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2654done
2655
31ed1192
JP
2656# configure lsp13 to send and received IPv4 packets with an address range
2657ovn-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 2658
8ff5a966
NS
2659sleep 2
2660
7d9d86ad
NS
2661sip=`ip_to_hex 10 0 0 13`
2662tip=`ip_to_hex 192 168 0 22`
31ed1192 2663# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
2664test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2665
2666sip=`ip_to_hex 10 0 0 14`
2667tip=`ip_to_hex 192 168 0 23`
31ed1192 2668# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
2669# with dst ip 192.168.0.23 should be allowed
2670test_ip 13 f00000000013 f00000000023 $sip $tip 23
2671
2672sip=`ip_to_hex 192 168 0 33`
2673tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
2674# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2675# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
2676test_ip 33 f00000000033 f00000000013 $sip $tip 13
2677
2678sip=`ip_to_hex 192 168 0 33`
2679tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
2680# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2681# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
2682test_ip 33 f00000000033 f00000000013 $sip $tip 13
2683
2684sip=`ip_to_hex 192 168 0 33`
2685tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
2686# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2687# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
2688test_ip 33 f00000000033 f00000000013 $sip $tip
2689
2690sip=`ip_to_hex 192 168 0 33`
2691tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
2692# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2693# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
2694test_ip 33 f00000000033 f00000000013 $sip $tip 13
2695
2696sip=`ip_to_hex 192 168 0 33`
2697tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
2698# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2699# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
2700test_ip 33 f00000000033 f00000000013 $sip $tip
2701
2702sip=`ip_to_hex 192 168 0 33`
2703tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
2704# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2705# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 2706test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 2707
bb0c41d3
RM
2708#dump information including flow counters
2709ovn-nbctl show
2710ovn-sbctl dump-flows -- list multicast_group
2711
2712echo "------ hv1 dump ------"
2713as hv1 ovs-vsctl show
6195e2e7 2714as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2715as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2716
2717echo "------ hv2 dump ------"
2718as hv2 ovs-vsctl show
6195e2e7 2719as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2720as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2721
2722echo "------ hv3 dump ------"
2723as hv3 ovs-vsctl show
6195e2e7 2724as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2725as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2726
685f4dfe
NS
2727# Now check the packets actually received against the ones expected.
2728for i in 1 2 3; do
2729 for j in 1 2 3; do
49d7c759 2730 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
2731 done
2732done
2733
7a8f15e0 2734OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 2735
685f4dfe 2736AT_CLEANUP
509afdc3
GS
2737
2738AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
2739AT_KEYWORDS([ovnpeer])
2740AT_SKIP_IF([test $HAVE_PYTHON = no])
2741ovn_start
2742
2743# Logical network:
2744# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2745# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2746# R2 has ls2 (172.16.1.0/24) connected to it.
2747
fa2a27b2
JP
2748ovn-nbctl lr-add R1
2749ovn-nbctl lr-add R2
509afdc3 2750
ea46a4e9
JP
2751ovn-nbctl ls-add ls1
2752ovn-nbctl ls-add ls2
509afdc3
GS
2753
2754# Connect ls1 to R1
bf44c2cd 2755ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
509afdc3 2756
31ed1192 2757ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 2758 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
509afdc3
GS
2759
2760# Connect ls2 to R2
bf44c2cd 2761ovn-nbctl lrp-add R2 ls2 00:00:00:01:02:04 172.16.1.1/24
509afdc3 2762
31ed1192 2763ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 2764 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
509afdc3
GS
2765
2766# Connect R1 to R2
4685e523
JP
2767ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
2768ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 2769
6d9ecfa9
JP
2770ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
2771ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
2772
2773# Create logical port ls1-lp1 in ls1
31ed1192
JP
2774ovn-nbctl lsp-add ls1 ls1-lp1 \
2775-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
509afdc3
GS
2776
2777# Create logical port ls2-lp1 in ls2
31ed1192
JP
2778ovn-nbctl lsp-add ls2 ls2-lp1 \
2779-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
509afdc3
GS
2780
2781# Create two hypervisor and create OVS ports corresponding to logical ports.
2782net_add n1
2783
2784sim_add hv1
2785as hv1
2786ovs-vsctl add-br br-phys
2787ovn_attach n1 br-phys 192.168.0.1
2788ovs-vsctl -- add-port br-int hv1-vif1 -- \
2789 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
2790 options:tx_pcap=hv1/vif1-tx.pcap \
2791 options:rxq_pcap=hv1/vif1-rx.pcap \
2792 ofport-request=1
2793
2794sim_add hv2
2795as hv2
2796ovs-vsctl add-br br-phys
2797ovn_attach n1 br-phys 192.168.0.2
2798ovs-vsctl -- add-port br-int hv2-vif1 -- \
2799 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
2800 options:tx_pcap=hv2/vif1-tx.pcap \
2801 options:rxq_pcap=hv2/vif1-rx.pcap \
2802 ofport-request=1
2803
2804
2805# Pre-populate the hypervisors' ARP tables so that we don't lose any
2806# packets for ARP resolution (native tunneling doesn't queue packets
2807# for ARP resolution).
2808ovn_populate_arp
2809
2810# Allow some time for ovn-northd and ovn-controller to catch up.
2811# XXX This should be more systematic.
2812sleep 1
2813
2814# Send ip packets between the two ports.
2815ip_to_hex() {
2816 printf "%02x%02x%02x%02x" "$@"
2817}
509afdc3
GS
2818
2819# Packet to send.
2820src_mac="f00000010203"
2821dst_mac="000000010203"
2822src_ip=`ip_to_hex 192 168 1 2`
2823dst_ip=`ip_to_hex 172 16 1 2`
2824packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2825as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2826
2827
2828echo "---------NB dump-----"
2829ovn-nbctl show
2830echo "---------------------"
2831ovn-nbctl list logical_router
2832echo "---------------------"
2833ovn-nbctl list logical_router_port
2834echo "---------------------"
2835
2836echo "---------SB dump-----"
2837ovn-sbctl list datapath_binding
2838echo "---------------------"
2839ovn-sbctl list port_binding
2840echo "---------------------"
2841
2842echo "------ hv1 dump ----------"
8dab1022 2843as hv1 ovs-ofctl show br-int
509afdc3
GS
2844as hv1 ovs-ofctl dump-flows br-int
2845echo "------ hv2 dump ----------"
8dab1022 2846as hv2 ovs-ofctl show br-int
509afdc3
GS
2847as hv2 ovs-ofctl dump-flows br-int
2848
2849# Packet to Expect
2850src_mac="000000010204"
2851dst_mac="f00000010204"
49d7c759 2852echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
509afdc3 2853
49d7c759 2854OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 2855
7a8f15e0 2856OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
2857
2858AT_CLEANUP
5412db30
J
2859
2860
4685e523
JP
2861AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
2862AT_KEYWORDS([router-admin-state])
2863AT_SKIP_IF([test $HAVE_PYTHON = no])
2864ovn_start
2865
2866# Logical network:
2867# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
2868# and 172.16.1.0/24) connected to it.
2869
2870ovn-nbctl lr-add R1
2871
2872ovn-nbctl ls-add ls1
2873
2874# Connect ls1 to R1
bf44c2cd 2875ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
2876ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
2877 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
2878
2879# Create logical port ls1-lp1 in ls1
2880ovn-nbctl lsp-add ls1 ls1-lp1 \
2881 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
2882
2883# Create logical port ls1-lp2 in ls1
2884ovn-nbctl lsp-add ls1 ls1-lp2 \
2885 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
2886
2887# Create one hypervisor and create OVS ports corresponding to logical ports.
2888net_add n1
2889
2890sim_add hv1
2891as hv1
2892ovs-vsctl add-br br-phys
2893ovn_attach n1 br-phys 192.168.0.1
2894ovs-vsctl -- add-port br-int vif1 -- \
2895 set interface vif1 external-ids:iface-id=ls1-lp1 \
2896 options:tx_pcap=hv1/vif1-tx.pcap \
2897 options:rxq_pcap=hv1/vif1-rx.pcap \
2898 ofport-request=1
2899
2900ovs-vsctl -- add-port br-int vif2 -- \
2901 set interface vif2 external-ids:iface-id=ls1-lp2 \
2902 options:tx_pcap=hv1/vif2-tx.pcap \
2903 options:rxq_pcap=hv1/vif2-rx.pcap \
2904 ofport-request=1
2905
2906
2907# Allow some time for ovn-northd and ovn-controller to catch up.
2908# XXX This should be more systematic.
2909sleep 1
2910
2911# Send ip packets between the two ports.
2912ip_to_hex() {
2913 printf "%02x%02x%02x%02x" "$@"
2914}
4685e523
JP
2915
2916# Packet to send.
2917src_mac="f00000010203"
2918dst_mac="000000010203"
2919src_ip=`ip_to_hex 192 168 1 2`
2920dst_ip=`ip_to_hex 172 16 1 2`
2921packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2922as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
2923
2924
2925echo "---------NB dump-----"
2926ovn-nbctl show
2927echo "---------------------"
2928ovn-nbctl list logical_router
2929echo "---------------------"
2930ovn-nbctl list logical_router_port
2931echo "---------------------"
2932
2933echo "---------SB dump-----"
2934ovn-sbctl list datapath_binding
2935echo "---------------------"
2936ovn-sbctl list logical_flow
2937echo "---------------------"
2938
2939echo "------ hv1 dump ----------"
2940as hv1 ovs-ofctl dump-flows br-int
2941
2942
2943#Disable router R1
2944ovn-nbctl set Logical_Router R1 enabled=false
2945
3b8cd0ea
BP
2946# Allow some time for ovn-northd and ovn-controller to catch up.
2947# XXX This should be more systematic.
2948sleep 1
2949
4685e523
JP
2950echo "---------SB dump-----"
2951ovn-sbctl list datapath_binding
2952echo "---------------------"
2953ovn-sbctl list logical_flow
2954echo "---------------------"
2955
2956echo "------ hv1 dump ----------"
2957as hv1 ovs-ofctl dump-flows br-int
2958
2959as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
2960
2961# Packet to Expect
2962expect_src_mac="000000010203"
2963expect_dst_mac="f00000010204"
49d7c759 2964echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 2965
49d7c759 2966OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
2967
2968
2969as hv1
2970OVS_APP_EXIT_AND_WAIT([ovn-controller])
2971OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2972OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2973
2974as ovn-sb
2975OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2976
2977as ovn-nb
2978OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2979
2980as northd
2981OVS_APP_EXIT_AND_WAIT([ovn-northd])
2982
2983as main
2984OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2985OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2986
2987AT_CLEANUP
2988
2989
2990AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
2991AT_KEYWORDS([router-admin-state])
2992AT_SKIP_IF([test $HAVE_PYTHON = no])
2993ovn_start
2994
2995# Logical network:
2996# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
2997# and has switch ls2 (172.16.1.0/24) connected to it.
2998
fa2a27b2 2999ovn-nbctl lr-add R1
5412db30 3000
ea46a4e9
JP
3001ovn-nbctl ls-add ls1
3002ovn-nbctl ls-add ls2
5412db30
J
3003
3004# Connect ls1 to R1
bf44c2cd 3005ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3006ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3007 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3008
3009# Connect ls2 to R1
bf44c2cd 3010ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3011ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3012 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3013
3014# Create logical port ls1-lp1 in ls1
31ed1192
JP
3015ovn-nbctl lsp-add ls1 ls1-lp1 \
3016-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3017
3018# Create logical port ls2-lp1 in ls2
31ed1192
JP
3019ovn-nbctl lsp-add ls2 ls2-lp1 \
3020-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3021
3022# Create one hypervisor and create OVS ports corresponding to logical ports.
3023net_add n1
3024
3025sim_add hv1
3026as hv1
3027ovs-vsctl add-br br-phys
3028ovn_attach n1 br-phys 192.168.0.1
3029ovs-vsctl -- add-port br-int vif1 -- \
3030 set interface vif1 external-ids:iface-id=ls1-lp1 \
3031 options:tx_pcap=hv1/vif1-tx.pcap \
3032 options:rxq_pcap=hv1/vif1-rx.pcap \
3033 ofport-request=1
3034
3035ovs-vsctl -- add-port br-int vif2 -- \
3036 set interface vif2 external-ids:iface-id=ls2-lp1 \
3037 options:tx_pcap=hv1/vif2-tx.pcap \
3038 options:rxq_pcap=hv1/vif2-rx.pcap \
3039 ofport-request=1
3040
3041
3042# Allow some time for ovn-northd and ovn-controller to catch up.
3043# XXX This should be more systematic.
3044sleep 1
3045
3046# Send ip packets between the two ports.
3047ip_to_hex() {
3048 printf "%02x%02x%02x%02x" "$@"
3049}
5412db30
J
3050
3051# Packet to send.
3052src_mac="f00000010203"
3053dst_mac="000000010203"
3054src_ip=`ip_to_hex 192 168 1 2`
3055dst_ip=`ip_to_hex 172 16 1 2`
3056packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3057as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3058
3059
3060echo "---------NB dump-----"
3061ovn-nbctl show
3062echo "---------------------"
3063ovn-nbctl list logical_router
3064echo "---------------------"
3065ovn-nbctl list logical_router_port
3066echo "---------------------"
3067
3068echo "---------SB dump-----"
3069ovn-sbctl list datapath_binding
3070echo "---------------------"
3071ovn-sbctl list logical_flow
3072echo "---------------------"
3073
3074echo "------ hv1 dump ----------"
3075as hv1 ovs-ofctl dump-flows br-int
3076
5412db30
J
3077#Disable router R1
3078ovn-nbctl set Logical_Router R1 enabled=false
3079
3080echo "---------SB dump-----"
3081ovn-sbctl list datapath_binding
3082echo "---------------------"
3083ovn-sbctl list logical_flow
3084echo "---------------------"
3085
3086echo "------ hv1 dump ----------"
3087as hv1 ovs-ofctl dump-flows br-int
3088
a1361a6e
LR
3089# Allow some time for the disabling of logical router R1 to propagate.
3090# XXX This should be more systematic.
3091sleep 1
3092
5412db30
J
3093as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3094
3095# Packet to Expect
3096expect_src_mac="000000010204"
3097expect_dst_mac="f00000010204"
49d7c759 3098echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3099
49d7c759 3100OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3101
7a8f15e0 3102OVN_CLEANUP([hv1])
5412db30
J
3103
3104AT_CLEANUP
3105
28dc3fe9
SR
3106AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3107AT_KEYWORDS([ovnstaticroutespeer])
3108AT_SKIP_IF([test $HAVE_PYTHON = no])
3109ovn_start
3110
3111# Logical network:
3112# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3113# network. R1 has switchess foo (192.168.1.0/24)
3114# connected to it.
3115# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3116
fa2a27b2
JP
3117ovn-nbctl lr-add R1
3118ovn-nbctl lr-add R2
28dc3fe9 3119
ea46a4e9
JP
3120ovn-nbctl ls-add foo
3121ovn-nbctl ls-add alice
3122ovn-nbctl ls-add bob
28dc3fe9
SR
3123
3124# Connect foo to R1
bf44c2cd 3125ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3126ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3127 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3128
3129# Connect alice to R2
bf44c2cd 3130ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3131ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3132 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3133
3134# Connect bob to R2
bf44c2cd 3135ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3136ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3137 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3138
3139# Connect R1 to R2
4685e523
JP
3140ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3141ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3142
3143#install static routes
e48ccf3c
JP
3144ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3145ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3146ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3147
3148# Create logical port foo1 in foo
31ed1192
JP
3149ovn-nbctl lsp-add foo foo1 \
3150-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3151
3152# Create logical port alice1 in alice
31ed1192
JP
3153ovn-nbctl lsp-add alice alice1 \
3154-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3155
3156# Create logical port bob1 in bob
31ed1192
JP
3157ovn-nbctl lsp-add bob bob1 \
3158-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3159
3160# Create two hypervisor and create OVS ports corresponding to logical ports.
3161net_add n1
3162
3163sim_add hv1
3164as hv1
3165ovs-vsctl add-br br-phys
3166ovn_attach n1 br-phys 192.168.0.1
3167ovs-vsctl -- add-port br-int hv1-vif1 -- \
3168 set interface hv1-vif1 external-ids:iface-id=foo1 \
3169 options:tx_pcap=hv1/vif1-tx.pcap \
3170 options:rxq_pcap=hv1/vif1-rx.pcap \
3171 ofport-request=1
3172
3173ovs-vsctl -- add-port br-int hv1-vif2 -- \
3174 set interface hv1-vif2 external-ids:iface-id=alice1 \
3175 options:tx_pcap=hv1/vif2-tx.pcap \
3176 options:rxq_pcap=hv1/vif2-rx.pcap \
3177 ofport-request=2
3178
3179sim_add hv2
3180as hv2
3181ovs-vsctl add-br br-phys
3182ovn_attach n1 br-phys 192.168.0.2
3183ovs-vsctl -- add-port br-int hv2-vif1 -- \
3184 set interface hv2-vif1 external-ids:iface-id=bob1 \
3185 options:tx_pcap=hv2/vif1-tx.pcap \
3186 options:rxq_pcap=hv2/vif1-rx.pcap \
3187 ofport-request=1
3188
3189
3190# Pre-populate the hypervisors' ARP tables so that we don't lose any
3191# packets for ARP resolution (native tunneling doesn't queue packets
3192# for ARP resolution).
3193ovn_populate_arp
3194
3195# Allow some time for ovn-northd and ovn-controller to catch up.
3196# XXX This should be more systematic.
3197sleep 1
3198
3199ip_to_hex() {
3200 printf "%02x%02x%02x%02x" "$@"
3201}
28dc3fe9
SR
3202
3203# Send ip packets between foo1 and alice1
3204src_mac="f00000010203"
3205dst_mac="000000010203"
3206src_ip=`ip_to_hex 192 168 1 2`
3207dst_ip=`ip_to_hex 172 16 1 2`
3208packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3209as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3210
3211# Send ip packets between foo1 and bob1
3212src_mac="f00000010203"
3213dst_mac="000000010203"
3214src_ip=`ip_to_hex 192 168 1 2`
3215dst_ip=`ip_to_hex 172 16 2 2`
3216packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3217as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3218
3219echo "---------NB dump-----"
3220ovn-nbctl show
3221echo "---------------------"
3222ovn-nbctl list logical_router
3223echo "---------------------"
3224ovn-nbctl list logical_router_port
3225echo "---------------------"
3226
3227echo "---------SB dump-----"
3228ovn-sbctl list datapath_binding
3229echo "---------------------"
3230ovn-sbctl list port_binding
3231echo "---------------------"
3232
3233echo "------ hv1 dump ----------"
3234as hv1 ovs-ofctl dump-flows br-int
3235echo "------ hv2 dump ----------"
3236as hv2 ovs-ofctl dump-flows br-int
3237
3238# Packet to Expect at bob1
3239src_mac="000000010205"
3240dst_mac="f00000010205"
3241src_ip=`ip_to_hex 192 168 1 2`
3242dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3243echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3244
49d7c759 3245OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3246
3247# Packet to Expect at alice1
3248src_mac="000000010204"
3249dst_mac="f00000010204"
3250src_ip=`ip_to_hex 192 168 1 2`
3251dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3252echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3253
49d7c759 3254OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3255
7a8f15e0 3256OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3257
3258AT_CLEANUP
5412db30 3259
0ee8aaf6
RR
3260AT_SETUP([ovn -- send gratuitous arp on localnet])
3261AT_KEYWORDS([ovn])
d08dbed7 3262AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3263ovn_start
ea46a4e9 3264ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3265net_add n1
3266sim_add hv
3267as hv
3268ovs-vsctl \
3269 -- add-br br-phys \
3270 -- add-br br-eth0
3271
3272ovn_attach n1 br-phys 192.168.0.1
3273
3274AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3275AT_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])
3276
3277# Create a vif.
31ed1192
JP
3278AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3279AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3280AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3281
3282# Create a localnet port.
31ed1192
JP
3283AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3284AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3285AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3286AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3287
3288AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3289
3290# Wait for packet to be received.
49d7c759
BP
3291echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3292OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6
RR
3293
3294# Delete the localnet ports.
3295AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3296AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3297
7a8f15e0 3298OVN_CLEANUP([hv])
0ee8aaf6
RR
3299
3300AT_CLEANUP
75cf9d2b
GS
3301
3302AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3303AT_KEYWORDS([ovnstaticroutes])
3304AT_SKIP_IF([test $HAVE_PYTHON = no])
3305ovn_start
3306
3307# Logical network:
3308# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3309# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3310# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3311# connected to it.
3312
fa2a27b2
JP
3313ovn-nbctl lr-add R1
3314ovn-nbctl lr-add R2
3315ovn-nbctl lr-add R3
75cf9d2b 3316
ea46a4e9
JP
3317ovn-nbctl ls-add foo
3318ovn-nbctl ls-add alice
3319ovn-nbctl ls-add bob
3320ovn-nbctl ls-add join
75cf9d2b
GS
3321
3322# Connect foo to R1
31114af7 3323ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3324ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3325 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
3326
3327# Connect alice to R2
31114af7 3328ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3329ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3330 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
3331
3332# Connect bob to R3
31114af7 3333ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 3334ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 3335 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
3336
3337# Connect R1 to join
31114af7 3338ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3339ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3340 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
3341
3342# Connect R2 to join
31114af7 3343ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3344ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3345 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
3346
3347# Connect R3 to join
31114af7 3348ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 3349ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 3350 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
3351
3352#install static routes
e48ccf3c
JP
3353ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3354ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 3355
e48ccf3c
JP
3356ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3357ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 3358
e48ccf3c
JP
3359ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3360ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
3361
3362# Create logical port foo1 in foo
31ed1192
JP
3363ovn-nbctl lsp-add foo foo1 \
3364-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
3365
3366# Create logical port alice1 in alice
31ed1192
JP
3367ovn-nbctl lsp-add alice alice1 \
3368-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
3369
3370# Create logical port bob1 in bob
31ed1192
JP
3371ovn-nbctl lsp-add bob bob1 \
3372-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
3373
3374# Create two hypervisor and create OVS ports corresponding to logical ports.
3375net_add n1
3376
3377sim_add hv1
3378as hv1
3379ovs-vsctl add-br br-phys
3380ovn_attach n1 br-phys 192.168.0.1
3381ovs-vsctl -- add-port br-int hv1-vif1 -- \
3382 set interface hv1-vif1 external-ids:iface-id=foo1 \
3383 options:tx_pcap=hv1/vif1-tx.pcap \
3384 options:rxq_pcap=hv1/vif1-rx.pcap \
3385 ofport-request=1
3386
3387ovs-vsctl -- add-port br-int hv1-vif2 -- \
3388 set interface hv1-vif2 external-ids:iface-id=alice1 \
3389 options:tx_pcap=hv1/vif2-tx.pcap \
3390 options:rxq_pcap=hv1/vif2-rx.pcap \
3391 ofport-request=2
3392
3393sim_add hv2
3394as hv2
3395ovs-vsctl add-br br-phys
3396ovn_attach n1 br-phys 192.168.0.2
3397ovs-vsctl -- add-port br-int hv2-vif1 -- \
3398 set interface hv2-vif1 external-ids:iface-id=bob1 \
3399 options:tx_pcap=hv2/vif1-tx.pcap \
3400 options:rxq_pcap=hv2/vif1-rx.pcap \
3401 ofport-request=1
3402
3403
3404# Pre-populate the hypervisors' ARP tables so that we don't lose any
3405# packets for ARP resolution (native tunneling doesn't queue packets
3406# for ARP resolution).
3407ovn_populate_arp
3408
3409# Allow some time for ovn-northd and ovn-controller to catch up.
3410# XXX This should be more systematic.
3411sleep 1
3412
3413ip_to_hex() {
3414 printf "%02x%02x%02x%02x" "$@"
3415}
75cf9d2b
GS
3416
3417# Send ip packets between foo1 and alice1
3418src_mac="f00000010203"
3419dst_mac="000001010203"
3420src_ip=`ip_to_hex 192 168 1 2`
3421dst_ip=`ip_to_hex 172 16 1 2`
3422packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3423as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3424as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3425
3426# Send ip packets between foo1 and bob1
3427src_mac="f00000010203"
3428dst_mac="000001010203"
3429src_ip=`ip_to_hex 192 168 1 2`
3430dst_ip=`ip_to_hex 10 32 1 2`
3431packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3432as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3433
3434echo "---------NB dump-----"
3435ovn-nbctl show
3436echo "---------------------"
3437ovn-nbctl list logical_router
3438echo "---------------------"
3439ovn-nbctl list logical_router_port
3440echo "---------------------"
3441
3442echo "---------SB dump-----"
3443ovn-sbctl list datapath_binding
3444echo "---------------------"
3445ovn-sbctl list port_binding
3446echo "---------------------"
3447ovn-sbctl dump-flows
3448echo "---------------------"
3449
3450echo "------ hv1 dump ----------"
3451as hv1 ovs-ofctl show br-int
3452as hv1 ovs-ofctl dump-flows br-int
3453echo "------ hv2 dump ----------"
3454as hv2 ovs-ofctl show br-int
3455as hv2 ovs-ofctl dump-flows br-int
3456echo "----------------------------"
3457
3458# Packet to Expect at bob1
3459src_mac="000003010203"
3460dst_mac="f00000010205"
3461src_ip=`ip_to_hex 192 168 1 2`
3462dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 3463echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3464
49d7c759 3465OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
3466
3467# Packet to Expect at alice1
3468src_mac="000002010203"
3469dst_mac="f00000010204"
3470src_ip=`ip_to_hex 192 168 1 2`
3471dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3472echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3473
49d7c759 3474OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 3475
7a8f15e0 3476OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
3477
3478AT_CLEANUP
c1645003 3479
281977f7
NS
3480AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3481AT_KEYWORDS([dhcpv4])
3482AT_SKIP_IF([test $HAVE_PYTHON = no])
3483ovn_start
3484
3485ovn-nbctl ls-add ls1
3486
3487ovn-nbctl lsp-add ls1 ls1-lp1 \
3488-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3489
3490ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3491
3492ovn-nbctl lsp-add ls1 ls1-lp2 \
3493-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3494
3495ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3496
3497ovn-nbctl ls-add ls2
3498ovn-nbctl lsp-add ls2 ls2-lp1 \
3499-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3500ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3501ovn-nbctl lsp-add ls2 ls2-lp2 \
3502-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3503ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3504
3505ovn-nbctl -- --id=@d1 create DHCP_Options cidr=10.0.0.0/24 \
3506options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3507\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"" \
3508-- add Logical_Switch_Port ls1-lp1 dhcpv4_options @d1 \
3509-- add Logical_Switch_Port ls1-lp2 dhcpv4_options @d1
3510
3511ovn-nbctl -- --id=@d2 create DHCP_Options cidr=30.0.0.0/24 \
3512options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3513\"lease_time\"=\"3600\"" -- add Logical_Switch_Port ls2-lp2 dhcpv4_options @d2
3514
3515net_add n1
3516sim_add hv1
3517
3518as hv1
3519ovs-vsctl add-br br-phys
3520ovn_attach n1 br-phys 192.168.0.1
3521ovs-vsctl -- add-port br-int hv1-vif1 -- \
3522 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3523 options:tx_pcap=hv1/vif1-tx.pcap \
3524 options:rxq_pcap=hv1/vif1-rx.pcap \
3525 ofport-request=1
3526
3527ovs-vsctl -- add-port br-int hv1-vif2 -- \
3528 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3529 options:tx_pcap=hv1/vif2-tx.pcap \
3530 options:rxq_pcap=hv1/vif2-rx.pcap \
3531 ofport-request=2
3532
3533ovs-vsctl -- add-port br-int hv1-vif3 -- \
3534 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3535 options:tx_pcap=hv1/vif3-tx.pcap \
3536 options:rxq_pcap=hv1/vif3-rx.pcap \
3537 ofport-request=3
3538
3539ovs-vsctl -- add-port br-int hv1-vif4 -- \
3540 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3541 options:tx_pcap=hv1/vif4-tx.pcap \
3542 options:rxq_pcap=hv1/vif4-rx.pcap \
3543 ofport-request=4
3544
3545ovn_populate_arp
3546
3547sleep 2
3548
3549as hv1 ovs-vsctl show
3550
281977f7
NS
3551# This shell function sends a DHCP request packet
3552# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3553test_dhcp() {
3554 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4
3555 local request=ffffffffffff${src_mac}080045100110000000008011000000000000ffffffff
3556 # udp header and dhcp header
3557 request+=0044004300fc0000
3558 request+=010106006359aa760000000000000000000000000000000000000000${src_mac}
3559 # client hardware padding
3560 request+=00000000000000000000
3561 # server hostname
3562 request+=0000000000000000000000000000000000000000000000000000000000000000
3563 request+=0000000000000000000000000000000000000000000000000000000000000000
3564 # boot file name
3565 request+=0000000000000000000000000000000000000000000000000000000000000000
3566 request+=0000000000000000000000000000000000000000000000000000000000000000
3567 request+=0000000000000000000000000000000000000000000000000000000000000000
3568 request+=0000000000000000000000000000000000000000000000000000000000000000
3569 # dhcp magic cookie
3570 request+=63825363
3571 # dhcp message type
3572 request+=3501${dhcp_type}ff
3573
3574 if test $offer_ip != 0; then
3575 local srv_mac=$5 srv_ip=$6 expected_dhcp_opts=$7
3576 # total IP length will be the IP length of the request packet
3577 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3578 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3579 udp_len=`expr $ip_len - 20`
3580 printf -v ip_len "%x" $ip_len
3581 printf -v udp_len "%x" $udp_len
3582 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3583 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3584 # udp header and dhcp header.
3585 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
3586 reply+=004300440${udp_len}0000020106006359aa760000000000000000
3587 # your ip address
3588 reply+=${offer_ip}
3589 # next server ip address, relay agent ip address, client mac address
3590 reply+=0000000000000000${src_mac}
3591 # client hardware padding
3592 reply+=00000000000000000000
3593 # server hostname
3594 reply+=0000000000000000000000000000000000000000000000000000000000000000
3595 reply+=0000000000000000000000000000000000000000000000000000000000000000
3596 # boot file name
3597 reply+=0000000000000000000000000000000000000000000000000000000000000000
3598 reply+=0000000000000000000000000000000000000000000000000000000000000000
3599 reply+=0000000000000000000000000000000000000000000000000000000000000000
3600 reply+=0000000000000000000000000000000000000000000000000000000000000000
3601 # dhcp magic cookie
3602 reply+=63825363
3603 # dhcp message type
3604 local dhcp_reply_type=02
3605 if test $dhcp_type = 03; then
3606 dhcp_reply_type=05
3607 fi
3608 reply+=3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3609 echo $reply >> $inport.expected
3610 else
3611 shift; shift; shift; shift;
3612 for outport; do
e4543cfe 3613 echo $request >> $outport.expected
281977f7
NS
3614 done
3615 fi
3616 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3617}
3618
3619reset_pcap_file() {
3620 local iface=$1
3621 local pcap_file=$2
3622 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3623options:rxq_pcap=dummy-rx.pcap
3624 rm -f ${pcap_file}*.pcap
3625 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3626options:rxq_pcap=${pcap_file}-rx.pcap
3627}
3628
3629ip_to_hex() {
3630 printf "%02x%02x%02x%02x" "$@"
3631}
3632
3633AT_CAPTURE_FILE([ofctl_monitor0.log])
3634as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3635--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3636
3637echo "---------NB dump-----"
3638ovn-nbctl show
3639echo "---------------------"
3640echo "---------SB dump-----"
3641ovn-sbctl list datapath_binding
3642echo "---------------------"
3643ovn-sbctl list logical_flow
3644echo "---------------------"
3645
3646echo "---------------------"
3647ovn-sbctl dump-flows
3648echo "---------------------"
3649
3650echo "------ hv1 dump ----------"
3651as hv1 ovs-ofctl dump-flows br-int
3652
3653# Send DHCPDISCOVER.
3654offer_ip=`ip_to_hex 10 0 0 4`
3655server_ip=`ip_to_hex 10 0 0 1`
3656expected_dhcp_opts=0104ffffff0003040a00000136040a000001330400000e10
3657test_dhcp 1 f00000000001 01 $offer_ip ff1000000001 $server_ip $expected_dhcp_opts
3658
3659# NXT_RESUMEs should be 1.
3660OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3661
3662$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3663cat 1.expected | cut -c -48 > expout
3664AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3665# Skipping the IPv4 checksum.
3666cat 1.expected | cut -c 53- > expout
3667AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3668
3669# ovs-ofctl also resumes the packets and this causes other ports to receive
3670# the DHCP request packet. So reset the pcap files so that its easier to test.
3671reset_pcap_file hv1-vif1 hv1/vif1
3672reset_pcap_file hv1-vif2 hv1/vif2
3673rm -f 1.expected
3674rm -f 2.expected
3675
3676# Send DHCPREQUEST.
3677offer_ip=`ip_to_hex 10 0 0 6`
3678server_ip=`ip_to_hex 10 0 0 1`
3679expected_dhcp_opts=0104ffffff0003040a00000136040a000001330400000e10
3680test_dhcp 2 f00000000002 03 $offer_ip ff1000000001 $server_ip $expected_dhcp_opts
3681
3682# NXT_RESUMEs should be 2.
3683OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3684
3685$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3686cat 2.expected | cut -c -48 > expout
3687AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3688# Skipping the IPv4 checksum.
3689cat 2.expected | cut -c 53- > expout
3690AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3691
3692reset_pcap_file hv1-vif1 hv1/vif1
3693reset_pcap_file hv1-vif2 hv1/vif2
3694rm -f 1.expected
3695rm -f 2.expected
3696
3697# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3698# but should be resumed without the reply.
3699# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3700# one from ovn-controller and the other from "ovs-ofctl resume."
3701offer_ip=0
3702test_dhcp 2 f00000000002 08 $offer_ip 1 1
3703
3704# NXT_RESUMEs should be 3.
3705OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3706
3707# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 3708OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
3709
3710reset_pcap_file hv1-vif1 hv1/vif1
3711reset_pcap_file hv1-vif2 hv1/vif2
3712rm -f 1.expected
3713rm -f 2.expected
3714
3715# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3716# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3717
3718test_dhcp 3 f00000000003 01 0 4
3719
3720# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3721# this lport.
3722test_dhcp 4 f00000000004 01 0 3
3723
3724# NXT_RESUMEs should be 3.
3725OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3726
49d7c759
BP
3727OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
3728OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7
NS
3729
3730as hv1
33ac3c83
NS
3731OVS_APP_EXIT_AND_WAIT([ovn-controller])
3732OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3733OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3734
3735as ovn-sb
3736OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3737
3738as ovn-nb
3739OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3740
3741as northd
3742OVS_APP_EXIT_AND_WAIT([ovn-northd])
3743
3744as main
3745OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3746OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3747
3748AT_CLEANUP
3749
40df4566 3750AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
3751AT_KEYWORDS([dhcpv6])
3752AT_SKIP_IF([test $HAVE_PYTHON = no])
3753ovn_start
3754
3755ovn-nbctl ls-add ls1
3756ovn-nbctl lsp-add ls1 ls1-lp1 \
3757-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3758
3759ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3760
3761ovn-nbctl lsp-add ls1 ls1-lp2 \
3762-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3763
3764ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3765
40df4566
ZKL
3766ovn-nbctl lsp-add ls1 ls1-lp3 \
3767-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3768
3769ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3770
33ac3c83
NS
3771ovn-nbctl -- --id=@d1 create DHCP_Options cidr="ae70\:\:/64" \
3772options="\"server_id\"=\"00:00:00:10:00:01\"" \
3773-- add Logical_Switch_Port ls1-lp1 dhcpv6_options @d1 \
3774-- add Logical_Switch_Port ls1-lp2 dhcpv6_options @d1
3775
40df4566
ZKL
3776ovn-nbctl -- --id=@d2 create DHCP_Options cidr="ae70\:\:/64" \
3777options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"" \
3778-- add Logical_Switch_Port ls1-lp3 dhcpv6_options @d2
3779
33ac3c83
NS
3780ovn-nbctl ls-add ls2
3781ovn-nbctl lsp-add ls2 ls2-lp1 \
3782-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
3783ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
3784ovn-nbctl lsp-add ls2 ls2-lp2 \
3785-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
3786ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
3787
3788net_add n1
3789sim_add hv1
3790
3791as hv1
3792ovs-vsctl add-br br-phys
3793ovn_attach n1 br-phys 192.168.0.1
3794ovs-vsctl -- add-port br-int hv1-vif1 -- \
3795 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3796 options:tx_pcap=hv1/vif1-tx.pcap \
3797 options:rxq_pcap=hv1/vif1-rx.pcap \
3798 ofport-request=1
3799
3800ovs-vsctl -- add-port br-int hv1-vif2 -- \
3801 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3802 options:tx_pcap=hv1/vif2-tx.pcap \
3803 options:rxq_pcap=hv1/vif2-rx.pcap \
3804 ofport-request=2
3805
3806ovs-vsctl -- add-port br-int hv1-vif3 -- \
3807 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3808 options:tx_pcap=hv1/vif3-tx.pcap \
3809 options:rxq_pcap=hv1/vif3-rx.pcap \
3810 ofport-request=3
3811
3812ovs-vsctl -- add-port br-int hv1-vif4 -- \
3813 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3814 options:tx_pcap=hv1/vif4-tx.pcap \
3815 options:rxq_pcap=hv1/vif4-rx.pcap \
3816 ofport-request=4
3817
40df4566
ZKL
3818ovs-vsctl -- add-port br-int hv1-vif5 -- \
3819 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
3820 options:tx_pcap=hv1/vif5-tx.pcap \
3821 options:rxq_pcap=hv1/vif5-rx.pcap \
3822 ofport-request=5
3823
33ac3c83
NS
3824ovn_populate_arp
3825
3826sleep 2
3827
3828trim_zeros() {
3829 sed 's/\(00\)\{1,\}$//'
3830}
3831
3832# This shell function sends a DHCPv6 request packet
40df4566
ZKL
3833# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
3834# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
3835# packet should be received twice (one from ovn-controller and the other
3836# from the "ovs-ofctl monitor br-int resume"
3837test_dhcpv6() {
3838 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
3839 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
3840 # dst ip ff02::1:2
3841 request+=ff020000000000000000000000010002
3842 # udp header and dhcpv6 header
3843 request+=02220223002affff${msg_code}010203
3844 # Client identifier
3845 request+=0001000a00030001${src_mac}
3846 # IA-NA (Identity Association for Non Temporary Address)
3847 request+=0003000c0102030400000e1000001518
3848 shift; shift; shift; shift; shift;
3849 if test $offer_ip != 0; then
3850 local server_mac=000000100001
3851 local server_lla=fe80000000000000020000fffe100001
3852 local reply_code=07
3853 if test $msg_code = 01; then
3854 reply_code=02
3855 fi
40df4566
ZKL
3856 local msg_len=54
3857 if test $offer_ip = 1; then
3858 msg_len=28
3859 fi
3860 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 3861 # udp header and dhcpv6 header
40df4566 3862 reply+=0223022200${msg_len}ffff${reply_code}010203
33ac3c83
NS
3863 # Client identifier
3864 reply+=0001000a00030001${src_mac}
3865 # IA-NA
40df4566
ZKL
3866 if test $offer_ip != 1; then
3867 reply+=0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
3868 fi
33ac3c83
NS
3869 # Server identifier
3870 reply+=0002000a00030001${server_mac}
3871 echo $reply | trim_zeros >> $inport.expected
3872 else
3873 for outport; do
3874 echo $request | trim_zeros >> $outport.expected
3875 done
3876 fi
3877
3878 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3879}
3880
3881reset_pcap_file() {
3882 local iface=$1
3883 local pcap_file=$2
3884 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3885options:rxq_pcap=dummy-rx.pcap
3886 rm -f ${pcap_file}*.pcap
3887 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3888options:rxq_pcap=${pcap_file}-rx.pcap
3889}
3890
3891AT_CAPTURE_FILE([ofctl_monitor0.log])
3892as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3893--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3894
3895echo "---------NB dump-----"
3896ovn-nbctl show
3897echo "---------------------"
3898echo "---------SB dump-----"
3899ovn-sbctl list datapath_binding
3900echo "---------------------"
3901ovn-sbctl list logical_flow
3902echo "---------------------"
3903
3904echo "---------------------"
3905ovn-sbctl dump-flows
3906echo "---------------------"
3907
3908echo "------ hv1 dump ----------"
3909as hv1 ovs-ofctl dump-flows br-int
3910
3911src_mac=f00000000001
3912src_lla=fe80000000000000f20000fffe000001
3913offer_ip=ae700000000000000000000000000004
3914test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
3915
3916# NXT_RESUMEs should be 1.
3917OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3918
3919$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
3920# cat 1.expected | trim_zeros > expout
3921cat 1.expected | cut -c -120 > expout
3922AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
3923# Skipping the UDP checksum
3924cat 1.expected | cut -c 125- > expout
3925AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
3926
3927rm 1.expected
3928
3929# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
3930# without any modifications and the packet should be received by ls1-lp1.
3931# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
3932# resume and the other from ovs-ofctl monitor resume.
3933
3934reset_pcap_file hv1-vif1 hv1/vif1
3935reset_pcap_file hv1-vif2 hv1/vif2
3936
3937src_mac=f00000000002
3938src_lla=fe80000000000000f20000fffe000002
3939offer_ip=ae700000000000000000000000000005
3940# Set invalid msg_type
3941
3942test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
3943
3944# NXT_RESUMEs should be 2.
3945OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3946
3947# vif2-tx.pcap should not have received the DHCPv6 reply packet
3948rm 2.packets
3949$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
3950AT_CHECK([cat 2.packets], [0], [])
3951
3952# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
3953$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
3954cat 1.expected > expout
3955AT_CHECK([cat 1.packets], [0], [expout])
3956
3957# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
3958# There should be no DHCPv6 reply from ovn-controller and the request packet
3959# should be received by ls2-lp2.
3960
3961src_mac=f00000000003
3962src_lla=fe80000000000000f20000fffe000003
3963test_dhcpv6 3 $src_mac $src_lla 01 0 4
3964
3965# NXT_RESUMEs should be 2 only.
3966OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3967
3968# vif3-tx.pcap should not have received the DHCPv6 reply packet
3969$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
3970AT_CHECK([cat 3.packets], [0], [])
3971
3972# vif4-tx.pcap should have received the DHCPv6 request packet
3973$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
3974cat 4.expected > expout
3975AT_CHECK([cat 4.packets], [0], [expout])
3976
40df4566
ZKL
3977# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
3978# The DHCPv6 reply should doesn't contian offer_ip.
3979src_mac=f00000000022
3980src_lla=fe80000000000000f20000fffe000022
3981reset_pcap_file hv1-vif5 hv1/vif5
3982test_dhcpv6 5 $src_mac $src_lla 01 1 5
3983
3984# NXT_RESUMEs should be 3.
3985OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3986
3987$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
3988# Skipping the UDP checksum
3989cat 5.expected | cut -c 1-120,125- > expout
3990AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
3991
33ac3c83 3992as hv1
281977f7
NS
3993OVS_APP_EXIT_AND_WAIT([ovn-controller])
3994OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3995OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3996
3997as ovn-sb
3998OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3999
4000as ovn-nb
4001OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4002
4003as northd
4004OVS_APP_EXIT_AND_WAIT([ovn-northd])
4005
4006as main
4007OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4008OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4009
4010AT_CLEANUP
4011
c1645003
GS
4012AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4013AT_KEYWORDS([ovngatewayrouter])
4014AT_SKIP_IF([test $HAVE_PYTHON = no])
4015ovn_start
4016
4017# Logical network:
4018# Two LRs - R1 and R2 that are connected to each other via LS "join"
4019# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4020# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4021# R2 is a gateway router.
4022
4023
4024
4025# Create two hypervisor and create OVS ports corresponding to logical ports.
4026net_add n1
4027
4028sim_add hv1
4029as hv1
4030ovs-vsctl add-br br-phys
4031ovn_attach n1 br-phys 192.168.0.1
4032ovs-vsctl -- add-port br-int hv1-vif1 -- \
4033 set interface hv1-vif1 external-ids:iface-id=foo1 \
4034 options:tx_pcap=hv1/vif1-tx.pcap \
4035 options:rxq_pcap=hv1/vif1-rx.pcap \
4036 ofport-request=1
4037
4038
4039sim_add hv2
4040as hv2
4041ovs-vsctl add-br br-phys
4042ovn_attach n1 br-phys 192.168.0.2
4043ovs-vsctl -- add-port br-int hv2-vif1 -- \
4044 set interface hv2-vif1 external-ids:iface-id=alice1 \
4045 options:tx_pcap=hv2/vif1-tx.pcap \
4046 options:rxq_pcap=hv2/vif1-rx.pcap \
4047 ofport-request=1
4048
4049# Pre-populate the hypervisors' ARP tables so that we don't lose any
4050# packets for ARP resolution (native tunneling doesn't queue packets
4051# for ARP resolution).
4052ovn_populate_arp
4053
4054ovn-nbctl create Logical_Router name=R1
4055ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4056
ea46a4e9
JP
4057ovn-nbctl ls-add foo
4058ovn-nbctl ls-add alice
4059ovn-nbctl ls-add join
c1645003
GS
4060
4061# Connect foo to R1
31114af7 4062ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4063ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4064 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4065
4066# Connect alice to R2
31114af7 4067ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4068ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4069 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4070
4071# Connect R1 to join
31114af7 4072ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4073ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4074 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4075
4076# Connect R2 to join
31114af7 4077ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4078ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4079 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4080
4081
4082#install static routes
4083ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4084ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4085R1 static_routes @lrt
4086
4087ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4088ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4089R2 static_routes @lrt
4090
4091# Create logical port foo1 in foo
31ed1192
JP
4092ovn-nbctl lsp-add foo foo1 \
4093-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4094
4095# Create logical port alice1 in alice
31ed1192
JP
4096ovn-nbctl lsp-add alice alice1 \
4097-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4098
4099
4100# Allow some time for ovn-northd and ovn-controller to catch up.
4101# XXX This should be more systematic.
4102sleep 2
4103
4104ip_to_hex() {
4105 printf "%02x%02x%02x%02x" "$@"
4106}
c1645003
GS
4107
4108# Send ip packets between foo1 and alice1
4109src_mac="f00000010203"
4110dst_mac="000001010203"
4111src_ip=`ip_to_hex 192 168 1 2`
4112dst_ip=`ip_to_hex 172 16 1 2`
4113packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4114
4115echo "---------NB dump-----"
4116ovn-nbctl show
4117echo "---------------------"
4118ovn-nbctl list logical_router
4119echo "---------------------"
4120ovn-nbctl list logical_router_port
4121echo "---------------------"
4122
4123echo "---------SB dump-----"
4124ovn-sbctl list datapath_binding
4125echo "---------------------"
4126ovn-sbctl list port_binding
4127echo "---------------------"
4128ovn-sbctl dump-flows
4129echo "---------------------"
4130ovn-sbctl list chassis
4131ovn-sbctl list encap
4132echo "---------------------"
4133
c1645003
GS
4134# Packet to Expect at alice1
4135src_mac="000002010203"
4136dst_mac="f00000010204"
4137src_ip=`ip_to_hex 192 168 1 2`
4138dst_ip=`ip_to_hex 172 16 1 2`
4139expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4140
4141
4142as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4143as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4144
ab39371d
RM
4145echo "------ hv1 dump after packet 1 ----------"
4146as hv1 ovs-ofctl show br-int
4147as hv1 ovs-ofctl dump-flows br-int
4148echo "------ hv2 dump after packet 1 ----------"
4149as hv2 ovs-ofctl show br-int
4150as hv2 ovs-ofctl dump-flows br-int
4151echo "----------------------------"
4152
49d7c759
BP
4153echo $expected > expected
4154OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4155
34114cf8
GS
4156# Delete the router and re-create it. Things should work as before.
4157ovn-nbctl lr-del R2
4158ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4159# Connect alice to R2
4160ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4161# Connect R2 to join
4162ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4163
4164ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4165ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4166R2 static_routes @lrt
4167
4168# Wait for ovn-controller to catch up.
4169sleep 1
4170
4171# Send the packet again.
4172as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4173
4174echo "------ hv1 dump after packet 2 ----------"
4175as hv1 ovs-ofctl show br-int
4176as hv1 ovs-ofctl dump-flows br-int
4177echo "------ hv2 dump after packet 2 ----------"
4178as hv2 ovs-ofctl show br-int
4179as hv2 ovs-ofctl dump-flows br-int
4180echo "----------------------------"
4181
49d7c759
BP
4182echo $expected >> expected
4183OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4184
7a8f15e0 4185OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4186
4187AT_CLEANUP
bb3c4568
FF
4188
4189AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4190AT_KEYWORDS([router-icmp-reply])
4191AT_SKIP_IF([test $HAVE_PYTHON = no])
4192ovn_start
4193
4194# Logical network:
4195# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4196# and has switch ls2 (172.16.1.0/24) connected to it.
4197
fa2a27b2 4198ovn-nbctl lr-add R1
bb3c4568 4199
ea46a4e9
JP
4200ovn-nbctl ls-add ls1
4201ovn-nbctl ls-add ls2
bb3c4568
FF
4202
4203# Connect ls1 to R1
31114af7 4204ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4205ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4206 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4207
4208# Connect ls2 to R1
31114af7 4209ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4210ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4211 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4212
4213# Create logical port ls1-lp1 in ls1
31ed1192
JP
4214ovn-nbctl lsp-add ls1 ls1-lp1 \
4215-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4216
4217# Create logical port ls2-lp1 in ls2
31ed1192
JP
4218ovn-nbctl lsp-add ls2 ls2-lp1 \
4219-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4220
4221# Create one hypervisor and create OVS ports corresponding to logical ports.
4222net_add n1
4223
4224sim_add hv1
4225as hv1
4226ovs-vsctl add-br br-phys
4227ovn_attach n1 br-phys 192.168.0.1
4228ovs-vsctl -- add-port br-int vif1 -- \
4229 set interface vif1 external-ids:iface-id=ls1-lp1 \
4230 options:tx_pcap=hv1/vif1-tx.pcap \
4231 options:rxq_pcap=hv1/vif1-rx.pcap \
4232 ofport-request=1
4233
4234ovs-vsctl -- add-port br-int vif2 -- \
4235 set interface vif2 external-ids:iface-id=ls2-lp1 \
4236 options:tx_pcap=hv1/vif2-tx.pcap \
4237 options:rxq_pcap=hv1/vif2-rx.pcap \
4238 ofport-request=1
4239
4240
4241# Allow some time for ovn-northd and ovn-controller to catch up.
4242# XXX This should be more systematic.
4243sleep 1
4244
4245
4246ip_to_hex() {
4247 printf "%02x%02x%02x%02x" "$@"
4248}
bb3c4568
FF
4249for i in 1 2; do
4250 : > vif$i.expected
4251done
4252# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4253#
4254# Causes a packet to be received on INPORT. The packet is an ICMPv4
4255# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4256# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4257# provided, then it should be the ip and icmp checksums of the packet
4258# responded; otherwise, no reply is expected.
4259# In the absence of an ip checksum calculation helpers, this relies
4260# on the caller to provide the checksums for the ip and icmp headers.
4261# XXX This should be more systematic.
4262#
4263# INPORT is an lport number, e.g. 11 for vif11.
4264# ETH_SRC and ETH_DST are each 12 hex digits.
4265# IPV4_SRC and IPV4_DST are each 8 hex digits.
4266# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4267# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4268test_ipv4_icmp_request() {
4269 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4270 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4271 shift; shift; shift; shift; shift; shift; shift
4272 shift; shift
4273
4274 # Use ttl to exercise section 4.2.2.9 of RFC1812
4275 local ip_ttl=01
4276 local icmp_id=5fbf
4277 local icmp_seq=0001
4278 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4279 local icmp_type_code_request=0800
4280 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4281 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4282
4283 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4284 if test X$exp_icmp_chksum != X; then
4285 # Expect to receive the reply, if any. In same port where packet was sent.
4286 # Note: src and dst fields are expected to be reversed.
4287 local icmp_type_code_response=0000
4288 local reply_icmp_ttl=fe
4289 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4290 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4291 echo $reply >> vif$inport.expected
4292 fi
4293}
4294
4295# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4296rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4297rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4298l1_ip=$(ip_to_hex 192 168 1 2)
4299l2_ip=$(ip_to_hex 172 16 1 2)
4300
4301# Ping router ip address that is on same subnet as the logical port
4302test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4303test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4304
4305# Ping router ip address that is on the other side of the logical ports
4306test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4307test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4308
4309echo "---------NB dump-----"
4310ovn-nbctl show
4311echo "---------------------"
4312ovn-nbctl list logical_router
4313echo "---------------------"
4314ovn-nbctl list logical_router_port
4315echo "---------------------"
4316
4317echo "---------SB dump-----"
4318ovn-sbctl list datapath_binding
4319echo "---------------------"
4320ovn-sbctl list logical_flow
4321echo "---------------------"
4322
4323echo "------ hv1 dump ----------"
4324as hv1 ovs-ofctl dump-flows br-int
4325
4326# Now check the packets actually received against the ones expected.
4327for inport in 1 2; do
49d7c759 4328 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4329done
4330
7a8f15e0 4331OVN_CLEANUP([hv1])
bb3c4568
FF
4332
4333AT_CLEANUP
94f79fcb
RB
4334
4335# 1 hypervisor, 1 port
4336# make sure that the port state is properly set to up and back down
4337# when created and deleted.
4338AT_SETUP([ovn -- port state up and down])
4339AT_KEYWORDS([ovn])
4340ovn_start
4341
4342ovn-nbctl ls-add ls1
4343ovn-nbctl lsp-add ls1 lp1
4344ovn-nbctl lsp-set-addresses lp1 unknown
4345
4346net_add n1
4347sim_add hv1
4348as hv1 ovs-vsctl add-br br-phys
4349as hv1 ovn_attach n1 br-phys 192.168.0.1
4350
4351as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4352OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4353
4354as hv1 ovs-vsctl del-port br-int vif1
4355OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4356
7a8f15e0 4357OVN_CLEANUP([hv1])
94f79fcb 4358
94f79fcb 4359AT_CLEANUP
e75451fe 4360
f8a8db39
JP
4361AT_SETUP([ovn -- nd_na ])
4362AT_KEYWORDS([ovn-nd_na])
e75451fe
ZKL
4363AT_SKIP_IF([test $HAVE_PYTHON = no])
4364ovn_start
4365
4366#TODO: since patch port for IPv6 logical router port is not ready not,
4367# so we are not going to test vifs on different lswitches cases. Try
4368# to update for that once relevant stuff implemented.
4369
4370# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4371# with. NS packet we test, from one VIF for another VIF, will be replied
4372# by local ovn-controller, but not by target VIF.
4373
4374# Create hypervisors and logical switch lsw0.
4375ovn-nbctl ls-add lsw0
4376net_add n1
4377sim_add hv1
4378as hv1
4379ovs-vsctl add-br br-phys
4380ovn_attach n1 br-phys 192.168.0.2
4381
4382# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4383ovs-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
4384ovn-nbctl lsp-add lsw0 lp1
4385ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4386ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4387
4388# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4389ovs-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
4390ovn-nbctl lsp-add lsw0 lp2
4391ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4392ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4393
4394# Add ACL rule for ICMPv6 on lsw0
4395ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4396ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4397ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4398
4399# Allow some time for ovn-northd and ovn-controller to catch up.
4400# XXX This should be more systematic.
4401sleep 1
4402
4403# Given the name of a logical port, prints the name of the hypervisor
4404# on which it is located.
4405vif_to_hv() {
4406 echo hv1${1%?}
4407}
e75451fe
ZKL
4408for i in 1 2; do
4409 : > $i.expected
4410done
4411
4412# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4413# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4414# vif2 will not receive NS packet, since ovn-controller will reply for it.
4415ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4416na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4417
4418as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 4419echo $na_packet >> 1.expected
e75451fe 4420
e75451fe
ZKL
4421echo "------ hv1 dump ------"
4422as hv1 ovs-vsctl show
4423as hv1 ovs-ofctl -O OpenFlow13 show br-int
4424as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4425
4426for i in 1 2; do
49d7c759 4427 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
4428done
4429
7a8f15e0 4430OVN_CLEANUP([hv1])
e75451fe
ZKL
4431
4432AT_CLEANUP
7417d147
RM
4433
4434AT_SETUP([ovn -- address sets modification/removal smoke test])
4435AT_KEYWORDS([ovn-addr])
4436ovn_start
4437
4438net_add n1
4439
4440sim_add hv1
4441as hv1
4442ovs-vsctl add-br br-phys
4443ovn_attach n1 br-phys 192.168.0.1
4444
4445row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4446ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4447ovn-nbctl destroy Address_Set $row
4448
4449sleep 1
4450
4451# A bug previously existed in the address set support code
4452# that caused ovn-controller to crash after an address set
4453# was updated and then removed. This test case ensures
4454# that ovn-controller is at least still running after
4455# creating, updating, and deleting an address set.
4456AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4457
4458OVN_CLEANUP([hv1])
4459
4460AT_CLEANUP
8639f9be
ND
4461
4462AT_SETUP([ovn -- ipam])
4463AT_KEYWORDS([ovnipam])
4464AT_SKIP_IF([test $HAVE_PYTHON = no])
4465ovn_start
4466
4467# Add a port to a switch that does not have a subnet set, then set the
4468# subnet which should result in an address being allocated for the port.
4469ovn-nbctl ls-add sw0
4470ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
4471ovn-nbctl add Logical-Switch sw0 other_config subnet=192.168.1.0/24
4472AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4473 ["0a:00:00:00:00:01 192.168.1.2"
4474])
4475
4476# Add 9 more ports to sw0, addresses should all be unique.
4477for n in `seq 1 9`; do
4478 ovn-nbctl lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
4479done
4480AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4481 ["0a:00:00:00:00:02 192.168.1.3"
4482])
4483AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4484 ["0a:00:00:00:00:03 192.168.1.4"
4485])
4486AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4487 ["0a:00:00:00:00:04 192.168.1.5"
4488])
4489AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4490 ["0a:00:00:00:00:05 192.168.1.6"
4491])
4492AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4493 ["0a:00:00:00:00:06 192.168.1.7"
4494])
4495AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4496 ["0a:00:00:00:00:07 192.168.1.8"
4497])
4498AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4499 ["0a:00:00:00:00:08 192.168.1.9"
4500])
4501AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4502 ["0a:00:00:00:00:09 192.168.1.10"
4503])
4504AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4505 ["0a:00:00:00:00:0a 192.168.1.11"
4506])
4507
4508# Trying similar tests with a second switch. MAC addresses should be unique
4509# across both switches but IP's only need to be unique within the same switch.
4510ovn-nbctl ls-add sw1
4511ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
4512ovn-nbctl add Logical-Switch sw1 other_config subnet=192.168.1.0/24
4513AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4514 ["0a:00:00:00:00:0b 192.168.1.2"
4515])
4516
4517for n in `seq 11 19`; do
4518 ovn-nbctl lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
4519done
4520AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4521 ["0a:00:00:00:00:0c 192.168.1.3"
4522])
4523AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4524 ["0a:00:00:00:00:0d 192.168.1.4"
4525])
4526AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4527 ["0a:00:00:00:00:0e 192.168.1.5"
4528])
4529AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4530 ["0a:00:00:00:00:0f 192.168.1.6"
4531])
4532AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4533 ["0a:00:00:00:00:10 192.168.1.7"
4534])
4535AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4536 ["0a:00:00:00:00:11 192.168.1.8"
4537])
4538AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4539 ["0a:00:00:00:00:12 192.168.1.9"
4540])
4541AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4542 ["0a:00:00:00:00:13 192.168.1.10"
4543])
4544AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4545 ["0a:00:00:00:00:14 192.168.1.11"
4546])
4547
4548# Change a port's address to test for multiple ip's for a single address entry
4549# and addresses set by the user.
4550ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
4551ovn-nbctl lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
4552AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4553 ["0a:00:00:00:00:16 192.168.1.13"
4554])
4555
4556# Test for logical router port address management.
4557ovn-nbctl create Logical_Router name=R1
4558ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4559network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4560-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4561-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
4562ovn-nbctl lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
4563AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4564 ["0a:00:00:00:00:18 192.168.1.15"
4565])
4566
4567# Test for address reuse after logical port is deleted.
4568ovn-nbctl lsp-del p0
4569ovn-nbctl lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
4570AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4571 ["0a:00:00:00:00:19 192.168.1.2"
4572])
4573
4574# Test for multiple addresses to one logical port.
4575ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4576"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
4577ovn-nbctl lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
4578AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4579 ["0a:00:00:00:00:1c 192.168.1.16"
4580])
4581
4582# Test for exhausting subnet address space.
4583ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
4584ovn-nbctl lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
4585AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4586 ["0a:00:00:00:00:1d 172.16.1.2"
4587])
4588
4589ovn-nbctl lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
4590AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
4591 [[[]]
4592])
4593
4594# Test that address management does not add duplicate MAC for lsp/lrp peers.
4595ovn-nbctl create Logical_Router name=R2
4596ovn-nbctl ls-add sw3
4597ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
4598"0a:00:00:00:00:1e"
4599ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4600network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4601-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4602-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
4603ovn-nbctl lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
4604AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4605 ["0a:00:00:00:00:20 192.168.1.17"
4606])
4607
4608as ovn-sb
4609OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4610
4611as ovn-nb
4612OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4613
4614as northd
4615OVS_APP_EXIT_AND_WAIT([ovn-northd])
4616
4617AT_CLEANUP
4618
4619AT_SETUP([ovn -- ipam connectivity])
4620AT_KEYWORDS([ovnipamconnectivity])
4621AT_SKIP_IF([test $HAVE_PYTHON = no])
4622ovn_start
4623
4624ovn-nbctl lr-add R1
4625
4626# Test for a ping using dynamically allocated addresses.
4627ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
4628ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
4629
4630# Connect foo to R1
4631ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
4632ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4633 options:router-port=foo addresses=\"00:00:00:01:02:03\"
4634
4635# Connect alice to R1
4636ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
4637ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
4638 options:router-port=alice addresses=\"00:00:00:01:02:04\"
4639
4640# Create logical port foo1 in foo
4641ovn-nbctl lsp-add foo foo1 \
4642-- lsp-set-addresses foo1 "dynamic"
4643AT_CHECK([ovn-nbctl get Logical-Switch-Port foo1 dynamic_addresses], [0],
4644 ["0a:00:00:00:00:01 192.168.1.2"
4645])
4646
4647# Create logical port alice1 in alice
4648ovn-nbctl lsp-add alice alice1 \
4649-- lsp-set-addresses alice1 "dynamic"
4650AT_CHECK([ovn-nbctl get Logical-Switch-Port alice1 dynamic_addresses], [0],
4651 ["0a:00:00:00:00:02 192.168.2.2"
4652])
4653
4654# Create logical port foo2 in foo
4655ovn-nbctl lsp-add foo foo2 \
4656-- lsp-set-addresses foo2 "dynamic"
4657AT_CHECK([ovn-nbctl get Logical-Switch-Port foo2 dynamic_addresses], [0],
4658 ["0a:00:00:00:00:03 192.168.1.3"
4659])
4660
4661# Create a hypervisor and create OVS ports corresponding to logical ports.
4662net_add n1
4663
4664sim_add hv1
4665as hv1
4666ovs-vsctl add-br br-phys
4667ovn_attach n1 br-phys 192.168.0.1
4668ovs-vsctl -- add-port br-int hv1-vif1 -- \
4669 set interface hv1-vif1 external-ids:iface-id=foo1 \
4670 options:tx_pcap=hv1/vif1-tx.pcap \
4671 options:rxq_pcap=hv1/vif1-rx.pcap \
4672 ofport-request=1
4673
4674ovs-vsctl -- add-port br-int hv1-vif2 -- \
4675 set interface hv1-vif2 external-ids:iface-id=foo2 \
4676 options:tx_pcap=hv1/vif2-tx.pcap \
4677 options:rxq_pcap=hv1/vif2-rx.pcap \
4678 ofport-request=2
4679
4680ovs-vsctl -- add-port br-int hv1-vif3 -- \
4681 set interface hv1-vif3 external-ids:iface-id=alice1 \
4682 options:tx_pcap=hv1/vif3-tx.pcap \
4683 options:rxq_pcap=hv1/vif3-rx.pcap \
4684 ofport-request=3
4685
4686# Allow some time for ovn-northd and ovn-controller to catch up.
4687# XXX This should be more systematic.
4688sleep 1
4689
4690ip_to_hex() {
4691 printf "%02x%02x%02x%02x" "$@"
4692}
8639f9be
ND
4693
4694# Send ip packets between foo1 and foo2
4695src_mac="0a0000000001"
4696dst_mac="0a0000000003"
4697src_ip=`ip_to_hex 192 168 1 2`
4698dst_ip=`ip_to_hex 192 168 1 3`
4699packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4700as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4701
4702# Send ip packets between foo1 and alice1
4703src_mac="0a0000000001"
4704dst_mac="000000010203"
4705src_ip=`ip_to_hex 192 168 1 2`
4706dst_ip=`ip_to_hex 192 168 2 2`
4707packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4708as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4709
4710echo "---------NB dump-----"
4711ovn-nbctl show
4712echo "---------------------"
4713ovn-nbctl list logical_router
4714echo "---------------------"
4715ovn-nbctl list logical_router_port
4716echo "---------------------"
4717
4718echo "---------SB dump-----"
4719ovn-sbctl list datapath_binding
4720echo "---------------------"
4721ovn-sbctl list port_binding
4722echo "---------------------"
4723
4724echo "------ hv1 dump ----------"
4725as hv1 ovs-ofctl dump-flows br-int
4726
4727# Packet to Expect at foo2
4728src_mac="0a0000000001"
4729dst_mac="0a0000000003"
4730src_ip=`ip_to_hex 192 168 1 2`
4731dst_ip=`ip_to_hex 192 168 1 3`
4732expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4733
e4543cfe
DDP
4734$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
4735echo $expected > expout
8639f9be
ND
4736AT_CHECK([cat received1.packets], [0], [expout])
4737
4738# Packet to Expect at alice1
4739src_mac="000000010204"
4740dst_mac="0a0000000002"
4741src_ip=`ip_to_hex 192 168 1 2`
4742dst_ip=`ip_to_hex 192 168 2 2`
4743expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
4744
e4543cfe
DDP
4745$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
4746echo $expected > expout
8639f9be
ND
4747AT_CHECK([cat received2.packets], [0], [expout])
4748
4749OVN_CLEANUP([hv1])
4750
4751AT_CLEANUP
f5792c3f
NS
4752
4753AT_SETUP([ovn -- ovs-vswitchd restart])
4754AT_KEYWORDS([vswitchd restart])
4755AT_SKIP_IF([test $HAVE_PYTHON = no])
4756ovn_start
4757
4758ovn-nbctl ls-add ls1
4759
4760ovn-nbctl lsp-add ls1 ls1-lp1 \
4761-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4762
4763ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4764
4765net_add n1
4766sim_add hv1
4767
4768as hv1
4769ovs-vsctl add-br br-phys
4770ovn_attach n1 br-phys 192.168.0.1
4771ovs-vsctl -- add-port br-int hv1-vif1 -- \
4772 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4773 options:tx_pcap=hv1/vif1-tx.pcap \
4774 options:rxq_pcap=hv1/vif1-rx.pcap \
4775 ofport-request=1
4776
4777ovn_populate_arp
4778sleep 2
4779
4780as hv1 ovs-vsctl show
4781
4782echo "---------------------"
4783ovn-sbctl dump-flows
4784echo "---------------------"
4785
4786echo "------ hv1 dump ----------"
4787as hv1 ovs-ofctl dump-flows br-int
4788total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4789
4790echo "Total flows before vswitchd restart = " $total_flows
4791
4792# Code taken from ovs-save utility
4793save_flows () {
4794 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
4795 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
4796 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
4797 echo "EOF" >> restore_flows.sh
4798}
4799
4800restart_vswitchd () {
4801 restore_flows=$1
4802
4803 if test $restore_flows = true; then
4804 save_flows
4805 fi
4806
4807 as hv1
4808 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4809
4810 if test $restore_flows = true; then
4811 as hv1
4812 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
4813 fi
4814
4815 as hv1
4816 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
4817 ovs-ofctl dump-flows br-int
4818
4819 if test $restore_flows = true; then
4820 sh ./restore_flows.sh
4821 echo "Flows after restore"
4822 as hv1
4823 ovs-ofctl dump-flows br-int
4824 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
4825 flow-restore-wait="true"
4826 fi
4827}
4828
4829# Save the flows, restart vswitchd and restore the flows
4830restart_vswitchd true
4831OVS_WAIT_UNTIL([
4832 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4833 echo "Total flows after vswitchd restart = " $total_flows_after_restart
4834 test "${total_flows}" = "${total_flows_after_restart}"
4835])
4836
4837# Restart vswitchd without restoring
4838restart_vswitchd false
4839OVS_WAIT_UNTIL([
4840 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4841 echo "Total flows after vswitchd restart = " $total_flows_after_restart
4842 test "${total_flows}" = "${total_flows_after_restart}"
4843])
4844
4845OVN_CLEANUP([hv1])
4846AT_CLEANUP
47021598
CSV
4847
4848AT_SETUP([ovn -- send arp for nexthop])
4849AT_KEYWORDS([ovn])
4850AT_SKIP_IF([test $HAVE_PYTHON = no])
4851ovn_start
4852
4853# Topology: Two LSs - ls1 and ls2 are connected via router r0
4854
4855# Create logical switches
4856ovn-nbctl ls-add ls1
4857ovn-nbctl ls-add ls2
4858
4859# Create router
4860ovn-nbctl create Logical_Router name=lr0
4861
4862# Add router ls1p1 port to gateway router
4863ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
4864ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
4865 type=router options:router-port=lrp-ls1lp1 \
4866 addresses='"f0:00:00:00:00:01 192.168.0.1"'
4867
4868# Add router ls2p2 port to gateway router
4869ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
4870ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
4871 type=router options:router-port=lrp-ls2lp1 \
4872 addresses='"f0:00:00:00:00:02 192.168.1.1"'
4873
4874# Set default gateway (nexthop) to 192.168.1.254
4875ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
4876
4877# Create logical port ls1lp2 in ls1
4878ovn-nbctl lsp-add ls1 ls1lp2 \
4879-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
4880
4881# Create logical port ls2lp2 in ls2
4882ovn-nbctl lsp-add ls2 ls2lp2 \
4883-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
4884
4885net_add n1
4886sim_add hv1
4887as hv1
4888ovs-vsctl add-br br-phys
4889ovn_attach n1 br-phys 192.168.0.1
4890ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
4891 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
4892 options:tx_pcap=hv1/ls1lp2-tx.pcap \
4893 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
4894 ofport-request=1
4895ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
4896 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
4897 options:tx_pcap=hv1/ls2lp2-tx.pcap \
4898 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
4899 ofport-request=2
4900
4901# Allow some time for ovn-northd and ovn-controller to catch up.
4902# XXX This should be more systematic.
4903sleep 1
4904
4905echo "---------NB dump-----"
4906ovn-nbctl show
4907echo "---------------------"
4908ovn-nbctl list logical_router
4909echo "---------------------"
4910ovn-nbctl list logical_router_port
4911echo "---------------------"
4912
4913echo "---------SB dump-----"
4914ovn-sbctl list datapath_binding
4915echo "---------------------"
4916ovn-sbctl list port_binding
4917echo "---------------------"
4918ovn-sbctl dump-flows
4919echo "---------------------"
4920ovn-sbctl list chassis
4921ovn-sbctl list encap
4922echo "---------------------"
4923
4924echo "------Flows dump-----"
4925as hv1
4926ovs-ofctl dump-flows
4927echo "---------------------"
4928
4929ip_to_hex() {
4930 printf "%02x%02x%02x%02x" "$@"
4931}
4932
4933src_mac="f00000000003"
4934dst_mac="f00000000001"
4935src_ip=`ip_to_hex 192 168 0 2`
4936dst_ip=`ip_to_hex 8 8 8 8`
4937packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4938
4939# Send IP packet destined to 8.8.8.8 from lsp1lp2
4940as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
4941
4942trim_zeros() {
4943 sed 's/\(00\)\{1,\}$//'
4944}
4945
4946# ARP packet should be received with Target IP Address set to 192.168.1.254 and
4947# not 8.8.8.8
4948
4949$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
4950expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
4951echo $expected > expout
4952AT_CHECK([cat packets], [0], [expout])
4953cat packets
4954
4955OVN_CLEANUP([hv1])
4956
4957AT_CLEANUP
8439c2eb
CSV
4958
4959AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
4960AT_KEYWORDS([ovn])
4961AT_SKIP_IF([test $HAVE_PYTHON = no])
4962ovn_start
4963# Create logical switch
4964ovn-nbctl ls-add ls0
4965# Create gateway router
4966ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
4967# Add router port to gateway router
4968ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
4969ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
4970 type=router options:router-port=lrp0-rp addresses='"f0:00:00:00:00:01"'
4971# Add nat-address option
4972ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
4973
4974net_add n1
4975sim_add hv1
4976as hv1
4977ovs-vsctl \
4978 -- add-br br-phys \
4979 -- add-br br-eth0
4980
4981ovn_attach n1 br-phys 192.168.0.1
4982
4983AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
4984AT_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])
4985
4986# Create a localnet port.
4987AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
4988AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
4989AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
4990AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
4991
4992
4993# Wait for packet to be received.
4994OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
4995trim_zeros() {
4996 sed 's/\(00\)\{1,\}$//'
4997}
4998$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
4999expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5000echo $expected > expout
5001AT_CHECK([sort packets], [0], [expout])
5002cat packets
5003
5004OVN_CLEANUP([hv1])
5005
5006AT_CLEANUP
6e31816f
CSV
5007
5008AT_SETUP([ovn -- delete mac bindings])
5009AT_KEYWORDS([ovn])
5010ovn_start
5011net_add n1
5012sim_add hv1
5013as hv1
5014ovs-vsctl -- add-br br-phys
5015ovn_attach n1 br-phys 192.168.0.1
5016# Create logical switch ls0
5017ovn-nbctl ls-add ls0
5018# Create ports lp0, lp1 in ls0
5019ovn-nbctl lsp-add ls0 lp0
5020ovn-nbctl lsp-add ls0 lp1
5021ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5022ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5023dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5024ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5025ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5026ovn-sbctl find MAC_Binding
5027#Delete port lp0
5028ovn-nbctl lsp-del lp0
5029ovn-sbctl find MAC_Binding
5030AT_CHECK([ovn-sbctl find MAC_Binding logical_port=lp0], [0], [])
5031#Delete ls0. This will verify that the mac_bindings are cleaned up when a
5032#datapath is deleted without explicitly removing the the logical ports
5033ovn-nbctl ls-del ls0
5034ovn-sbctl find MAC_Binding
5035AT_CHECK([ovn-sbctl find MAC_Binding], [0], [])
5036
5037OVN_CLEANUP([hv1])
5038
5039AT_CLEANUP
926c34fd
RM
5040
5041AT_SETUP([ovn -- conntrack zone allocation])
5042AT_KEYWORDS([ovnconntrack])
5043AT_SKIP_IF([test $HAVE_PYTHON = no])
5044ovn_start
5045
5046# Logical network:
5047# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5048# connected to a router R1.
5049# foo has foo1 to act as a client.
5050# bar has bar1, bar2, bar3 to act as servers.
5051
5052net_add n1
5053
5054sim_add hv1
5055as hv1
5056ovs-vsctl add-br br-phys
5057ovn_attach n1 br-phys 192.168.0.1
5058for i in foo1 bar1 bar2 bar3; do
5059 ovs-vsctl -- add-port br-int $i -- \
5060 set interface $i external-ids:iface-id=$i \
5061 options:tx_pcap=hv1/$i-tx.pcap \
5062 options:rxq_pcap=hv1/$i-rx.pcap
5063done
5064
5065ovn-nbctl create Logical_Router name=R1
5066ovn-nbctl ls-add foo
5067ovn-nbctl ls-add bar
5068
5069# Connect foo to R1
5070ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5071ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5072 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5073
5074# Connect bar to R1
5075ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5076ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5077 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5078
5079# Create logical port foo1 in foo
5080ovn-nbctl lsp-add foo foo1 \
5081-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5082
5083# Create logical port bar1, bar2 and bar3 in bar
5084for i in `seq 1 3`; do
5085 ip=`expr $i + 1`
5086 ovn-nbctl lsp-add bar bar$i \
5087 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5088done
5089
5090OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5091
5092OVN_CLEANUP([hv1])
5093
5094AT_CLEANUP
b511690b
GS
5095
5096AT_SETUP([ovn -- tag allocation])
5097AT_KEYWORDS([ovntags])
5098ovn_start
5099
5100AT_CHECK([ovn-nbctl ls-add ls0])
5101AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5102AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5103AT_CHECK([ovn-nbctl ls-add ls1])
5104
5105dnl When a tag is provided, no allocation is done
5106AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5107AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5108])
5109dnl The same 'tag' gets created in southbound database.
5110AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5111logical_port="c0"], [0], [3
5112])
5113
5114dnl Allocate tags and see it getting created in both NB and SB
5115AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5116AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5117])
5118AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5119logical_port="c1"], [0], [1
5120])
5121
5122AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5123AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5124])
5125AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5126logical_port="c2"], [0], [2
5127])
5128AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5129AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5130])
5131AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5132logical_port="c3"], [0], [4
5133])
5134
5135dnl A different parent.
5136AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5137AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5138])
5139AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5140logical_port="c4"], [0], [1
5141])
5142
5143AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5144AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5145])
5146AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5147logical_port="c5"], [0], [2
5148])
5149
5150dnl Delete a logical port and create a new one.
5151AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5152AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5153AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5154])
5155AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5156logical_port="c6"], [0], [1
5157])
5158
5159dnl Restart northd to see that the same allocation remains.
5160as northd
5161OVS_APP_EXIT_AND_WAIT([ovn-northd])
5162start_daemon ovn-northd \
5163 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5164 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5165
5166dnl Create a switch to make sure that ovn-northd has run through the main loop.
5167AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5168AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5169])
5170AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5171])
5172AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5173])
5174AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5175])
5176AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5177])
5178AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5179])
5180
5181dnl Create a switch port with a tag that has already been allocated.
5182dnl It should go through fine with a duplicate tag.
5183AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5184AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5185])
5186AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5187logical_port="c7"], [0], [2
5188])
5189AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5190])
5191
5192AT_CHECK([ovn-nbctl ls-add ls2])
5193dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5194dnl gets copied to 'tag'
5195AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5196AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5197])
5198dnl The same 'tag' gets created in southbound database.
5199AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5200logical_port="local0"], [0], [25
5201])
5202dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5203AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5204AT_CHECK([ovn-nbctl lsp-get-tag local1])
5205dnl change the tag_request.
5206AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5207AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5208])
5209
5210AT_CLEANUP
57afd0c0
RR
5211
5212AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5213AT_KEYWORDS([ovn])
5214ovn_start
5215ovn-nbctl ls-add lsw0
5216net_add n1
5217for i in 1 2; do
5218 sim_add hv$i
5219 as hv$i
5220 ovs-vsctl add-br br-phys
5221 ovn_attach n1 br-phys 192.168.0.$i
5222 ovs-vsctl add-br br-eth0
5223 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5224done
5225
5226# Create a localnet port.
5227AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5228AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5229AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5230AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5231
5232
5233# Create 3 vifs.
5234AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5235AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5236AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5237AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5238AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5239AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5240AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5241AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5242AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5243
5244# Bind the localvif1 to hv1.
5245as hv1
5246AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5247
5248# On hv1, check that there are no flows outputting bcast to tunnel
5249OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5250
5251# On hv2, check that there is 1 flow outputting bcast to tunnel to hv1.
5252as hv2
5253OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 1])
5254
5255# Now bind vif2 on hv2.
5256AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5257
5258# At this point, the broadcast flow on vif2 should be deleted.
5259# because, there is now a localnet vif bound (table=32 programming logic)
5260OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5261
5262# Verify that the local net patch port exists on hv2.
5263OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5264
5265# Now bind vif3 on hv2.
5266AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5267
5268# Verify that the local net patch port still exists on hv2
5269OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5270
5271# Delete localvif2
5272AT_CHECK([ovn-nbctl lsp-del localvif2])
5273
5274# Verify that the local net patch port still exists on hv2,
5275# because, localvif3 is still bound.
5276OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5277
5278
5279OVN_CLEANUP([hv1],[hv2])
5280AT_CLEANUP