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