]> git.proxmox.com Git - ovs.git/blob - tests/ovn.at
tests: Convert ovsdb-monitor-sort utility from Perl to Python.
[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 -- is_chassis_resident simplification])
457 simplify() {
458 echo "$1" | ovstest test-ovn simplify-expr
459 }
460 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
461 ])
462 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
463 ])
464 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
465 ])
466 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
467 ])
468 AT_CLEANUP
469
470 AT_SETUP([ovn -- 4-term numeric expression normalization])
471 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
472 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
473 ])
474 AT_CLEANUP
475
476 AT_SETUP([ovn -- 4-term string expression normalization])
477 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
478 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
479 ])
480 AT_CLEANUP
481
482 AT_SETUP([ovn -- 4-term mixed expression normalization])
483 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
484 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
485 ])
486 AT_CLEANUP
487
488 AT_SETUP([ovn -- 5-term numeric expression normalization])
489 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
490 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
491 ])
492 AT_CLEANUP
493
494 AT_SETUP([ovn -- 5-term string expression normalization])
495 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
496 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
497 ])
498 AT_CLEANUP
499
500 AT_SETUP([ovn -- 5-term mixed expression normalization])
501 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
503 ])
504 AT_CLEANUP
505
506 AT_SETUP([ovn -- 4-term numeric expressions to flows])
507 AT_KEYWORDS([expression])
508 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
509 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
510 ])
511 AT_CLEANUP
512
513 AT_SETUP([ovn -- 4-term string expressions to flows])
514 AT_KEYWORDS([expression])
515 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
516 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
517 ])
518 AT_CLEANUP
519
520 AT_SETUP([ovn -- 4-term mixed expressions to flows])
521 AT_KEYWORDS([expression])
522 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
523 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
524 ])
525 AT_CLEANUP
526
527 AT_SETUP([ovn -- 3-term numeric expressions to flows])
528 AT_KEYWORDS([expression])
529 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
530 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
531 ])
532 AT_CLEANUP
533
534 AT_SETUP([ovn -- converting expressions to flows -- string fields])
535 AT_KEYWORDS([expression])
536 expr_to_flow () {
537 echo "$1" | ovstest test-ovn expr-to-flows | sort
538 }
539 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
540 ])
541 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
542 ])
543 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
544 ])
545 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
546 ip,reg14=0x5
547 ipv6,reg14=0x5
548 ])
549 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
550 ip,reg14=0x6
551 ipv6,reg14=0x6
552 ])
553 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
554 ])
555 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
556 [reg14=0x5
557 reg14=0x6
558 reg14=0xfffe
559 ])
560 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
561 ip,reg14=0x5
562 ip,reg14=0x6
563 ipv6,reg14=0x5
564 ipv6,reg14=0x6
565 ])
566 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
567 (no flows)
568 ])
569 AT_CLEANUP
570
571 AT_SETUP([ovn -- converting expressions to flows -- address sets])
572 AT_KEYWORDS([expression])
573 expr_to_flow () {
574 echo "$1" | ovstest test-ovn expr-to-flows | sort
575 }
576 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
577 ip,nw_src=10.0.0.1
578 ip,nw_src=10.0.0.2
579 ip,nw_src=10.0.0.3
580 ])
581 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
582 ip,nw_src=10.0.0.1
583 ip,nw_src=10.0.0.2
584 ip,nw_src=10.0.0.3
585 ])
586 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
587 ip,nw_src=1.2.3.4
588 ip,nw_src=10.0.0.1
589 ip,nw_src=10.0.0.2
590 ip,nw_src=10.0.0.3
591 ])
592 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
593 ip,nw_src=1.2.0.0/20
594 ip,nw_src=10.0.0.1
595 ip,nw_src=10.0.0.2
596 ip,nw_src=10.0.0.3
597 ip,nw_src=5.5.5.0/24
598 ])
599 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
600 ipv6,ipv6_src=::1
601 ipv6,ipv6_src=::2
602 ipv6,ipv6_src=::3
603 ])
604 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
605 ipv6,ipv6_src=::1
606 ipv6,ipv6_src=::2
607 ipv6,ipv6_src=::3
608 ipv6,ipv6_src=::4
609 ])
610 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
611 dl_src=00:00:00:00:00:01
612 dl_src=00:00:00:00:00:02
613 dl_src=00:00:00:00:00:03
614 ])
615 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
616 dl_src=00:00:00:00:00:01
617 dl_src=00:00:00:00:00:02
618 dl_src=00:00:00:00:00:03
619 ])
620 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
621 dl_src=00:00:00:00:00:01
622 dl_src=00:00:00:00:00:02
623 dl_src=00:00:00:00:00:03
624 dl_src=ba:be:be:ef:de:ad
625 ])
626 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
627 (no flows)
628 ])
629 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
630 ip,nw_src=1.2.3.4
631 ])
632 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
633 ip,nw_src=1.2.3.4
634 ])
635 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
636
637 ])
638 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
639 ip,nw_src=0.0.0.0/1.0.0.0
640 ip,nw_src=128.0.0.0/1
641 ip,nw_src=16.0.0.0/16.0.0.0
642 ip,nw_src=2.0.0.0/2.0.0.0
643 ip,nw_src=32.0.0.0/32.0.0.0
644 ip,nw_src=4.0.0.0/4.0.0.0
645 ip,nw_src=64.0.0.0/64.0.0.0
646 ip,nw_src=8.0.0.0/8.0.0.0
647 ])
648 AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
649 ip,nw_src=0.0.0.0/1.0.0.0
650 ip,nw_src=128.0.0.0/1
651 ip,nw_src=16.0.0.0/16.0.0.0
652 ip,nw_src=2.0.0.0/2.0.0.0
653 ip,nw_src=32.0.0.0/32.0.0.0
654 ip,nw_src=4.0.0.0/4.0.0.0
655 ip,nw_src=64.0.0.0/64.0.0.0
656 ip,nw_src=8.0.0.0/8.0.0.0
657 ])
658 AT_CLEANUP
659
660 AT_SETUP([ovn -- action parsing])
661 dnl Unindented text is input (a set of OVN logical actions).
662 dnl Indented text is expected output.
663 AT_DATA([test-cases.txt],
664 [[# drop
665 drop;
666 encodes as drop
667 drop; next;
668 Syntax error at `next' expecting end of input.
669 next; drop;
670 Syntax error at `drop' expecting action.
671
672 # output
673 output;
674 encodes as resubmit(,64)
675
676 # next
677 next;
678 encodes as resubmit(,19)
679 next(11);
680 formats as next;
681 encodes as resubmit(,19)
682 next(0);
683 encodes as resubmit(,8)
684 next(23);
685 encodes as resubmit(,31)
686
687 next();
688 Syntax error at `)' expecting "pipeline" or "table".
689 next(10;
690 Syntax error at `;' expecting `)'.
691 next(24);
692 "next" action cannot advance beyond table 23.
693
694 next(table=11);
695 formats as next;
696 encodes as resubmit(,19)
697 next(pipeline=ingress);
698 formats as next;
699 encodes as resubmit(,19)
700 next(table=11, pipeline=ingress);
701 formats as next;
702 encodes as resubmit(,19)
703 next(pipeline=ingress, table=11);
704 formats as next;
705 encodes as resubmit(,19)
706
707 next(pipeline=egress);
708 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
709
710 next(table=10);
711 formats as next(10);
712 encodes as resubmit(,18)
713
714 # Loading a constant value.
715 tcp.dst=80;
716 formats as tcp.dst = 80;
717 encodes as set_field:80->tcp_dst
718 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
719 eth.dst[40] = 1;
720 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
721 vlan.pcp = 2;
722 encodes as set_field:0x4000/0xe000->vlan_tci
723 has prereqs vlan.tci[12]
724 vlan.tci[13..15] = 2;
725 encodes as set_field:0x4000/0xe000->vlan_tci
726 inport = "";
727 encodes as set_field:0->reg14
728 ip.ttl=4;
729 formats as ip.ttl = 4;
730 encodes as set_field:4->nw_ttl
731 has prereqs eth.type == 0x800 || eth.type == 0x86dd
732 outport="eth0"; next; outport="LOCAL"; next;
733 formats as outport = "eth0"; next; outport = "LOCAL"; next;
734 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
735
736 inport[1] = 1;
737 Cannot select subfield of string field inport.
738 ip.proto[1] = 1;
739 Cannot select subfield of nominal field ip.proto.
740 eth.dst[40] == 1;
741 Syntax error at `==' expecting `=' or `<->'.
742 ip = 1;
743 Predicate symbol ip used where lvalue required.
744 ip.proto = 6;
745 Field ip.proto is not modifiable.
746 inport = {"a", "b"};
747 Syntax error at `{' expecting constant.
748 inport = {};
749 Syntax error at `{' expecting constant.
750 bad_prereq = 123;
751 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
752 self_recurse = 123;
753 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'.
754 vlan.present = 0;
755 Predicate symbol vlan.present used where lvalue required.
756
757 # Moving one field into another.
758 reg0=reg1;
759 formats as reg0 = reg1;
760 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
761 vlan.pcp = reg0[0..2];
762 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
763 has prereqs vlan.tci[12]
764 reg0[10] = vlan.pcp[1];
765 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
766 has prereqs vlan.tci[12]
767 outport = inport;
768 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
769
770 reg0[0] = vlan.present;
771 Predicate symbol vlan.present used where lvalue required.
772 reg0 = reg1[0..10];
773 Can't assign 11-bit value to 32-bit destination.
774 inport = reg0;
775 Can't assign integer field (reg0) to string field (inport).
776 inport = big_string;
777 String fields inport and big_string are incompatible for assignment.
778 ip.proto = reg0[0..7];
779 Field ip.proto is not modifiable.
780
781 # Exchanging fields.
782 reg0 <-> reg1;
783 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]
784 vlan.pcp <-> reg0[0..2];
785 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]
786 has prereqs vlan.tci[12]
787 reg0[10] <-> vlan.pcp[1];
788 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
789 has prereqs vlan.tci[12]
790 outport <-> inport;
791 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
792
793 reg0[0] <-> vlan.present;
794 Predicate symbol vlan.present used where lvalue required.
795 reg0 <-> reg1[0..10];
796 Can't exchange 32-bit field with 11-bit field.
797 inport <-> reg0;
798 Can't exchange string field (inport) with integer field (reg0).
799 inport <-> big_string;
800 String fields inport and big_string are incompatible for exchange.
801 ip.proto <-> reg0[0..7];
802 Field ip.proto is not modifiable.
803 reg0[0..7] <-> ip.proto;
804 Field ip.proto is not modifiable.
805
806 # TTL decrement.
807 ip.ttl--;
808 encodes as dec_ttl
809 has prereqs ip
810 ip.ttl
811 Syntax error at end of input expecting `--'.
812
813 # load balancing.
814 ct_lb;
815 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
816 has prereqs ip
817 ct_lb();
818 formats as ct_lb;
819 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
820 has prereqs ip
821 ct_lb(192.168.1.2:80, 192.168.1.3:80);
822 encodes as group:1
823 has prereqs ip
824 ct_lb(192.168.1.2, 192.168.1.3, );
825 formats as ct_lb(192.168.1.2, 192.168.1.3);
826 encodes as group:2
827 has prereqs ip
828 ct_lb(fd0f::2, fd0f::3, );
829 formats as ct_lb(fd0f::2, fd0f::3);
830 encodes as group:3
831 has prereqs ip
832
833 ct_lb(192.168.1.2:);
834 Syntax error at `)' expecting port number.
835 ct_lb(192.168.1.2:123456);
836 Syntax error at `123456' expecting port number.
837 ct_lb(foo);
838 Syntax error at `foo' expecting IP address.
839 ct_lb([192.168.1.2]);
840 Syntax error at `192.168.1.2' expecting IPv6 address.
841
842 # ct_next
843 ct_next;
844 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
845 has prereqs ip
846
847 # ct_commit
848 ct_commit;
849 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
850 has prereqs ip
851 ct_commit();
852 formats as ct_commit;
853 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
854 has prereqs ip
855 ct_commit(ct_mark=1);
856 formats as ct_commit(ct_mark=0x1);
857 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
858 has prereqs ip
859 ct_commit(ct_mark=1/1);
860 formats as ct_commit(ct_mark=0x1/0x1);
861 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
862 has prereqs ip
863 ct_commit(ct_label=1);
864 formats as ct_commit(ct_label=0x1);
865 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
866 has prereqs ip
867 ct_commit(ct_label=1/1);
868 formats as ct_commit(ct_label=0x1/0x1);
869 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
870 has prereqs ip
871 ct_commit(ct_mark=1, ct_label=2);
872 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
873 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
874 has prereqs ip
875
876 ct_commit(ct_label=0x01020304050607080910111213141516);
877 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
878 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
879 has prereqs ip
880 ct_commit(ct_label=0x181716151413121110090807060504030201);
881 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
882 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
883 has prereqs ip
884 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
885 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
886 has prereqs ip
887 ct_commit(ct_label=18446744073709551615);
888 formats as ct_commit(ct_label=0xffffffffffffffff);
889 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
890 has prereqs ip
891 ct_commit(ct_label=18446744073709551616);
892 Decimal constants must be less than 2**64.
893
894 # ct_dnat
895 ct_dnat;
896 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
897 has prereqs ip
898 ct_dnat(192.168.1.2);
899 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
900 has prereqs ip
901
902 ct_dnat(192.168.1.2, 192.168.1.3);
903 Syntax error at `,' expecting `)'.
904 ct_dnat(foo);
905 Syntax error at `foo' expecting IPv4 address.
906 ct_dnat(foo, bar);
907 Syntax error at `foo' expecting IPv4 address.
908 ct_dnat();
909 Syntax error at `)' expecting IPv4 address.
910
911 # ct_snat
912 ct_snat;
913 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
914 has prereqs ip
915 ct_snat(192.168.1.2);
916 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
917 has prereqs ip
918
919 ct_snat(192.168.1.2, 192.168.1.3);
920 Syntax error at `,' expecting `)'.
921 ct_snat(foo);
922 Syntax error at `foo' expecting IPv4 address.
923 ct_snat(foo, bar);
924 Syntax error at `foo' expecting IPv4 address.
925 ct_snat();
926 Syntax error at `)' expecting IPv4 address.
927
928 # ct_clear
929 ct_clear;
930 encodes as ct_clear
931
932 # clone
933 clone { ip4.dst = 255.255.255.255; output; }; next;
934 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
935 has prereqs eth.type == 0x800
936
937 # arp
938 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
939 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
940 has prereqs ip4
941 arp { };
942 formats as arp { drop; };
943 encodes as controller(userdata=00.00.00.00.00.00.00.00)
944 has prereqs ip4
945
946 # get_arp
947 get_arp(outport, ip4.dst);
948 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[]
949 has prereqs eth.type == 0x800
950 get_arp(inport, reg0);
951 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[]
952
953 get_arp;
954 Syntax error at `;' expecting `('.
955 get_arp();
956 Syntax error at `)' expecting field name.
957 get_arp(inport);
958 Syntax error at `)' expecting `,'.
959 get_arp(inport ip4.dst);
960 Syntax error at `ip4.dst' expecting `,'.
961 get_arp(inport, ip4.dst;
962 Syntax error at `;' expecting `)'.
963 get_arp(inport, eth.dst);
964 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
965 get_arp(inport, outport);
966 Cannot use string field outport where numeric field is required.
967 get_arp(reg0, ip4.dst);
968 Cannot use numeric field reg0 where string field is required.
969
970 # put_arp
971 put_arp(inport, arp.spa, arp.sha);
972 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[]
973 has prereqs eth.type == 0x806 && eth.type == 0x806
974
975 # put_dhcp_opts
976 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
977 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)
978 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");
979 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");
980 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)
981 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);
982 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);
983 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)
984
985 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
986 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
987 reg1[0] = put_dhcp_opts();
988 put_dhcp_opts requires offerip to be specified.
989 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
990 Syntax error at `x' expecting DHCPv4 option name.
991 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
992 put_dhcp_opts requires offerip to be specified.
993 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
994 Syntax error at `"hi"'.
995 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
996 Syntax error at `xyzzy' expecting DHCPv4 option name.
997 reg1[0] = put_dhcp_opts(offerip="xyzzy");
998 DHCPv4 option offerip requires numeric value.
999 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1000 DHCPv4 option domain requires string value.
1001
1002 # nd_ns
1003 nd_ns { nd.target = xxreg0; output; };
1004 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1005 has prereqs ip6
1006
1007 nd_ns { };
1008 formats as nd_ns { drop; };
1009 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1010 has prereqs ip6
1011
1012 # nd_na
1013 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; };
1014 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1015 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)
1016 has prereqs nd_ns
1017
1018 # get_nd
1019 get_nd(outport, ip6.dst);
1020 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[]
1021 has prereqs eth.type == 0x86dd
1022 get_nd(inport, xxreg0);
1023 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[]
1024 get_nd;
1025 Syntax error at `;' expecting `('.
1026 get_nd();
1027 Syntax error at `)' expecting field name.
1028 get_nd(inport);
1029 Syntax error at `)' expecting `,'.
1030 get_nd(inport ip6.dst);
1031 Syntax error at `ip6.dst' expecting `,'.
1032 get_nd(inport, ip6.dst;
1033 Syntax error at `;' expecting `)'.
1034 get_nd(inport, eth.dst);
1035 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1036 get_nd(inport, outport);
1037 Cannot use string field outport where numeric field is required.
1038 get_nd(xxreg0, ip6.dst);
1039 Cannot use numeric field xxreg0 where string field is required.
1040
1041 # put_nd
1042 put_nd(inport, nd.target, nd.sll);
1043 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[]
1044 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)
1045
1046 # put_dhcpv6_opts
1047 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1048 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)
1049 reg1[0] = put_dhcpv6_opts();
1050 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1051 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1052 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1053 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)
1054 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1055 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1056 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)
1057 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1058 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)
1059 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1060 Syntax error at `x' expecting DHCPv6 option name.
1061 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1062 Syntax error at `"hi"'.
1063 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1064 Syntax error at `xyzzy' expecting DHCPv6 option name.
1065 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1066 DHCPv6 option ia_addr requires numeric value.
1067 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1068 DHCPv6 option domain_search requires string value.
1069
1070 # set_queue
1071 set_queue(0);
1072 encodes as set_queue:0
1073 set_queue(61440);
1074 encodes as set_queue:61440
1075 set_queue(65535);
1076 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1077
1078 # dns_lookup
1079 reg1[0] = dns_lookup();
1080 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1081 has prereqs udp
1082 reg1[0] = dns_lookup("foo");
1083 dns_lookup doesn't take any parameters
1084
1085 # put_nd_ra_opts
1086 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1087 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
1088 has prereqs ip6
1089 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1090 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
1091 has prereqs ip6
1092 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1093 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
1094 has prereqs ip6
1095 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1096 slla option not present
1097 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1098 prefix option can't be set when address mode is dhcpv6_stateful.
1099 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1100 prefix option can't be set when address mode is dhcpv6_stateful.
1101 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1102 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1103 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1104 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1105 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1106 Syntax error at `dhcpv6_stateless' expecting constant.
1107 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1108 Invalid value for "prefix" option
1109 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1110 Invalid value for "addr_mode" option
1111 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1112 IPv6 ND RA option mtu requires numeric value.
1113 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1114 Invalid value for "mtu" option
1115
1116 # Contradictionary prerequisites (allowed but not useful):
1117 ip4.src = ip6.src[0..31];
1118 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1119 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1120 ip4.src <-> ip6.src[0..31];
1121 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[]
1122 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1123
1124 # Miscellaneous negative tests.
1125 ;
1126 Syntax error at `;'.
1127 xyzzy;
1128 Syntax error at `xyzzy' expecting action.
1129 next; 123;
1130 Syntax error at `123'.
1131 next; xyzzy;
1132 Syntax error at `xyzzy' expecting action.
1133 next
1134 Syntax error at end of input expecting `;'.
1135 ]])
1136 sed '/^[[ ]]/d' test-cases.txt > input.txt
1137 cp test-cases.txt expout
1138 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1139 AT_CLEANUP
1140
1141 AT_BANNER([OVN end-to-end tests])
1142
1143 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1144 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1145 AT_KEYWORDS([ovnarp])
1146 AT_SKIP_IF([test $HAVE_PYTHON = no])
1147 ovn_start
1148
1149 # Create hypervisors hv[123].
1150 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1151 # Add all of the vifs to a single logical switch lsw0.
1152 # Turn on port security on all the vifs except vif[123]1.
1153 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1154 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1155 ovn-nbctl ls-add lsw0
1156 net_add n1
1157 for i in 1 2 3; do
1158 sim_add hv$i
1159 as hv$i
1160 ovs-vsctl add-br br-phys
1161 ovn_attach n1 br-phys 192.168.0.$i
1162
1163 for j in 1 2 3; do
1164 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
1165 ovn-nbctl lsp-add lsw0 lp$i$j
1166 if test $j = 1; then
1167 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1168 else
1169 if test $j = 3; then
1170 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1171 else
1172 ip_addrs="192.168.0.$i$j"
1173 fi
1174 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1175 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1176 fi
1177 done
1178 done
1179 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1180 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1181 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1182 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\"
1183 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1184
1185 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1186 # packets for ARP resolution (native tunneling doesn't queue packets
1187 # for ARP resolution).
1188 ovn_populate_arp
1189
1190 # Allow some time for ovn-northd and ovn-controller to catch up.
1191 # XXX This should be more systematic.
1192 sleep 1
1193
1194 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1195 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1196 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1197 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1198
1199 # Given the name of a logical port, prints the name of the hypervisor
1200 # on which it is located.
1201 vif_to_hv() {
1202 echo hv${1%?}
1203 }
1204
1205 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1206 #
1207 # This shell function causes a packet to be received on INPORT. The packet's
1208 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1209 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1210 # more) list the VIFs on which the packet should be received. INPORT and the
1211 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1212 for i in 1 2 3; do
1213 for j in 1 2 3; do
1214 : > $i$j.expected
1215 done
1216 done
1217 test_packet() {
1218 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1219 hv=`vif_to_hv $inport`
1220 vif=vif$inport
1221 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1222 for outport; do
1223 echo $packet >> $outport.expected
1224 done
1225 }
1226
1227 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1228 #
1229 # Causes a packet to be received on INPORT. The packet is an ARP
1230 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1231 # it should be the hardware address of the target to expect to receive in an
1232 # ARP reply; otherwise no reply is expected.
1233 #
1234 # INPORT is an logical switch port number, e.g. 11 for vif11.
1235 # SHA and REPLY_HA are each 12 hex digits.
1236 # SPA and TPA are each 8 hex digits.
1237 test_arp() {
1238 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1239 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1240 hv=`vif_to_hv $inport`
1241 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1242
1243 if test X$reply_ha = X; then
1244 # Expect to receive the broadcast ARP on the other logical switch ports
1245 # if no reply is expected.
1246 local i j
1247 for i in 1 2 3; do
1248 for j in 1 2 3; do
1249 if test $i$j != $inport; then
1250 echo $request >> $i$j.expected
1251 fi
1252 done
1253 done
1254 else
1255 # Expect to receive the reply, if any.
1256 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1257 echo $reply >> $inport.expected
1258 fi
1259 }
1260
1261 ip_to_hex() {
1262 printf "%02x%02x%02x%02x" "$@"
1263 }
1264
1265 # Send packets between all pairs of source and destination ports:
1266 #
1267 # 1. Unicast packets are delivered to exactly one logical switch port
1268 # (except that packets destined to their input ports are dropped).
1269 #
1270 # 2. Broadcast and multicast are delivered to all logical switch ports
1271 # except the input port.
1272 #
1273 # 3. When port security is turned on, the switch drops packets from the wrong
1274 # MAC address.
1275 #
1276 # 4. The switch drops all packets with a VLAN tag.
1277 #
1278 # 5. The switch drops all packets with a multicast source address. (This only
1279 # affects behavior when port security is turned off, since otherwise port
1280 # security would drop the packet anyway.)
1281 #
1282 # 6. The switch delivers packets with an unknown destination to logical
1283 # switch ports with "unknown" among their MAC addresses (and port
1284 # security disabled).
1285 #
1286 # 7. The switch drops unicast packets that violate an ACL.
1287 #
1288 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1289 #
1290 # 9. OVN generates responses to ARP requests for known IPs, except for
1291 # requests from a port for the port's own IP.
1292 #
1293 # 10. No response to ARP requests for unknown IPs.
1294
1295 for is in 1 2 3; do
1296 for js in 1 2 3; do
1297 s=$is$js
1298 bcast=
1299 unknown=
1300 bacl2=
1301 bacl3=
1302 for id in 1 2 3; do
1303 for jd in 1 2 3; do
1304 d=$id$jd
1305
1306 if test $d != $s; then unicast=$d; else unicast=; fi
1307 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1308
1309 if test $d != $s && test $js = 1; then
1310 impersonate=$d
1311 else
1312 impersonate=
1313 fi
1314 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1315
1316 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1317 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1318 if test $d = $s || (test $js = 1 && test $d = 33); then
1319 # Source of 11, 21, or 31 and dest of 33 should be dropped
1320 # due to the 4th ACL that uses address_set(set1).
1321 acl4=
1322 else
1323 acl4=$d
1324 fi
1325 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1326 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1327 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1328 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1329
1330 test_packet $s f000000000$d f00000000055 810000091234 #4
1331 test_packet $s f000000000$d 0100000000$s $s$d #5
1332
1333 if test $d != $s && test $jd = 1; then
1334 unknown="$unknown $d"
1335 fi
1336 bcast="$bcast $unicast"
1337 bacl2="$bacl2 $acl2"
1338 bacl3="$bacl3 $acl3"
1339
1340 sip=`ip_to_hex 192 168 0 $i$j`
1341 tip=`ip_to_hex 192 168 0 $id$jd`
1342 tip_unknown=`ip_to_hex 11 11 11 11`
1343 if test $d != $s; then
1344 reply_ha=f000000000$d
1345 else
1346 reply_ha=
1347 fi
1348 test_arp $s f000000000$s $sip $tip $reply_ha #9
1349 test_arp $s f000000000$s $sip $tip_unknown #10
1350
1351 if test $jd = 3; then
1352 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1353 tip=`ip_to_hex 192 169 0 $id$jd`
1354 test_arp $s f000000000$s $sip $tip $reply_ha #9
1355 fi
1356 done
1357 done
1358
1359 # Broadcast and multicast.
1360 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1361 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1362 if test $js = 1; then
1363 bcast_impersonate=$bcast
1364 else
1365 bcast_impersonate=
1366 fi
1367 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1368
1369 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1370
1371 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1372 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1373 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1374 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1375 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1376 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1377 done
1378 done
1379
1380 # set address for lp13 with invalid characters.
1381 # lp13 should be configured with only 192.168.0.13.
1382 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1383
1384 # Allow some time for ovn-northd and ovn-controller to catch up.
1385 # XXX This should be more systematic.
1386 sleep 1
1387
1388 sip=`ip_to_hex 192 168 0 11`
1389 tip=`ip_to_hex 192 168 0 13`
1390 test_arp 11 f00000000011 $sip $tip f00000000013
1391
1392 tip=`ip_to_hex 192 169 0 13`
1393 #arp request for 192.169.0.13 should be flooded
1394 test_arp 11 f00000000011 $sip $tip
1395
1396 # dump information and flows with counters
1397 ovn-sbctl dump-flows -- list multicast_group
1398
1399 echo "------ hv1 dump ------"
1400 as hv1 ovs-vsctl show
1401 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1402
1403 echo "------ hv2 dump ------"
1404 as hv2 ovs-vsctl show
1405 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1406
1407 echo "------ hv3 dump ------"
1408 as hv3 ovs-vsctl show
1409 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1410
1411 # Now check the packets actually received against the ones expected.
1412 for i in 1 2 3; do
1413 for j in 1 2 3; do
1414 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1415 done
1416 done
1417
1418 OVN_CLEANUP([hv1],[hv2],[hv3])
1419
1420 AT_CLEANUP
1421
1422 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1423 AT_SKIP_IF([test $HAVE_PYTHON = no])
1424 ovn_start
1425
1426 # Create a logical switch and some logical ports.
1427 # Turn on port security on all lports except ls1.
1428 # Make ls1 a destination for unknown MACs.
1429 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1430 ovn-nbctl ls-add lsw0
1431 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1432 for i in 1 2 3; do
1433 ovn-nbctl lsp-add lsw0 lp$i
1434 done
1435 ovn-nbctl --wait=sb sync
1436 for i in 1 2 3; do
1437 ovn-sbctl lsp-bind lp$i hv0
1438 if test $i = 1; then
1439 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1440 else
1441 if test $i = 3; then
1442 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1443 else
1444 ip_addrs="192.168.0.$i"
1445 fi
1446 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1447 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
1448 fi
1449 done
1450 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1451 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1452 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1453 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1454 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1455
1456 ovn-nbctl --wait=sb sync
1457 on_exit 'kill `cat ovn-trace.pid`'
1458 ovn-trace --detach --pidfile --no-chdir
1459
1460 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1461 #
1462 # This shell function causes a packet to be received on INPORT. The packet's
1463 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1464 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1465 # more) list the VIFs on which the packet should be received. INPORT and the
1466 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1467 test_packet() {
1468 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1469 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1470 while :; do
1471 case $1 in # (
1472 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1473 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1474 *) break ;;
1475 esac
1476 done
1477 for outport; do
1478 echo "output(\"lp$outport\");"
1479 done > expout
1480
1481 AT_CAPTURE_FILE([trace])
1482 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1483 }
1484
1485 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1486 #
1487 # Causes a packet to be received on INPORT. The packet is an ARP
1488 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1489 # it should be the hardware address of the target to expect to receive in an
1490 # ARP reply; otherwise no reply is expected.
1491 #
1492 # INPORT is an logical switch port number, e.g. 11 for vif11.
1493 # SHA and REPLY_HA are each 12 hex digits.
1494 # SPA and TPA are each 8 hex digits.
1495 test_arp() {
1496 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1497
1498 local request="inport == \"lp$inport\"
1499 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1500 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1501 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1502
1503 if test -z "$reply_ha"; then
1504 reply=
1505 local i
1506 for i in 1 2 3; do
1507 if test $i != $inport; then
1508 reply="${reply}output(\"lp$i\");
1509 "
1510 fi
1511 done
1512 else
1513 reply="\
1514 eth.dst = $sha;
1515 eth.src = $reply_ha;
1516 arp.op = 2;
1517 arp.tha = $sha;
1518 arp.sha = $reply_ha;
1519 arp.tpa = $spa;
1520 arp.spa = $tpa;
1521 output(\"lp$inport\");
1522 "
1523 fi
1524
1525 AT_CAPTURE_FILE([trace])
1526 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1527 }
1528
1529 # Send packets between all pairs of source and destination ports:
1530 #
1531 # 1. Unicast packets are delivered to exactly one logical switch port
1532 # (except that packets destined to their input ports are dropped).
1533 #
1534 # 2. Broadcast and multicast are delivered to all logical switch ports
1535 # except the input port.
1536 #
1537 # 3. When port security is turned on, the switch drops packets from the wrong
1538 # MAC address.
1539 #
1540 # 4. The switch drops all packets with a VLAN tag.
1541 #
1542 # 5. The switch drops all packets with a multicast source address. (This only
1543 # affects behavior when port security is turned off, since otherwise port
1544 # security would drop the packet anyway.)
1545 #
1546 # 6. The switch delivers packets with an unknown destination to logical
1547 # switch ports with "unknown" among their MAC addresses (and port
1548 # security disabled).
1549 #
1550 # 7. The switch drops unicast packets that violate an ACL.
1551 #
1552 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1553 #
1554 # 9. OVN generates responses to ARP requests for known IPs, except for
1555 # requests from a port for the port's own IP.
1556 #
1557 # 10. No response to ARP requests for unknown IPs.
1558
1559 for s in 1 2 3; do
1560 bcast=
1561 unknown=
1562 bacl2=
1563 bacl3=
1564 for d in 1 2 3; do
1565 echo
1566 echo "lp$s -> lp$d"
1567 if test $d != $s; then unicast=$d; else unicast=; fi
1568 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1569
1570 if test $d != $s && test $s = 1; then
1571 impersonate=$d
1572 else
1573 impersonate=
1574 fi
1575 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1576
1577 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1578 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1579 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1580 # Source of 1 or 2 and dest of 3 should be dropped
1581 # due to the 4th ACL that uses address_set(set1).
1582 acl4=
1583 else
1584 acl4=$d
1585 fi
1586
1587 #7, acl1 to acl4:
1588 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1589 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1590 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1591 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1592
1593 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1594 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1595
1596 if test $d != $s && test $d = 1; then
1597 unknown="$unknown $d"
1598 fi
1599 bcast="$bcast $unicast"
1600 bacl2="$bacl2 $acl2"
1601 bacl3="$bacl3 $acl3"
1602
1603 sip=192.168.0.$s
1604 tip=192.168.0.$d
1605 tip_unknown=11.11.11.11
1606 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1607 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1608 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1609
1610 if test $d = 3; then
1611 # lp3 has an additional ip 192.169.0.[123]3.
1612 tip=192.169.0.$d
1613 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1614 fi
1615 done
1616
1617 # Broadcast and multicast.
1618 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1619 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1620 if test $s = 1; then
1621 bcast_impersonate=$bcast
1622 else
1623 bcast_impersonate=
1624 fi
1625 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1626
1627 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1628
1629 #8, acl1 to acl3:
1630 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1631 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1632 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1633
1634 #8, acl1 to acl3:
1635 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1636 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1637 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1638 done
1639
1640 AT_CLEANUP
1641
1642 # 2 hypervisors, 4 logical ports per HV
1643 # 2 locally attached networks (one flat, one vlan tagged over same device)
1644 # 2 ports per HV on each network
1645 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1646 AT_SKIP_IF([test $HAVE_PYTHON = no])
1647 ovn_start
1648
1649 # In this test cases we create 3 switches, all connected to same
1650 # physical network (through br-phys on each HV). Each switch has
1651 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1652 # of VIF port name indicates the hypervisor it is bound to, e.g.
1653 # lp23 means VIF 3 on hv2.
1654 #
1655 # Each switch's VLAN tag and their logical switch ports are:
1656 # - ls1:
1657 # - untagged
1658 # - ports: lp11, lp12, lp21, lp22
1659 #
1660 # - ls2:
1661 # - tagged with VLAN 101
1662 # - ports: lp13, lp14, lp23, lp24
1663 # - ls3:
1664 # - untagged
1665 # - ports: lp15, lp25
1666 #
1667 # Note: a localnet port is created for each switch to connect to
1668 # physical network.
1669
1670 for i in 1 2 3; do
1671 ls_name=ls$i
1672 ovn-nbctl ls-add $ls_name
1673 ln_port_name=ln$i
1674 if test $i -eq 2; then
1675 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1676 else
1677 ovn-nbctl lsp-add $ls_name $ln_port_name
1678 fi
1679 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1680 ovn-nbctl lsp-set-type $ln_port_name localnet
1681 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1682 done
1683
1684 # lsp_to_ls LSP
1685 #
1686 # Prints the name of the logical switch that contains LSP.
1687 lsp_to_ls () {
1688 case $1 in dnl (
1689 lp?[[12]]) echo ls1 ;; dnl (
1690 lp?[[34]]) echo ls2 ;; dnl (
1691 lp?5) echo ls3 ;; dnl (
1692 *) AT_FAIL_IF([:]) ;;
1693 esac
1694 }
1695
1696 net_add n1
1697 for i in 1 2; do
1698 sim_add hv$i
1699 as hv$i
1700 ovs-vsctl add-br br-phys
1701 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1702 ovn_attach n1 br-phys 192.168.0.$i
1703
1704 for j in 1 2 3 4 5; do
1705 ovs-vsctl add-port br-int vif$i$j -- \
1706 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1707 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1708 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1709 ofport-request=$i$j
1710
1711 lsp_name=lp$i$j
1712 ls_name=$(lsp_to_ls $lsp_name)
1713
1714 ovn-nbctl lsp-add $ls_name $lsp_name
1715 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1716 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1717
1718 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1719 done
1720 done
1721 ovn-nbctl --wait=sb sync
1722 ovn-sbctl dump-flows
1723
1724 ovn_populate_arp
1725
1726 # XXX This is now the 3rd copy of these functions in this file ...
1727
1728 # Given the name of a logical port, prints the name of the hypervisor
1729 # on which it is located.
1730 vif_to_hv() {
1731 echo hv${1%?}
1732 }
1733 #
1734 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1735 #
1736 # This shell function causes a packet to be received on INPORT. The packet's
1737 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1738 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1739 # logical switch port numbers, e.g. 11 for vif11.
1740 #
1741 # EOUT is the end-to-end output port, that is, where the packet will end up
1742 # after possibly bouncing through one or more localnet ports. LOUT is the
1743 # logical output port, which might be a localnet port, as seen by ovn-trace
1744 # (which doesn't know what localnet ports are connected to and therefore can't
1745 # figure out the end-to-end answer).
1746 for i in 1 2; do
1747 for j in 1 2 3 4 5; do
1748 : > $i$j.expected
1749 done
1750 done
1751 test_packet() {
1752 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1753 echo "$@"
1754
1755 # First try tracing the packet.
1756 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1757 if test $lout != drop; then
1758 echo "output(\"$lout\");"
1759 fi > expout
1760 AT_CAPTURE_FILE([trace])
1761 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1762
1763 # Then actually send a packet, for an end-to-end test.
1764 local packet=$(echo $dst$src | sed 's/://g')${eth}
1765 hv=`vif_to_hv $inport`
1766 vif=vif$inport
1767 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1768 if test $eout != drop; then
1769 echo $packet >> ${eout#lp}.expected
1770 fi
1771 }
1772
1773 # lp11 and lp21 are on the same network (phys, untagged)
1774 # and on different hypervisors
1775 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1776 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1777
1778 # lp11 and lp12 are on the same network (phys, untagged)
1779 # and on the same hypervisor
1780 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1781 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1782
1783 # lp13 and lp23 are on the same network (phys, VLAN 101)
1784 # and on different hypervisors
1785 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1786 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1787
1788 # lp13 and lp14 are on the same network (phys, VLAN 101)
1789 # and on the same hypervisor
1790 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1791 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1792
1793 # lp11 and lp15 are on the same network (phys, untagged),
1794 # same hypervisor, and on different switches
1795 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1796 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1797
1798 # lp11 and lp25 are on the same network (phys, untagged),
1799 # different hypervisors, and on different switches
1800 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1801 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1802
1803 # Ports that should not be able to communicate
1804 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1805 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1806 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1807 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1808 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1809 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1810 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1811 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
1812
1813 # Dump a bunch of info helpful for debugging if there's a failure.
1814
1815 echo "------ OVN dump ------"
1816 ovn-nbctl show
1817 ovn-sbctl show
1818
1819 echo "------ hv1 dump ------"
1820 as hv1 ovs-vsctl show
1821 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1822
1823 echo "------ hv2 dump ------"
1824 as hv2 ovs-vsctl show
1825 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1826
1827 # Now check the packets actually received against the ones expected.
1828 for i in 1 2; do
1829 for j in 1 2 3 4 5; do
1830 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1831 done
1832 done
1833
1834 OVN_CLEANUP([hv1],[hv2])
1835
1836 AT_CLEANUP
1837
1838 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1839 AT_KEYWORDS([vtep])
1840 AT_SKIP_IF([test $HAVE_PYTHON = no])
1841 ovn_start
1842
1843 # Configure the Northbound database
1844 ovn-nbctl ls-add lsw0
1845
1846 ovn-nbctl lsp-add lsw0 lp1
1847 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1848
1849 ovn-nbctl lsp-add lsw0 lp2
1850 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1851
1852 ovn-nbctl lsp-add lsw0 lp-vtep
1853 ovn-nbctl lsp-set-type lp-vtep vtep
1854 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1855 ovn-nbctl lsp-set-addresses lp-vtep unknown
1856
1857 # lpr, lr and lrp1 are used for the ARP request handling test only.
1858 ovn-nbctl lsp-add lsw0 lpr
1859 ovn-nbctl lr-add lr
1860 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1861 ovn-nbctl set Logical_Switch_Port lpr type=router \
1862 options:router-port=lrp1 \
1863 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1864
1865
1866 net_add n1 # Network to connect hv1, hv2, and vtep
1867 net_add n2 # Network to connect vtep and hv3
1868
1869 # Create hypervisor hv1 connected to n1
1870 sim_add hv1
1871 as hv1
1872 ovs-vsctl add-br br-phys
1873 ovn_attach n1 br-phys 192.168.0.1
1874 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
1875
1876 # Create hypervisor hv2 connected to n1
1877 sim_add hv2
1878 as hv2
1879 ovs-vsctl add-br br-phys
1880 ovn_attach n1 br-phys 192.168.0.2
1881 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
1882
1883
1884 # Start the vtep emulator with a leg in both networks
1885 sim_add vtep
1886 as vtep
1887
1888 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1889 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1890
1891 ovs-vsctl add-br br-phys
1892 net_attach n1 br-phys
1893
1894 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1895 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1896 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1897 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1898
1899 ovs-vsctl add-br br-vtep
1900 net_attach n2 br-vtep
1901
1902 vtep-ctl add-ps br-vtep
1903 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1904 vtep-ctl add-ls lsw0
1905
1906 start_daemon ovs-vtep br-vtep
1907 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1908
1909 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
1910
1911 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1912 grep -- source`"])
1913 # It takes more time for the update to be processed by ovs-vtep.
1914 sleep 1
1915
1916 # Add hv3 on the other side of the vtep
1917 sim_add hv3
1918 as hv3
1919 ovs-vsctl add-br br-phys
1920 net_attach n2 br-phys
1921
1922 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
1923
1924 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1925 # packets for ARP resolution (native tunneling doesn't queue packets
1926 # for ARP resolution).
1927 ovn_populate_arp
1928
1929 # Allow some time for ovn-northd and ovn-controller to catch up.
1930 # XXX This should be more systematic.
1931 sleep 1
1932
1933 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1934 #
1935 # This shell function causes a packet to be received on INPORT. The packet's
1936 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1937 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1938 # more) list the VIFs on which the packet should be received. INPORT and the
1939 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
1940 for i in 1 2 3; do
1941 : > $i.expected
1942 done
1943 test_packet() {
1944 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1945 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1946 hv=hv$inport
1947 vif=vif$inport
1948 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1949 for outport; do
1950 echo $packet >> $outport.expected
1951 done
1952 }
1953
1954 # Send packets between all pairs of source and destination ports:
1955 #
1956 # 1. Unicast packets are delivered to exactly one logical switch port
1957 # (except that packets destined to their input ports are dropped).
1958 #
1959 # 2. Broadcast and multicast are delivered to all logical switch ports
1960 # except the input port.
1961 #
1962 # 3. The switch delivers packets with an unknown destination to logical
1963 # switch ports with "unknown" among their MAC addresses (and port
1964 # security disabled).
1965 for s in 1 2 3; do
1966 bcast=
1967 unknown=
1968 for d in 1 2 3; do
1969 if test $d != $s; then unicast=$d; else unicast=; fi
1970 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1971
1972 # The vtep (vif3) is the only one configured for "unknown"
1973 if test $d != $s && test $d = 3; then
1974 unknown="$unknown $d"
1975 fi
1976 bcast="$bcast $unicast"
1977 done
1978
1979 # Broadcast and multicast.
1980 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1981 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
1982
1983 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1984 done
1985
1986 # ARP request should not be responded to by logical switch router
1987 # type arp responder on HV1 and HV2 and should reach directly to
1988 # vif1 and vif2
1989 ip_to_hex() {
1990 printf "%02x%02x%02x%02x" "$@"
1991 }
1992 sha=f00000000003
1993 spa=`ip_to_hex 192 168 1 2`
1994 tpa=`ip_to_hex 192 168 1 1`
1995 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1996 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
1997 echo $request >> 1.expected
1998 echo $request >> 2.expected
1999
2000 # dump information with counters
2001 echo "------ OVN dump ------"
2002 ovn-nbctl show
2003 ovn-sbctl show
2004
2005 echo "---------SB dump-----"
2006 ovn-sbctl list datapath_binding
2007 echo "---------------------"
2008 ovn-sbctl list port_binding
2009 echo "---------------------"
2010 ovn-sbctl dump-flows
2011
2012 echo "------ hv1 dump ------"
2013 as hv1 ovs-vsctl show
2014 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2015 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2016
2017 echo "------ hv2 dump ------"
2018 as hv2 ovs-vsctl show
2019 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2020 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2021
2022 echo "------ hv3 dump ------"
2023 as hv3 ovs-vsctl show
2024 # note: hv3 has no logical port bind, thus it should not have br-int
2025 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2026 [ovs-ofctl: br-int is not a bridge or a socket
2027 ])
2028
2029 # Now check the packets actually received against the ones expected.
2030 for i in 1 2 3; do
2031 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2032 done
2033
2034 # Gracefully terminate daemons
2035 OVN_CLEANUP([hv1],[hv2],[vtep])
2036 OVN_CLEANUP_VSWITCH([hv3])
2037
2038 AT_CLEANUP
2039
2040 # Similar test to "hardware GW"
2041 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2042 AT_SKIP_IF([test $HAVE_PYTHON = no])
2043 ovn_start
2044
2045 # Configure the Northbound database
2046 ovn-nbctl ls-add lsw0
2047
2048 ovn-nbctl lsp-add lsw0 lp1
2049 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2050
2051 ovn-nbctl lsp-add lsw0 lp2
2052 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2053
2054 ovn-nbctl lsp-add lsw0 lp-gw
2055 ovn-nbctl lsp-set-type lp-gw l2gateway
2056 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2057 ovn-nbctl lsp-set-addresses lp-gw unknown
2058
2059 net_add n1 # Network to connect hv1, hv2, and gw
2060 net_add n2 # Network to connect gw and hv3
2061
2062 # Create hypervisor hv1 connected to n1
2063 sim_add hv1
2064 as hv1
2065 ovs-vsctl add-br br-phys
2066 ovn_attach n1 br-phys 192.168.0.1
2067 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
2068
2069 # Create hypervisor hv2 connected to n1
2070 sim_add hv2
2071 as hv2
2072 ovs-vsctl add-br br-phys
2073 ovn_attach n1 br-phys 192.168.0.2
2074 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
2075
2076 # Create hypervisor hv_gw connected to n1 and n2
2077 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2078 sim_add hv_gw
2079 as hv_gw
2080 ovs-vsctl add-br br-phys
2081 ovn_attach n1 br-phys 192.168.0.3
2082 ovs-vsctl add-br br-phys2
2083 net_attach n2 br-phys2
2084 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2085
2086 # Add hv3 on the other side of the GW
2087 sim_add hv3
2088 as hv3
2089 ovs-vsctl add-br br-phys
2090 net_attach n2 br-phys
2091 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
2092
2093
2094 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2095 # packets for ARP resolution (native tunneling doesn't queue packets
2096 # for ARP resolution).
2097 ovn_populate_arp
2098
2099 # Allow some time for ovn-northd and ovn-controller to catch up.
2100 # XXX This should be more systematic.
2101 sleep 1
2102
2103 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2104 #
2105 # This shell function causes a packet to be received on INPORT. The packet's
2106 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2107 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2108 # more) list the VIFs on which the packet should be received. INPORT and the
2109 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2110 for i in 1 2 3; do
2111 : > $i.expected
2112 done
2113 test_packet() {
2114 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2115 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2116 hv=hv$inport
2117 vif=vif$inport
2118 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2119 for outport; do
2120 echo $packet >> $outport.expected
2121 done
2122 }
2123
2124 # Send packets between all pairs of source and destination ports:
2125 #
2126 # 1. Unicast packets are delivered to exactly one lport (except that packets
2127 # destined to their input ports are dropped).
2128 #
2129 # 2. Broadcast and multicast are delivered to all lports except the input port.
2130 #
2131 # 3. The lswitch delivers packets with an unknown destination to lports with
2132 # "unknown" among their MAC addresses (and port security disabled).
2133 for s in 1 2 3 ; do
2134 bcast=
2135 unknown=
2136 for d in 1 2 3 ; do
2137 if test $d != $s; then unicast=$d; else unicast=; fi
2138 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2139
2140 # The vtep (vif3) is the only one configured for "unknown"
2141 if test $d != $s && test $d = 3; then
2142 unknown="$unknown $d"
2143 fi
2144 bcast="$bcast $unicast"
2145 done
2146
2147 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2148 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2149 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2150 done
2151
2152 echo "------ ovn-nbctl show ------"
2153 ovn-nbctl show
2154 echo "------ ovn-sbctl show ------"
2155 ovn-sbctl show
2156
2157 echo "------ hv1 ------"
2158 as hv1 ovs-vsctl show
2159 echo "------ hv1 br-int ------"
2160 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2161 echo "------ hv1 br-phys ------"
2162 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2163
2164 echo "------ hv2 ------"
2165 as hv2 ovs-vsctl show
2166 echo "------ hv2 br-int ------"
2167 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2168 echo "------ hv2 br-phys ------"
2169 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2170
2171 echo "------ hv_gw ------"
2172 as hv_gw ovs-vsctl show
2173 echo "------ hv_gw br-phys ------"
2174 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2175 echo "------ hv_gw br-phys2 ------"
2176 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2177
2178 echo "------ hv3 ------"
2179 as hv3 ovs-vsctl show
2180 echo "------ hv3 br-phys ------"
2181 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2182
2183 # Now check the packets actually received against the ones expected.
2184 for i in 1 2 3; do
2185 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2186 done
2187 AT_CLEANUP
2188
2189 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2190 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2191 AT_SKIP_IF([test $HAVE_PYTHON = no])
2192 ovn_start
2193
2194 # Logical network:
2195 #
2196 # Three logical switches ls1, ls2, ls3.
2197 # One logical router lr0 connected to ls[123],
2198 # with nine subnets, three per logical switch:
2199 #
2200 # lrp11 on ls1 for subnet 192.168.11.0/24
2201 # lrp12 on ls1 for subnet 192.168.12.0/24
2202 # lrp13 on ls1 for subnet 192.168.13.0/24
2203 # ...
2204 # lrp33 on ls3 for subnet 192.168.33.0/24
2205 #
2206 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2207 # digits are the subnet and the last digit distinguishes the VIF.
2208 for i in 1 2 3; do
2209 ovn-nbctl ls-add ls$i
2210 for j in 1 2 3; do
2211 for k in 1 2 3; do
2212 # Add "unknown" to MAC addresses for lp?11, so packets for
2213 # MAC-IP bindings discovered via ARP later have somewhere to go.
2214 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2215
2216 ovn-nbctl \
2217 -- lsp-add ls$i lp$i$j$k \
2218 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2219 192.168.$i$j.$k" $unknown
2220 done
2221 done
2222 done
2223
2224 ovn-nbctl lr-add lr0
2225 for i in 1 2 3; do
2226 for j in 1 2 3; do
2227 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2228 ovn-nbctl \
2229 -- lsp-add ls$i lrp$i$j-attachment \
2230 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2231 options:router-port=lrp$i$j \
2232 addresses='"00:00:00:00:ff:'$i$j'"'
2233 done
2234 done
2235
2236 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2237 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2238
2239 # Physical network:
2240 #
2241 # Three hypervisors hv[123].
2242 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2243 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2244 # lp?3[123] all on hv3.
2245
2246
2247 # Given the name of a logical port, prints the name of the hypervisor
2248 # on which it is located.
2249 vif_to_hv() {
2250 case $1 in dnl (
2251 ?11) echo 1 ;; dnl (
2252 ?12 | ?21 | ?22) echo 2 ;; dnl (
2253 ?13 | ?23 | ?3?) echo 3 ;;
2254 esac
2255 }
2256
2257 # Given the name of a logical port, prints the name of its logical router
2258 # port, e.g. "vif_to_lrp 123" yields 12.
2259 vif_to_lrp() {
2260 echo ${1%?}
2261 }
2262
2263 # Given the name of a logical port, prints the name of its logical
2264 # switch, e.g. "vif_to_ls 123" yields 1.
2265 vif_to_ls() {
2266 echo ${1%??}
2267 }
2268
2269 net_add n1
2270 for i in 1 2 3; do
2271 sim_add hv$i
2272 as hv$i
2273 ovs-vsctl add-br br-phys
2274 ovn_attach n1 br-phys 192.168.0.$i
2275 done
2276 for i in 1 2 3; do
2277 for j in 1 2 3; do
2278 for k in 1 2 3; do
2279 hv=`vif_to_hv $i$j$k`
2280 as hv$hv ovs-vsctl \
2281 -- add-port br-int vif$i$j$k \
2282 -- set Interface vif$i$j$k \
2283 external-ids:iface-id=lp$i$j$k \
2284 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2285 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2286 ofport-request=$i$j$k
2287 done
2288 done
2289 done
2290
2291 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2292 # packets for ARP resolution (native tunneling doesn't queue packets
2293 # for ARP resolution).
2294 ovn_populate_arp
2295
2296 # Allow some time for ovn-northd and ovn-controller to catch up.
2297 # XXX This should be more systematic.
2298 sleep 1
2299
2300 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2301 #
2302 # This shell function causes a packet to be received on INPORT. The packet's
2303 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2304 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2305 # more) list the VIFs on which the packet should be received. INPORT and the
2306 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2307 for i in 1 2 3; do
2308 for j in 1 2 3; do
2309 for k in 1 2 3; do
2310 : > $i$j$k.expected
2311 done
2312 done
2313 done
2314 test_ip() {
2315 # This packet has bad checksums but logical L3 routing doesn't check.
2316 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2317 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2318 shift; shift; shift; shift; shift
2319 hv=hv`vif_to_hv $inport`
2320 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2321 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2322 in_ls=`vif_to_ls $inport`
2323 in_lrp=`vif_to_lrp $inport`
2324 for outport; do
2325 out_ls=`vif_to_ls $outport`
2326 if test $in_ls = $out_ls; then
2327 # Ports on the same logical switch receive exactly the same packet.
2328 echo $packet
2329 else
2330 # Routing decrements TTL and updates source and dest MAC
2331 # (and checksum).
2332 out_lrp=`vif_to_lrp $outport`
2333 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2334 fi >> $outport.expected
2335 done
2336 }
2337
2338 as hv1 ovs-vsctl --columns=name,ofport list interface
2339 as hv1 ovn-sbctl list port_binding
2340 as hv1 ovn-sbctl list datapath_binding
2341 as hv1 ovn-sbctl dump-flows
2342 as hv1 ovs-ofctl dump-flows br-int
2343
2344 # Send IP packets between all pairs of source and destination ports:
2345 #
2346 # 1. Unicast IP packets are delivered to exactly one logical switch port
2347 # (except that packets destined to their input ports are dropped).
2348 #
2349 # 2. Broadcast IP packets are delivered to all logical switch ports
2350 # except the input port.
2351 ip_to_hex() {
2352 printf "%02x%02x%02x%02x" "$@"
2353 }
2354 for is in 1 2 3; do
2355 for js in 1 2 3; do
2356 for ks in 1 2 3; do
2357 bcast=
2358 s=$is$js$ks
2359 smac=f00000000$s
2360 sip=`ip_to_hex 192 168 $is$js $ks`
2361 for id in 1 2 3; do
2362 for jd in 1 2 3; do
2363 for kd in 1 2 3; do
2364 d=$id$jd$kd
2365 dip=`ip_to_hex 192 168 $id$jd $kd`
2366 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2367 if test $d != $s; then unicast=$d; else unicast=; fi
2368
2369 test_ip $s $smac $dmac $sip $dip $unicast #1
2370
2371 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2372 done
2373 done
2374 done
2375 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2376 done
2377 done
2378 done
2379
2380 # 3. Send an IP packet from every logical port to every other subnet,
2381 # to an IP address that does not have a static IP-MAC binding.
2382 # This should generate a broadcast ARP request for the destination
2383 # IP address in the destination subnet.
2384 for is in 1 2 3; do
2385 for js in 1 2 3; do
2386 for ks in 1 2 3; do
2387 s=$is$js$ks
2388 smac=f00000000$s
2389 sip=`ip_to_hex 192 168 $is$js $ks`
2390 for id in 1 2 3; do
2391 for jd in 1 2 3; do
2392 if test $is$js = $id$jd; then
2393 continue
2394 fi
2395
2396 # Send the packet.
2397 dmac=00000000ff$is$js
2398 # Calculate a 4th octet for the destination that is
2399 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2400 # that have static MAC bindings, and fits in the range
2401 # 0-255.
2402 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2403 dip=`ip_to_hex 192 168 $id$jd $o4`
2404 test_ip $s $smac $dmac $sip $dip
2405
2406 # Every LP on the destination subnet's lswitch should
2407 # receive the ARP request.
2408 lrmac=00000000ff$id$jd
2409 lrip=`ip_to_hex 192 168 $id$jd 254`
2410 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2411 for jd2 in 1 2 3; do
2412 for kd in 1 2 3; do
2413 echo $arp >> $id$jd2$kd.expected
2414 done
2415 done
2416 done
2417 done
2418 done
2419 done
2420 done
2421
2422 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2423 #
2424 # Causes a packet to be received on INPORT. The packet is an ARP
2425 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2426 # it should be the hardware address of the target to expect to receive in an
2427 # ARP reply; otherwise no reply is expected.
2428 #
2429 # INPORT is an logical switch port number, e.g. 11 for vif11.
2430 # SHA and REPLY_HA are each 12 hex digits.
2431 # SPA and TPA are each 8 hex digits.
2432 test_arp() {
2433 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2434 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2435 hv=hv`vif_to_hv $inport`
2436 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2437 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2438
2439 # Expect to receive the broadcast ARP on the other logical switch ports if
2440 # IP address is not configured to the switch patch port.
2441 local i=`vif_to_ls $inport`
2442 local j k
2443 for j in 1 2 3; do
2444 for k in 1 2 3; do
2445 # 192.168.33.254 is configured to the switch patch port for lrp33,
2446 # so no ARP flooding expected for it.
2447 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2448 echo $request >> $i$j$k.expected
2449 fi
2450 done
2451 done
2452
2453 # Expect to receive the reply, if any.
2454 if test X$reply_ha != X; then
2455 lrp=`vif_to_lrp $inport`
2456 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2457 echo $reply >> $inport.expected
2458 fi
2459 }
2460
2461 # Test router replies to ARP requests from all source ports:
2462 #
2463 # 4. Router replies to query for its MAC address from port's own IP address.
2464 #
2465 # 5. Router replies to query for its MAC address from any random IP address
2466 # in its subnet.
2467 #
2468 # 6. Router replies to query for its MAC address from another subnet.
2469 #
2470 # 7. No reply to query for IP address other than router IP.
2471 for i in 1 2 3; do
2472 for j in 1 2 3; do
2473 for k in 1 2 3; do
2474 smac=f00000000$i$j$k # Source MAC
2475 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2476 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2477 rmac=00000000ff$i$j # Router MAC
2478 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2479 test_arp $i$j$k $smac $sip $rip $rmac #4
2480 test_arp $i$j$k $smac $otherip $rip $rmac #5
2481 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2482 test_arp $i$j$k $smac $sip $otherip #7
2483 done
2484 done
2485 done
2486
2487 # Allow some time for packet forwarding.
2488 # XXX This can be improved.
2489 sleep 1
2490
2491 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2492 # earlier as #3.
2493 #
2494 # Here, the $s is the VIF that originated the ARP request and $d is
2495 # the VIF that sends the ARP reply, which is somewhat backward but
2496 # it means that $s and $d are the same as #3.
2497 : > mac_bindings.expected
2498 for is in 1 2 3; do
2499 for js in 1 2 3; do
2500 for ks in 1 2 3; do
2501 s=$is$js$ks
2502 for id in 1 2 3; do
2503 for jd in 1 2 3; do
2504 if test $is$js = $id$jd; then
2505 continue
2506 fi
2507
2508 kd=1
2509 d=$id$jd$kd
2510
2511 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2512 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2513 host_mac=8000000000$o4
2514
2515 lrmac=00000000ff$id$jd
2516 lrip=`ip_to_hex 192 168 $id$jd 254`
2517
2518 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2519
2520 echo
2521 echo
2522 echo
2523 hv=hv`vif_to_hv $d`
2524 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2525 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2526 #as $hv ovs-ofctl dump-flows br-int table=19
2527
2528 host_ip_pretty=192.168.$id$jd.$o4
2529 host_mac_pretty=80:00:00:00:00:$o4
2530 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2531 done
2532 done
2533 done
2534 done
2535 done
2536
2537 # Allow some time for packet forwarding.
2538 # XXX This can be improved.
2539 sleep 1
2540
2541 # 9. Send an IP packet from every logical port to every other subnet. These
2542 # are the same packets already sent as #3, but now the destinations' IP-MAC
2543 # bindings have been discovered via ARP, so instead of provoking an ARP
2544 # request, these packets now get routed to their destinations (which don't
2545 # have static MAC bindings, so they go to the port we've designated as
2546 # accepting "unknown" MACs.)
2547 for is in 1 2 3; do
2548 for js in 1 2 3; do
2549 for ks in 1 2 3; do
2550 s=$is$js$ks
2551 smac=f00000000$s
2552 sip=`ip_to_hex 192 168 $is$js $ks`
2553 for id in 1 2 3; do
2554 for jd in 1 2 3; do
2555 if test $is$js = $id$jd; then
2556 continue
2557 fi
2558
2559 # Send the packet.
2560 dmac=00000000ff$is$js
2561 # Calculate a 4th octet for the destination that is
2562 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2563 # that have static MAC bindings, and fits in the range
2564 # 0-255.
2565 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2566 dip=`ip_to_hex 192 168 $id$jd $o4`
2567 test_ip $s $smac $dmac $sip $dip
2568
2569 # Expect the packet egress.
2570 host_mac=8000000000$o4
2571 outport=${id}11
2572 out_lrp=$id$jd
2573 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2574 done
2575 done
2576 done
2577 done
2578 done
2579
2580 ovn-sbctl -f csv -d bare --no-heading \
2581 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2582
2583 # Now check the packets actually received against the ones expected.
2584 for i in 1 2 3; do
2585 for j in 1 2 3; do
2586 for k in 1 2 3; do
2587 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2588 [$i$j$k.expected])
2589 done
2590 done
2591 done
2592
2593 # Check the MAC bindings against those expected.
2594 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2595 ])
2596
2597 # Gracefully terminate daemons
2598 OVN_CLEANUP([hv1], [hv2], [hv3])
2599
2600 AT_CLEANUP
2601
2602 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2603 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2604 AT_SKIP_IF([test $HAVE_PYTHON = no])
2605 ovn_start
2606
2607 # Create hypervisors hv[123].
2608 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2609 # Add all of the vifs to a single logical switch lsw0.
2610 # Turn off port security on vifs vif[123]1
2611 # Turn on l2 port security on vifs vif[123]2
2612 # Turn of l2 and l3 port security on vifs vif[123]3
2613 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2614 ovn-nbctl ls-add lsw0
2615 net_add n1
2616 for i in 1 2 3; do
2617 sim_add hv$i
2618 as hv$i
2619 ovs-vsctl add-br br-phys
2620 ovn_attach n1 br-phys 192.168.0.$i
2621
2622 for j in 1 2 3; do
2623 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
2624 ovn-nbctl lsp-add lsw0 lp$i$j
2625 if test $j = 1; then
2626 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2627 elif test $j = 2; then
2628 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2629 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2630 else
2631 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2632 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2633 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2634 fi
2635 done
2636 done
2637
2638 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2639 # packets for ARP resolution (native tunneling doesn't queue packets
2640 # for ARP resolution).
2641 ovn_populate_arp
2642
2643 # Allow some time for ovn-northd and ovn-controller to catch up.
2644 # XXX This should be more systematic.
2645 sleep 1
2646
2647 # Given the name of a logical port, prints the name of the hypervisor
2648 # on which it is located.
2649 vif_to_hv() {
2650 echo hv${1%?}
2651 }
2652
2653 for i in 1 2 3; do
2654 for j in 1 2 3; do
2655 : > $i$j.expected
2656 done
2657 done
2658
2659 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2660 #
2661 # This shell function causes an ip packet to be received on INPORT.
2662 # The packet's content has Ethernet destination DST and source SRC
2663 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2664 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2665 # be received. INPORT and the OUTPORTs are specified as logical switch
2666 # port numbers, e.g. 11 for vif11.
2667 test_ip() {
2668 # This packet has bad checksums but logical L3 routing doesn't check.
2669 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2670 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2671 shift; shift; shift; shift; shift
2672 hv=`vif_to_hv $inport`
2673 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2674 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2675 for outport; do
2676 echo $packet >> $outport.expected
2677 done
2678 }
2679
2680 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2681 #
2682 # Causes a packet to be received on INPORT. The packet is an ARP
2683 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2684 # it should be the hardware address of the target to expect to receive in an
2685 # ARP reply; otherwise no reply is expected.
2686 #
2687 # INPORT is an logical switch port number, e.g. 11 for vif11.
2688 # SHA and REPLY_HA are each 12 hex digits.
2689 # SPA and TPA are each 8 hex digits.
2690 test_arp() {
2691 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2692 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2693 hv=`vif_to_hv $inport`
2694 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2695 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2696 if test $drop != 1; then
2697 if test X$reply_ha = X; then
2698 # Expect to receive the broadcast ARP on the other logical switch ports
2699 # if no reply is expected.
2700 local i j
2701 for i in 1 2 3; do
2702 for j in 1 2 3; do
2703 if test $i$j != $inport; then
2704 echo $request >> $i$j.expected
2705 fi
2706 done
2707 done
2708 else
2709 # Expect to receive the reply, if any.
2710 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2711 echo $reply >> $inport.expected
2712 fi
2713 fi
2714 }
2715
2716 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2717 # This function is similar to test_ip() except that it sends
2718 # ipv6 packet
2719 test_ipv6() {
2720 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2721 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2722 shift; shift; shift; shift; shift
2723 hv=`vif_to_hv $inport`
2724 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2725 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2726 for outport; do
2727 echo $packet >> $outport.expected
2728 done
2729 }
2730
2731 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2732 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2733 # of the test packet
2734 test_icmpv6() {
2735 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2736 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2737 shift; shift; shift; shift; shift; shift
2738 hv=`vif_to_hv $inport`
2739 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2740 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2741 for outport; do
2742 echo $packet >> $outport.expected
2743 done
2744 }
2745
2746 ip_to_hex() {
2747 printf "%02x%02x%02x%02x" "$@"
2748 }
2749
2750 # no port security
2751 sip=`ip_to_hex 192 168 0 12`
2752 tip=`ip_to_hex 192 168 0 13`
2753 # the arp packet should be allowed even if lp[123]1 is
2754 # not configured with mac f00000000023 and ip 192.168.0.12
2755 for i in 1 2 3; do
2756 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2757 for j in 1 2 3; do
2758 if test $i != $j; then
2759 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2760 fi
2761 done
2762 done
2763
2764 # l2 port security
2765 sip=`ip_to_hex 192 168 0 12`
2766 tip=`ip_to_hex 192 168 0 13`
2767
2768 # arp packet should be allowed since lp22 is configured with
2769 # mac f00000000022
2770 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2771
2772 # arp packet should not be allowed since lp32 is not configured with
2773 # mac f00000000021
2774 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2775
2776 # arp packet with sha set to f00000000021 should not be allowed
2777 # for lp12
2778 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2779
2780 # ip packets should be allowed and received since lp[123]2 do not
2781 # have l3 port security
2782 sip=`ip_to_hex 192 168 0 55`
2783 tip=`ip_to_hex 192 168 0 66`
2784 for i in 1 2 3; do
2785 for j in 1 2 3; do
2786 if test $i != $j; then
2787 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2788 fi
2789 done
2790 done
2791
2792 # ipv6 packets should be received by lp[123]2
2793 # lp[123]1 can send ipv6 traffic as there is no port security
2794 sip=fe800000000000000000000000000000
2795 tip=ff020000000000000000000000000000
2796
2797 for i in 1 2 3; do
2798 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2799 done
2800
2801
2802 # l2 and l3 port security
2803 sip=`ip_to_hex 192 168 0 13`
2804 tip=`ip_to_hex 192 168 0 22`
2805 # arp packet should be allowed since lp13 is configured with
2806 # f00000000013 and 192.168.0.13
2807 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2808
2809 # the arp packet should be dropped because lp23 is not configured
2810 # with mac f00000000022
2811 sip=`ip_to_hex 192 168 0 13`
2812 tip=`ip_to_hex 192 168 0 22`
2813 test_arp 23 f00000000022 f00000000022 $sip $tip 1
2814
2815 # the arp packet should be dropped because lp33 is not configured
2816 # with ip 192.168.0.55
2817 spa=`ip_to_hex 192 168 0 55`
2818 tpa=`ip_to_hex 192 168 0 22`
2819 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2820
2821 # ip packets should not be received by lp[123]3 since
2822 # l3 port security is enabled
2823 sip=`ip_to_hex 192 168 0 55`
2824 tip=`ip_to_hex 192 168 0 66`
2825 for i in 1 2 3; do
2826 for j in 1 2 3; do
2827 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2828 done
2829 done
2830
2831 # ipv6 packets should be dropped for lp[123]3 since
2832 # it is configured with only ipv4 address
2833 sip=fe800000000000000000000000000000
2834 tip=ff020000000000000000000000000000
2835
2836 for i in 1 2 3; do
2837 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2838 done
2839
2840 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2841 # lp[123]1 can send ipv6 traffic as there is no port security
2842 for i in 1 2 3; do
2843 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2844 done
2845
2846 # lp13 has extra port security with mac f0000000113 and ipv6 addr
2847 # fe80::ea2a:eaff:fe28:0012
2848
2849 # ipv4 packet should be dropped for lp13 with mac f0000000113
2850 sip=`ip_to_hex 192 168 0 13`
2851 tip=`ip_to_hex 192 168 0 23`
2852 test_ip 13 f00000000113 f00000000023 $sip $tip
2853
2854 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2855 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
2856 # lp11 can send ipv6 traffic as there is no port security
2857 sip=ee800000000000000000000000000000
2858 for i in 1 2 3; do
2859 tip=fe80000000000000ea2aeafffe2800${i}3
2860 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
2861 done
2862
2863
2864 # ipv6 packet should not be received by lp33 with mac f0000000333
2865 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2866 # configured with fe80::ea2a:eaff:fe28:0033
2867 # lp11 can send ipv6 traffic as there is no port security
2868
2869 sip=ee800000000000000000000000000000
2870 tip=fe80000000000000ea2aeafffe280023
2871 test_ipv6 11 f00000000011 f00000000333 $sip $tip
2872
2873 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2874 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
2875 # and should be dropped for any other ip6.src
2876 # lp21 can receive ipv6 traffic as there is no port security
2877
2878 tip=ee800000000000000000000000000000
2879 for i in 1 2 3; do
2880 sip=fe80000000000000ea2aeafffe2800${i}3
2881 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2882
2883 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
2884 sip=00000000000000000000000000000000
2885 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2886 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2887 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2888 # Traffic to non-multicast traffic should be dropped
2889 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2890 # Traffic of other ICMPv6 types should be dropped
2891 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
2892
2893 # should be dropped
2894 sip=ae80000000000000ea2aeafffe2800aa
2895 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2896 done
2897
2898 # configure lsp13 to send and received IPv4 packets with an address range
2899 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"
2900
2901 sleep 2
2902
2903 sip=`ip_to_hex 10 0 0 13`
2904 tip=`ip_to_hex 192 168 0 22`
2905 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
2906 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2907
2908 sip=`ip_to_hex 10 0 0 14`
2909 tip=`ip_to_hex 192 168 0 23`
2910 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
2911 # with dst ip 192.168.0.23 should be allowed
2912 test_ip 13 f00000000013 f00000000023 $sip $tip 23
2913
2914 sip=`ip_to_hex 192 168 0 33`
2915 tip=`ip_to_hex 10 0 0 15`
2916 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2917 # with dst ip 10.0.0.15 should be received by lsp13
2918 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2919
2920 sip=`ip_to_hex 192 168 0 33`
2921 tip=`ip_to_hex 20 0 0 4`
2922 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2923 # with dst ip 20.0.0.4 should be received by lsp13
2924 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2925
2926 sip=`ip_to_hex 192 168 0 33`
2927 tip=`ip_to_hex 20 0 0 5`
2928 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2929 # with dst ip 20.0.0.5 should not be received by lsp13
2930 test_ip 33 f00000000033 f00000000013 $sip $tip
2931
2932 sip=`ip_to_hex 192 168 0 33`
2933 tip=`ip_to_hex 20 0 0 255`
2934 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2935 # with dst ip 20.0.0.255 should be received by lsp13
2936 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2937
2938 sip=`ip_to_hex 192 168 0 33`
2939 tip=`ip_to_hex 192 168 0 255`
2940 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2941 # with dst ip 192.168.0.255 should not be received by lsp13
2942 test_ip 33 f00000000033 f00000000013 $sip $tip
2943
2944 sip=`ip_to_hex 192 168 0 33`
2945 tip=`ip_to_hex 224 0 0 4`
2946 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2947 # with dst ip 224.0.0.4 should be received by lsp13
2948 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2949
2950 #dump information including flow counters
2951 ovn-nbctl show
2952 ovn-sbctl dump-flows -- list multicast_group
2953
2954 echo "------ hv1 dump ------"
2955 as hv1 ovs-vsctl show
2956 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2957 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2958
2959 echo "------ hv2 dump ------"
2960 as hv2 ovs-vsctl show
2961 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2962 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2963
2964 echo "------ hv3 dump ------"
2965 as hv3 ovs-vsctl show
2966 as hv3 ovs-ofctl -O OpenFlow13 show br-int
2967 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2968
2969 # Now check the packets actually received against the ones expected.
2970 for i in 1 2 3; do
2971 for j in 1 2 3; do
2972 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2973 done
2974 done
2975
2976 OVN_CLEANUP([hv1],[hv2],[hv3])
2977
2978 AT_CLEANUP
2979
2980 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
2981 AT_SKIP_IF([test $HAVE_PYTHON = no])
2982 ovn_start
2983
2984 # Logical network:
2985 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2986 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2987 # R2 has ls2 (172.16.1.0/24) connected to it.
2988
2989 ls1_lp1_mac="f0:00:00:01:02:03"
2990 rp_ls1_mac="00:00:00:01:02:03"
2991 rp_ls2_mac="00:00:00:01:02:04"
2992 ls2_lp1_mac="f0:00:00:01:02:04"
2993
2994 ls1_lp1_ip="192.168.1.2"
2995 ls2_lp1_ip="172.16.1.2"
2996
2997 ovn-nbctl lr-add R1
2998 ovn-nbctl lr-add R2
2999
3000 ovn-nbctl ls-add ls1
3001 ovn-nbctl ls-add ls2
3002
3003 # Connect ls1 to R1
3004 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3005
3006 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3007 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3008
3009 # Connect ls2 to R2
3010 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3011
3012 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3013 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3014
3015 # Connect R1 to R2
3016 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3017 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3018
3019 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3020 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3021
3022 # Create logical port ls1-lp1 in ls1
3023 ovn-nbctl lsp-add ls1 ls1-lp1 \
3024 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3025
3026 # Create logical port ls2-lp1 in ls2
3027 ovn-nbctl lsp-add ls2 ls2-lp1 \
3028 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3029
3030 # Create two hypervisor and create OVS ports corresponding to logical ports.
3031 net_add n1
3032
3033 sim_add hv1
3034 as hv1
3035 ovs-vsctl add-br br-phys
3036 ovn_attach n1 br-phys 192.168.0.1
3037 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3038 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3039 options:tx_pcap=hv1/vif1-tx.pcap \
3040 options:rxq_pcap=hv1/vif1-rx.pcap \
3041 ofport-request=1
3042
3043 sim_add hv2
3044 as hv2
3045 ovs-vsctl add-br br-phys
3046 ovn_attach n1 br-phys 192.168.0.2
3047 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3048 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3049 options:tx_pcap=hv2/vif1-tx.pcap \
3050 options:rxq_pcap=hv2/vif1-rx.pcap \
3051 ofport-request=1
3052
3053
3054 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3055 # packets for ARP resolution (native tunneling doesn't queue packets
3056 # for ARP resolution).
3057 ovn_populate_arp
3058
3059 # Allow some time for ovn-northd and ovn-controller to catch up.
3060 # XXX This should be more systematic.
3061 sleep 1
3062
3063 # Packet to send.
3064 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3065 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3066 udp && udp.src==53 && udp.dst==4369"
3067 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3068
3069
3070 echo "---------NB dump-----"
3071 ovn-nbctl show
3072 echo "---------------------"
3073 ovn-nbctl list logical_router
3074 echo "---------------------"
3075 ovn-nbctl list logical_router_port
3076 echo "---------------------"
3077
3078 echo "---------SB dump-----"
3079 ovn-sbctl list datapath_binding
3080 echo "---------------------"
3081 ovn-sbctl list port_binding
3082 echo "---------------------"
3083
3084 echo "------ hv1 dump ----------"
3085 as hv1 ovs-ofctl show br-int
3086 as hv1 ovs-ofctl dump-flows br-int
3087 echo "------ hv2 dump ----------"
3088 as hv2 ovs-ofctl show br-int
3089 as hv2 ovs-ofctl dump-flows br-int
3090
3091 # Packet to Expect
3092 # The TTL should be decremented by 2.
3093 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3094 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3095 udp && udp.src==53 && udp.dst==4369"
3096 echo $packet | ovstest test-ovn expr-to-packets > expected
3097
3098 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3099
3100 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3101 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3102 ])
3103
3104 # Disable the ls2-lp1 port.
3105 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3106
3107 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3108 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3109 ])
3110
3111 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3112 # Packet to send.
3113 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3114 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3115 udp && udp.src==53 && udp.dst==4369"
3116
3117 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3118 # The 2nd packet sent shound not be received.
3119 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3120
3121 OVN_CLEANUP([hv1],[hv2])
3122
3123 AT_CLEANUP
3124
3125
3126 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3127 AT_KEYWORDS([router-admin-state])
3128 AT_SKIP_IF([test $HAVE_PYTHON = no])
3129 ovn_start
3130
3131 # Logical network:
3132 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3133 # and 172.16.1.0/24) connected to it.
3134
3135 ovn-nbctl lr-add R1
3136
3137 ovn-nbctl ls-add ls1
3138
3139 # Connect ls1 to R1
3140 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3141 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3142 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3143
3144 # Create logical port ls1-lp1 in ls1
3145 ovn-nbctl lsp-add ls1 ls1-lp1 \
3146 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3147
3148 # Create logical port ls1-lp2 in ls1
3149 ovn-nbctl lsp-add ls1 ls1-lp2 \
3150 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3151
3152 # Create one hypervisor and create OVS ports corresponding to logical ports.
3153 net_add n1
3154
3155 sim_add hv1
3156 as hv1
3157 ovs-vsctl add-br br-phys
3158 ovn_attach n1 br-phys 192.168.0.1
3159 ovs-vsctl -- add-port br-int vif1 -- \
3160 set interface vif1 external-ids:iface-id=ls1-lp1 \
3161 options:tx_pcap=hv1/vif1-tx.pcap \
3162 options:rxq_pcap=hv1/vif1-rx.pcap \
3163 ofport-request=1
3164
3165 ovs-vsctl -- add-port br-int vif2 -- \
3166 set interface vif2 external-ids:iface-id=ls1-lp2 \
3167 options:tx_pcap=hv1/vif2-tx.pcap \
3168 options:rxq_pcap=hv1/vif2-rx.pcap \
3169 ofport-request=1
3170
3171
3172 # Allow some time for ovn-northd and ovn-controller to catch up.
3173 # XXX This should be more systematic.
3174 sleep 1
3175
3176 # Send ip packets between the two ports.
3177 ip_to_hex() {
3178 printf "%02x%02x%02x%02x" "$@"
3179 }
3180
3181 # Packet to send.
3182 src_mac="f00000010203"
3183 dst_mac="000000010203"
3184 src_ip=`ip_to_hex 192 168 1 2`
3185 dst_ip=`ip_to_hex 172 16 1 2`
3186 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3187 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3188
3189
3190 echo "---------NB dump-----"
3191 ovn-nbctl show
3192 echo "---------------------"
3193 ovn-nbctl list logical_router
3194 echo "---------------------"
3195 ovn-nbctl list logical_router_port
3196 echo "---------------------"
3197
3198 echo "---------SB dump-----"
3199 ovn-sbctl list datapath_binding
3200 echo "---------------------"
3201 ovn-sbctl list logical_flow
3202 echo "---------------------"
3203
3204 echo "------ hv1 dump ----------"
3205 as hv1 ovs-ofctl dump-flows br-int
3206
3207
3208 #Disable router R1
3209 ovn-nbctl set Logical_Router R1 enabled=false
3210
3211 # Allow some time for ovn-northd and ovn-controller to catch up.
3212 # XXX This should be more systematic.
3213 sleep 1
3214
3215 echo "---------SB dump-----"
3216 ovn-sbctl list datapath_binding
3217 echo "---------------------"
3218 ovn-sbctl list logical_flow
3219 echo "---------------------"
3220
3221 echo "------ hv1 dump ----------"
3222 as hv1 ovs-ofctl dump-flows br-int
3223
3224 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3225
3226 # Packet to Expect
3227 expect_src_mac="000000010203"
3228 expect_dst_mac="f00000010204"
3229 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3230
3231 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3232
3233
3234 as hv1
3235 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3236 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3237 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3238
3239 as ovn-sb
3240 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3241
3242 as ovn-nb
3243 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3244
3245 as northd
3246 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3247
3248 as main
3249 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3250 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3251
3252 AT_CLEANUP
3253
3254
3255 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3256 AT_KEYWORDS([router-admin-state])
3257 AT_SKIP_IF([test $HAVE_PYTHON = no])
3258 ovn_start
3259
3260 # Logical network:
3261 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3262 # and has switch ls2 (172.16.1.0/24) connected to it.
3263
3264 ovn-nbctl lr-add R1
3265
3266 ovn-nbctl ls-add ls1
3267 ovn-nbctl ls-add ls2
3268
3269 # Connect ls1 to R1
3270 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3271 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3272 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3273
3274 # Connect ls2 to R1
3275 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3276 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3277 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3278
3279 # Create logical port ls1-lp1 in ls1
3280 ovn-nbctl lsp-add ls1 ls1-lp1 \
3281 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3282
3283 # Create logical port ls2-lp1 in ls2
3284 ovn-nbctl lsp-add ls2 ls2-lp1 \
3285 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3286
3287 # Create one hypervisor and create OVS ports corresponding to logical ports.
3288 net_add n1
3289
3290 sim_add hv1
3291 as hv1
3292 ovs-vsctl add-br br-phys
3293 ovn_attach n1 br-phys 192.168.0.1
3294 ovs-vsctl -- add-port br-int vif1 -- \
3295 set interface vif1 external-ids:iface-id=ls1-lp1 \
3296 options:tx_pcap=hv1/vif1-tx.pcap \
3297 options:rxq_pcap=hv1/vif1-rx.pcap \
3298 ofport-request=1
3299
3300 ovs-vsctl -- add-port br-int vif2 -- \
3301 set interface vif2 external-ids:iface-id=ls2-lp1 \
3302 options:tx_pcap=hv1/vif2-tx.pcap \
3303 options:rxq_pcap=hv1/vif2-rx.pcap \
3304 ofport-request=1
3305
3306
3307 # Allow some time for ovn-northd and ovn-controller to catch up.
3308 # XXX This should be more systematic.
3309 sleep 1
3310
3311 # Send ip packets between the two ports.
3312 ip_to_hex() {
3313 printf "%02x%02x%02x%02x" "$@"
3314 }
3315
3316 # Packet to send.
3317 src_mac="f00000010203"
3318 dst_mac="000000010203"
3319 src_ip=`ip_to_hex 192 168 1 2`
3320 dst_ip=`ip_to_hex 172 16 1 2`
3321 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3322 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3323
3324
3325 echo "---------NB dump-----"
3326 ovn-nbctl show
3327 echo "---------------------"
3328 ovn-nbctl list logical_router
3329 echo "---------------------"
3330 ovn-nbctl list logical_router_port
3331 echo "---------------------"
3332
3333 echo "---------SB dump-----"
3334 ovn-sbctl list datapath_binding
3335 echo "---------------------"
3336 ovn-sbctl list logical_flow
3337 echo "---------------------"
3338
3339 echo "------ hv1 dump ----------"
3340 as hv1 ovs-ofctl dump-flows br-int
3341
3342 #Disable router R1
3343 ovn-nbctl set Logical_Router R1 enabled=false
3344
3345 echo "---------SB dump-----"
3346 ovn-sbctl list datapath_binding
3347 echo "---------------------"
3348 ovn-sbctl list logical_flow
3349 echo "---------------------"
3350
3351 echo "------ hv1 dump ----------"
3352 as hv1 ovs-ofctl dump-flows br-int
3353
3354 # Allow some time for the disabling of logical router R1 to propagate.
3355 # XXX This should be more systematic.
3356 sleep 1
3357
3358 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3359
3360 # Packet to Expect
3361 expect_src_mac="000000010204"
3362 expect_dst_mac="f00000010204"
3363 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3364
3365 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3366
3367 OVN_CLEANUP([hv1])
3368
3369 AT_CLEANUP
3370
3371 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3372 AT_SKIP_IF([test $HAVE_PYTHON = no])
3373 ovn_start
3374
3375 # Logical network:
3376 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3377 # network. R1 has switchess foo (192.168.1.0/24)
3378 # connected to it.
3379 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3380
3381 ovn-nbctl lr-add R1
3382 ovn-nbctl lr-add R2
3383
3384 ovn-nbctl ls-add foo
3385 ovn-nbctl ls-add alice
3386 ovn-nbctl ls-add bob
3387
3388 # Connect foo to R1
3389 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3390 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3391 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3392
3393 # Connect alice to R2
3394 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3395 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3396 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3397
3398 # Connect bob to R2
3399 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3400 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3401 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3402
3403 # Connect R1 to R2
3404 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3405 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3406
3407 #install static routes
3408 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3409 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3410 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3411
3412 # Create logical port foo1 in foo
3413 ovn-nbctl lsp-add foo foo1 \
3414 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3415
3416 # Create logical port alice1 in alice
3417 ovn-nbctl lsp-add alice alice1 \
3418 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3419
3420 # Create logical port bob1 in bob
3421 ovn-nbctl lsp-add bob bob1 \
3422 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3423
3424 # Create two hypervisor and create OVS ports corresponding to logical ports.
3425 net_add n1
3426
3427 sim_add hv1
3428 as hv1
3429 ovs-vsctl add-br br-phys
3430 ovn_attach n1 br-phys 192.168.0.1
3431 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3432 set interface hv1-vif1 external-ids:iface-id=foo1 \
3433 options:tx_pcap=hv1/vif1-tx.pcap \
3434 options:rxq_pcap=hv1/vif1-rx.pcap \
3435 ofport-request=1
3436
3437 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3438 set interface hv1-vif2 external-ids:iface-id=alice1 \
3439 options:tx_pcap=hv1/vif2-tx.pcap \
3440 options:rxq_pcap=hv1/vif2-rx.pcap \
3441 ofport-request=2
3442
3443 sim_add hv2
3444 as hv2
3445 ovs-vsctl add-br br-phys
3446 ovn_attach n1 br-phys 192.168.0.2
3447 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3448 set interface hv2-vif1 external-ids:iface-id=bob1 \
3449 options:tx_pcap=hv2/vif1-tx.pcap \
3450 options:rxq_pcap=hv2/vif1-rx.pcap \
3451 ofport-request=1
3452
3453
3454 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3455 # packets for ARP resolution (native tunneling doesn't queue packets
3456 # for ARP resolution).
3457 ovn_populate_arp
3458
3459 # Allow some time for ovn-northd and ovn-controller to catch up.
3460 # XXX This should be more systematic.
3461 sleep 1
3462
3463 ip_to_hex() {
3464 printf "%02x%02x%02x%02x" "$@"
3465 }
3466
3467 # Send ip packets between foo1 and alice1
3468 src_mac="f00000010203"
3469 dst_mac="000000010203"
3470 src_ip=`ip_to_hex 192 168 1 2`
3471 dst_ip=`ip_to_hex 172 16 1 2`
3472 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3473 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3474
3475 # Send ip packets between foo1 and bob1
3476 src_mac="f00000010203"
3477 dst_mac="000000010203"
3478 src_ip=`ip_to_hex 192 168 1 2`
3479 dst_ip=`ip_to_hex 172 16 2 2`
3480 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3481 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3482
3483 echo "---------NB dump-----"
3484 ovn-nbctl show
3485 echo "---------------------"
3486 ovn-nbctl list logical_router
3487 echo "---------------------"
3488 ovn-nbctl list logical_router_port
3489 echo "---------------------"
3490
3491 echo "---------SB dump-----"
3492 ovn-sbctl list datapath_binding
3493 echo "---------------------"
3494 ovn-sbctl list port_binding
3495 echo "---------------------"
3496
3497 echo "------ hv1 dump ----------"
3498 as hv1 ovs-ofctl dump-flows br-int
3499 echo "------ hv2 dump ----------"
3500 as hv2 ovs-ofctl dump-flows br-int
3501
3502 # Packet to Expect at bob1
3503 src_mac="000000010205"
3504 dst_mac="f00000010205"
3505 src_ip=`ip_to_hex 192 168 1 2`
3506 dst_ip=`ip_to_hex 172 16 2 2`
3507 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3508
3509 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3510
3511 # Packet to Expect at alice1
3512 src_mac="000000010204"
3513 dst_mac="f00000010204"
3514 src_ip=`ip_to_hex 192 168 1 2`
3515 dst_ip=`ip_to_hex 172 16 1 2`
3516 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3517
3518 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3519
3520 OVN_CLEANUP([hv1],[hv2])
3521
3522 AT_CLEANUP
3523
3524 AT_SETUP([ovn -- send gratuitous arp on localnet])
3525 AT_SKIP_IF([test $HAVE_PYTHON = no])
3526 ovn_start
3527 ovn-nbctl ls-add lsw0
3528 net_add n1
3529 sim_add hv
3530 as hv
3531 ovs-vsctl \
3532 -- add-br br-phys \
3533 -- add-br br-eth0
3534
3535 ovn_attach n1 br-phys 192.168.0.1
3536
3537 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3538 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])
3539
3540 # Create a vif.
3541 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3542 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3543 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3544
3545 # Create a localnet port.
3546 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3547 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3548 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3549 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3550
3551 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3552
3553 # Wait for packet to be received.
3554 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3555 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3556
3557 # Delete the localnet ports.
3558 AT_CHECK([ovs-vsctl del-port localvif1])
3559 AT_CHECK([ovn-nbctl lsp-del ln_port])
3560
3561 OVN_CLEANUP([hv])
3562
3563 AT_CLEANUP
3564
3565 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3566 AT_SKIP_IF([test $HAVE_PYTHON = no])
3567 ovn_start
3568
3569 # Logical network:
3570 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3571 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3572 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3573 # connected to it.
3574
3575 ovn-nbctl lr-add R1
3576 ovn-nbctl lr-add R2
3577 ovn-nbctl lr-add R3
3578
3579 ovn-nbctl ls-add foo
3580 ovn-nbctl ls-add alice
3581 ovn-nbctl ls-add bob
3582 ovn-nbctl ls-add join
3583
3584 # Connect foo to R1
3585 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3586 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3587 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3588
3589 # Connect alice to R2
3590 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3591 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3592 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3593
3594 # Connect bob to R3
3595 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3596 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3597 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3598
3599 # Connect R1 to join
3600 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3601 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3602 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3603
3604 # Connect R2 to join
3605 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3606 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3607 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3608
3609 # Connect R3 to join
3610 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3611 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3612 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3613
3614 #install static routes
3615 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3616 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3617
3618 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3619 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3620
3621 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3622 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3623
3624 # Create logical port foo1 in foo
3625 ovn-nbctl lsp-add foo foo1 \
3626 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3627
3628 # Create logical port alice1 in alice
3629 ovn-nbctl lsp-add alice alice1 \
3630 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3631
3632 # Create logical port bob1 in bob
3633 ovn-nbctl lsp-add bob bob1 \
3634 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3635
3636 # Create two hypervisor and create OVS ports corresponding to logical ports.
3637 net_add n1
3638
3639 sim_add hv1
3640 as hv1
3641 ovs-vsctl add-br br-phys
3642 ovn_attach n1 br-phys 192.168.0.1
3643 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3644 set interface hv1-vif1 external-ids:iface-id=foo1 \
3645 options:tx_pcap=hv1/vif1-tx.pcap \
3646 options:rxq_pcap=hv1/vif1-rx.pcap \
3647 ofport-request=1
3648
3649 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3650 set interface hv1-vif2 external-ids:iface-id=alice1 \
3651 options:tx_pcap=hv1/vif2-tx.pcap \
3652 options:rxq_pcap=hv1/vif2-rx.pcap \
3653 ofport-request=2
3654
3655 sim_add hv2
3656 as hv2
3657 ovs-vsctl add-br br-phys
3658 ovn_attach n1 br-phys 192.168.0.2
3659 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3660 set interface hv2-vif1 external-ids:iface-id=bob1 \
3661 options:tx_pcap=hv2/vif1-tx.pcap \
3662 options:rxq_pcap=hv2/vif1-rx.pcap \
3663 ofport-request=1
3664
3665
3666 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3667 # packets for ARP resolution (native tunneling doesn't queue packets
3668 # for ARP resolution).
3669 ovn_populate_arp
3670
3671 # Allow some time for ovn-northd and ovn-controller to catch up.
3672 # XXX This should be more systematic.
3673 sleep 1
3674
3675 ip_to_hex() {
3676 printf "%02x%02x%02x%02x" "$@"
3677 }
3678
3679 # Send ip packets between foo1 and alice1
3680 src_mac="f00000010203"
3681 dst_mac="000001010203"
3682 src_ip=`ip_to_hex 192 168 1 2`
3683 dst_ip=`ip_to_hex 172 16 1 2`
3684 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3685 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3686 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3687
3688 # Send ip packets between foo1 and bob1
3689 src_mac="f00000010203"
3690 dst_mac="000001010203"
3691 src_ip=`ip_to_hex 192 168 1 2`
3692 dst_ip=`ip_to_hex 10 32 1 2`
3693 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3694 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3695
3696 echo "---------NB dump-----"
3697 ovn-nbctl show
3698 echo "---------------------"
3699 ovn-nbctl list logical_router
3700 echo "---------------------"
3701 ovn-nbctl list logical_router_port
3702 echo "---------------------"
3703
3704 echo "---------SB dump-----"
3705 ovn-sbctl list datapath_binding
3706 echo "---------------------"
3707 ovn-sbctl list port_binding
3708 echo "---------------------"
3709 ovn-sbctl dump-flows
3710 echo "---------------------"
3711
3712 echo "------ hv1 dump ----------"
3713 as hv1 ovs-ofctl show br-int
3714 as hv1 ovs-ofctl dump-flows br-int
3715 echo "------ hv2 dump ----------"
3716 as hv2 ovs-ofctl show br-int
3717 as hv2 ovs-ofctl dump-flows br-int
3718 echo "----------------------------"
3719
3720 # Packet to Expect at bob1
3721 src_mac="000003010203"
3722 dst_mac="f00000010205"
3723 src_ip=`ip_to_hex 192 168 1 2`
3724 dst_ip=`ip_to_hex 10 32 1 2`
3725 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3726
3727 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3728
3729 # Packet to Expect at alice1
3730 src_mac="000002010203"
3731 dst_mac="f00000010204"
3732 src_ip=`ip_to_hex 192 168 1 2`
3733 dst_ip=`ip_to_hex 172 16 1 2`
3734 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3735
3736 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3737
3738 OVN_CLEANUP([hv1],[hv2])
3739
3740 AT_CLEANUP
3741
3742 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3743 AT_SKIP_IF([test $HAVE_PYTHON = no])
3744 ovn_start
3745
3746 ovn-nbctl ls-add ls1
3747
3748 ovn-nbctl lsp-add ls1 ls1-lp1 \
3749 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3750
3751 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3752
3753 ovn-nbctl lsp-add ls1 ls1-lp2 \
3754 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3755
3756 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3757
3758 ovn-nbctl ls-add ls2
3759 ovn-nbctl lsp-add ls2 ls2-lp1 \
3760 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3761 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3762 ovn-nbctl lsp-add ls2 ls2-lp2 \
3763 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3764 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3765
3766 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
3767 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3768 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
3769
3770 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3771 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3772
3773 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
3774 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3775 \"lease_time\"=\"3600\"")"
3776
3777 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
3778
3779 net_add n1
3780 sim_add hv1
3781
3782 as hv1
3783 ovs-vsctl add-br br-phys
3784 ovn_attach n1 br-phys 192.168.0.1
3785 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3786 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3787 options:tx_pcap=hv1/vif1-tx.pcap \
3788 options:rxq_pcap=hv1/vif1-rx.pcap \
3789 ofport-request=1
3790
3791 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3792 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3793 options:tx_pcap=hv1/vif2-tx.pcap \
3794 options:rxq_pcap=hv1/vif2-rx.pcap \
3795 ofport-request=2
3796
3797 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3798 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3799 options:tx_pcap=hv1/vif3-tx.pcap \
3800 options:rxq_pcap=hv1/vif3-rx.pcap \
3801 ofport-request=3
3802
3803 ovs-vsctl -- add-port br-int hv1-vif4 -- \
3804 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3805 options:tx_pcap=hv1/vif4-tx.pcap \
3806 options:rxq_pcap=hv1/vif4-rx.pcap \
3807 ofport-request=4
3808
3809 ovn_populate_arp
3810
3811 sleep 2
3812
3813 as hv1 ovs-vsctl show
3814
3815 # This shell function sends a DHCP request packet
3816 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3817 test_dhcp() {
3818 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3819 shift; shift; shift; shift; shift;
3820 if test $use_ip != 0; then
3821 src_ip=$1
3822 dst_ip=$2
3823 shift; shift;
3824 else
3825 src_ip=`ip_to_hex 0 0 0 0`
3826 dst_ip=`ip_to_hex 255 255 255 255`
3827 fi
3828 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
3829 # udp header and dhcp header
3830 request=${request}0044004300fc0000
3831 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
3832 # client hardware padding
3833 request=${request}00000000000000000000
3834 # server hostname
3835 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3836 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3837 # boot file name
3838 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3839 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3840 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3841 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3842 # dhcp magic cookie
3843 request=${request}63825363
3844 # dhcp message type
3845 request=${request}3501${dhcp_type}ff
3846
3847 if test $offer_ip != 0; then
3848 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
3849 # total IP length will be the IP length of the request packet
3850 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3851 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3852 udp_len=`expr $ip_len - 20`
3853 ip_len=$(printf "%x" $ip_len)
3854 udp_len=$(printf "%x" $udp_len)
3855 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3856 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3857 # udp header and dhcp header.
3858 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
3859 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
3860 # your ip address
3861 reply=${reply}${offer_ip}
3862 # next server ip address, relay agent ip address, client mac address
3863 reply=${reply}0000000000000000${src_mac}
3864 # client hardware padding
3865 reply=${reply}00000000000000000000
3866 # server hostname
3867 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3868 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3869 # boot file name
3870 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3871 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3872 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3873 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3874 # dhcp magic cookie
3875 reply=${reply}63825363
3876 # dhcp message type
3877 local dhcp_reply_type=02
3878 if test $dhcp_type = 03; then
3879 dhcp_reply_type=05
3880 fi
3881 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3882 echo $reply >> $inport.expected
3883 else
3884 for outport; do
3885 echo $request >> $outport.expected
3886 done
3887 fi
3888 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3889 }
3890
3891 reset_pcap_file() {
3892 local iface=$1
3893 local pcap_file=$2
3894 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3895 options:rxq_pcap=dummy-rx.pcap
3896 rm -f ${pcap_file}*.pcap
3897 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3898 options:rxq_pcap=${pcap_file}-rx.pcap
3899 }
3900
3901 ip_to_hex() {
3902 printf "%02x%02x%02x%02x" "$@"
3903 }
3904
3905 AT_CAPTURE_FILE([ofctl_monitor0.log])
3906 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3907 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3908
3909 echo "---------NB dump-----"
3910 ovn-nbctl show
3911 echo "---------------------"
3912 echo "---------SB dump-----"
3913 ovn-sbctl list datapath_binding
3914 echo "---------------------"
3915 ovn-sbctl list logical_flow
3916 echo "---------------------"
3917
3918 echo "---------------------"
3919 ovn-sbctl dump-flows
3920 echo "---------------------"
3921
3922 echo "------ hv1 dump ----------"
3923 as hv1 ovs-ofctl dump-flows br-int
3924
3925 # Send DHCPDISCOVER.
3926 offer_ip=`ip_to_hex 10 0 0 4`
3927 server_ip=`ip_to_hex 10 0 0 1`
3928 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3929 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3930
3931 # NXT_RESUMEs should be 1.
3932 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3933
3934 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3935 cat 1.expected | cut -c -48 > expout
3936 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3937 # Skipping the IPv4 checksum.
3938 cat 1.expected | cut -c 53- > expout
3939 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3940
3941 # ovs-ofctl also resumes the packets and this causes other ports to receive
3942 # the DHCP request packet. So reset the pcap files so that its easier to test.
3943 reset_pcap_file hv1-vif1 hv1/vif1
3944 reset_pcap_file hv1-vif2 hv1/vif2
3945 rm -f 1.expected
3946 rm -f 2.expected
3947
3948 # Send DHCPREQUEST.
3949 offer_ip=`ip_to_hex 10 0 0 6`
3950 server_ip=`ip_to_hex 10 0 0 1`
3951 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3952 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3953
3954 # NXT_RESUMEs should be 2.
3955 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3956
3957 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3958 cat 2.expected | cut -c -48 > expout
3959 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3960 # Skipping the IPv4 checksum.
3961 cat 2.expected | cut -c 53- > expout
3962 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3963
3964 reset_pcap_file hv1-vif1 hv1/vif1
3965 reset_pcap_file hv1-vif2 hv1/vif2
3966 rm -f 1.expected
3967 rm -f 2.expected
3968
3969 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3970 # but should be resumed without the reply.
3971 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3972 # one from ovn-controller and the other from "ovs-ofctl resume."
3973 offer_ip=0
3974 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
3975
3976 # NXT_RESUMEs should be 3.
3977 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3978
3979 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
3980 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
3981
3982 reset_pcap_file hv1-vif1 hv1/vif1
3983 reset_pcap_file hv1-vif2 hv1/vif2
3984 rm -f 1.expected
3985 rm -f 2.expected
3986
3987 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3988 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3989
3990 test_dhcp 3 f00000000003 01 0 4 0
3991
3992 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3993 # this lport.
3994 test_dhcp 4 f00000000004 01 0 3 0
3995
3996 # NXT_RESUMEs should be 3.
3997 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3998
3999 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4000 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4001
4002 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4003 offer_ip=`ip_to_hex 10 0 0 6`
4004 server_ip=`ip_to_hex 10 0 0 1`
4005 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4006 src_ip=$offer_ip
4007 dst_ip=$server_ip
4008 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4009
4010 # NXT_RESUMEs should be 4.
4011 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4012
4013 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4014 cat 2.expected | cut -c -48 > expout
4015 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4016 # Skipping the IPv4 checksum.
4017 cat 2.expected | cut -c 53- > expout
4018 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4019
4020 reset_pcap_file hv1-vif1 hv1/vif1
4021 reset_pcap_file hv1-vif2 hv1/vif2
4022 rm -f 1.expected
4023 rm -f 2.expected
4024
4025 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4026 offer_ip=`ip_to_hex 10 0 0 6`
4027 server_ip=`ip_to_hex 10 0 0 1`
4028 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4029 src_ip=$offer_ip
4030 dst_ip=`ip_to_hex 255 255 255 255`
4031 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4032
4033 # NXT_RESUMEs should be 5.
4034 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4035
4036 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4037 cat 2.expected | cut -c -48 > expout
4038 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4039 # Skipping the IPv4 checksum.
4040 cat 2.expected | cut -c 53- > expout
4041 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4042
4043 reset_pcap_file hv1-vif1 hv1/vif1
4044 reset_pcap_file hv1-vif2 hv1/vif2
4045 rm -f 1.expected
4046 rm -f 2.expected
4047
4048 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4049 # The packet should not be received by ovn-controller.
4050 src_ip=`ip_to_hex 10 0 0 6`
4051 dst_ip=`ip_to_hex 10 0 0 4`
4052 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4053
4054 # NXT_RESUMEs should be 5.
4055 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4056
4057 # vif1-tx.pcap should have received the DHCPv4 request packet
4058 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4059
4060 as hv1
4061 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4062 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4063 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4064
4065 as ovn-sb
4066 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4067
4068 as ovn-nb
4069 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4070
4071 as northd
4072 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4073
4074 as main
4075 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4076 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4077
4078 AT_CLEANUP
4079
4080 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4081 AT_SKIP_IF([test $HAVE_PYTHON = no])
4082 ovn_start
4083
4084 ovn-nbctl ls-add ls1
4085 ovn-nbctl lsp-add ls1 ls1-lp1 \
4086 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4087
4088 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4089
4090 ovn-nbctl lsp-add ls1 ls1-lp2 \
4091 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4092
4093 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4094
4095 ovn-nbctl lsp-add ls1 ls1-lp3 \
4096 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4097
4098 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4099
4100 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4101 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4102
4103 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4104 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4105
4106 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4107 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4108
4109 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4110
4111 ovn-nbctl ls-add ls2
4112 ovn-nbctl lsp-add ls2 ls2-lp1 \
4113 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4114 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4115 ovn-nbctl lsp-add ls2 ls2-lp2 \
4116 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4117 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4118
4119 net_add n1
4120 sim_add hv1
4121
4122 as hv1
4123 ovs-vsctl add-br br-phys
4124 ovn_attach n1 br-phys 192.168.0.1
4125 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4126 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4127 options:tx_pcap=hv1/vif1-tx.pcap \
4128 options:rxq_pcap=hv1/vif1-rx.pcap \
4129 ofport-request=1
4130
4131 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4132 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4133 options:tx_pcap=hv1/vif2-tx.pcap \
4134 options:rxq_pcap=hv1/vif2-rx.pcap \
4135 ofport-request=2
4136
4137 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4138 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4139 options:tx_pcap=hv1/vif3-tx.pcap \
4140 options:rxq_pcap=hv1/vif3-rx.pcap \
4141 ofport-request=3
4142
4143 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4144 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4145 options:tx_pcap=hv1/vif4-tx.pcap \
4146 options:rxq_pcap=hv1/vif4-rx.pcap \
4147 ofport-request=4
4148
4149 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4150 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4151 options:tx_pcap=hv1/vif5-tx.pcap \
4152 options:rxq_pcap=hv1/vif5-rx.pcap \
4153 ofport-request=5
4154
4155 ovn_populate_arp
4156
4157 sleep 2
4158
4159 trim_zeros() {
4160 sed 's/\(00\)\{1,\}$//'
4161 }
4162
4163 # This shell function sends a DHCPv6 request packet
4164 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4165 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4166 # packet should be received twice (one from ovn-controller and the other
4167 # from the "ovs-ofctl monitor br-int resume"
4168 test_dhcpv6() {
4169 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4170 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4171 # dst ip ff02::1:2
4172 request=${request}ff020000000000000000000000010002
4173 # udp header and dhcpv6 header
4174 request=${request}02220223002affff${msg_code}010203
4175 # Client identifier
4176 request=${request}0001000a00030001${src_mac}
4177 # IA-NA (Identity Association for Non Temporary Address)
4178 request=${request}0003000c0102030400000e1000001518
4179 shift; shift; shift; shift; shift;
4180 if test $offer_ip != 0; then
4181 local server_mac=000000100001
4182 local server_lla=fe80000000000000020000fffe100001
4183 local reply_code=07
4184 if test $msg_code = 01; then
4185 reply_code=02
4186 fi
4187 local msg_len=54
4188 if test $offer_ip = 1; then
4189 msg_len=28
4190 fi
4191 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4192 # udp header and dhcpv6 header
4193 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4194 # Client identifier
4195 reply=${reply}0001000a00030001${src_mac}
4196 # IA-NA
4197 if test $offer_ip != 1; then
4198 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4199 fi
4200 # Server identifier
4201 reply=${reply}0002000a00030001${server_mac}
4202 echo $reply | trim_zeros >> $inport.expected
4203 else
4204 for outport; do
4205 echo $request | trim_zeros >> $outport.expected
4206 done
4207 fi
4208
4209 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4210 }
4211
4212 reset_pcap_file() {
4213 local iface=$1
4214 local pcap_file=$2
4215 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4216 options:rxq_pcap=dummy-rx.pcap
4217 rm -f ${pcap_file}*.pcap
4218 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4219 options:rxq_pcap=${pcap_file}-rx.pcap
4220 }
4221
4222 AT_CAPTURE_FILE([ofctl_monitor0.log])
4223 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4224 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4225
4226 echo "---------NB dump-----"
4227 ovn-nbctl show
4228 echo "---------------------"
4229 echo "---------SB dump-----"
4230 ovn-sbctl list datapath_binding
4231 echo "---------------------"
4232 ovn-sbctl list logical_flow
4233 echo "---------------------"
4234
4235 echo "---------------------"
4236 ovn-sbctl dump-flows
4237 echo "---------------------"
4238
4239 echo "------ hv1 dump ----------"
4240 as hv1 ovs-ofctl dump-flows br-int
4241
4242 src_mac=f00000000001
4243 src_lla=fe80000000000000f20000fffe000001
4244 offer_ip=ae700000000000000000000000000004
4245 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4246
4247 # NXT_RESUMEs should be 1.
4248 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4249
4250 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4251 # cat 1.expected | trim_zeros > expout
4252 cat 1.expected | cut -c -120 > expout
4253 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4254 # Skipping the UDP checksum
4255 cat 1.expected | cut -c 125- > expout
4256 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4257
4258 rm 1.expected
4259
4260 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4261 # without any modifications and the packet should be received by ls1-lp1.
4262 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4263 # resume and the other from ovs-ofctl monitor resume.
4264
4265 reset_pcap_file hv1-vif1 hv1/vif1
4266 reset_pcap_file hv1-vif2 hv1/vif2
4267
4268 src_mac=f00000000002
4269 src_lla=fe80000000000000f20000fffe000002
4270 offer_ip=ae700000000000000000000000000005
4271 # Set invalid msg_type
4272
4273 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4274
4275 # NXT_RESUMEs should be 2.
4276 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4277
4278 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4279 rm 2.packets
4280 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4281 AT_CHECK([cat 2.packets], [0], [])
4282
4283 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4284 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4285 cat 1.expected > expout
4286 AT_CHECK([cat 1.packets], [0], [expout])
4287
4288 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4289 # There should be no DHCPv6 reply from ovn-controller and the request packet
4290 # should be received by ls2-lp2.
4291
4292 src_mac=f00000000003
4293 src_lla=fe80000000000000f20000fffe000003
4294 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4295
4296 # NXT_RESUMEs should be 2 only.
4297 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4298
4299 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4300 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4301 AT_CHECK([cat 3.packets], [0], [])
4302
4303 # vif4-tx.pcap should have received the DHCPv6 request packet
4304 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4305 cat 4.expected > expout
4306 AT_CHECK([cat 4.packets], [0], [expout])
4307
4308 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4309 # The DHCPv6 reply should doesn't contian offer_ip.
4310 src_mac=f00000000022
4311 src_lla=fe80000000000000f20000fffe000022
4312 reset_pcap_file hv1-vif5 hv1/vif5
4313 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4314
4315 # NXT_RESUMEs should be 3.
4316 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4317
4318 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4319 # Skipping the UDP checksum
4320 cat 5.expected | cut -c 1-120,125- > expout
4321 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4322
4323 as hv1
4324 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4325 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4326 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4327
4328 as ovn-sb
4329 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4330
4331 as ovn-nb
4332 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4333
4334 as northd
4335 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4336
4337 as main
4338 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4339 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4340
4341 AT_CLEANUP
4342
4343 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4344 AT_SKIP_IF([test $HAVE_PYTHON = no])
4345 ovn_start
4346
4347 # Logical network:
4348 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4349 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4350 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4351 # R2 is a gateway router.
4352
4353
4354
4355 # Create two hypervisor and create OVS ports corresponding to logical ports.
4356 net_add n1
4357
4358 sim_add hv1
4359 as hv1
4360 ovs-vsctl add-br br-phys
4361 ovn_attach n1 br-phys 192.168.0.1
4362 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4363 set interface hv1-vif1 external-ids:iface-id=foo1 \
4364 options:tx_pcap=hv1/vif1-tx.pcap \
4365 options:rxq_pcap=hv1/vif1-rx.pcap \
4366 ofport-request=1
4367
4368
4369 sim_add hv2
4370 as hv2
4371 ovs-vsctl add-br br-phys
4372 ovn_attach n1 br-phys 192.168.0.2
4373 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4374 set interface hv2-vif1 external-ids:iface-id=alice1 \
4375 options:tx_pcap=hv2/vif1-tx.pcap \
4376 options:rxq_pcap=hv2/vif1-rx.pcap \
4377 ofport-request=1
4378
4379 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4380 # packets for ARP resolution (native tunneling doesn't queue packets
4381 # for ARP resolution).
4382 ovn_populate_arp
4383
4384 ovn-nbctl create Logical_Router name=R1
4385 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4386
4387 ovn-nbctl ls-add foo
4388 ovn-nbctl ls-add alice
4389 ovn-nbctl ls-add join
4390
4391 # Connect foo to R1
4392 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4393 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4394 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4395
4396 # Connect alice to R2
4397 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4398 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4399 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4400
4401 # Connect R1 to join
4402 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4403 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4404 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4405
4406 # Connect R2 to join
4407 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4408 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4409 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4410
4411
4412 #install static routes
4413 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4414 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4415 R1 static_routes @lrt
4416
4417 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4418 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4419 R2 static_routes @lrt
4420
4421 # Create logical port foo1 in foo
4422 ovn-nbctl lsp-add foo foo1 \
4423 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4424
4425 # Create logical port alice1 in alice
4426 ovn-nbctl lsp-add alice alice1 \
4427 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4428
4429
4430 # Allow some time for ovn-northd and ovn-controller to catch up.
4431 # XXX This should be more systematic.
4432 sleep 2
4433
4434 ip_to_hex() {
4435 printf "%02x%02x%02x%02x" "$@"
4436 }
4437
4438 # Send ip packets between foo1 and alice1
4439 src_mac="f00000010203"
4440 dst_mac="000001010203"
4441 src_ip=`ip_to_hex 192 168 1 2`
4442 dst_ip=`ip_to_hex 172 16 1 2`
4443 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4444
4445 echo "---------NB dump-----"
4446 ovn-nbctl show
4447 echo "---------------------"
4448 ovn-nbctl list logical_router
4449 echo "---------------------"
4450 ovn-nbctl list logical_router_port
4451 echo "---------------------"
4452
4453 echo "---------SB dump-----"
4454 ovn-sbctl list datapath_binding
4455 echo "---------------------"
4456 ovn-sbctl list port_binding
4457 echo "---------------------"
4458 ovn-sbctl dump-flows
4459 echo "---------------------"
4460 ovn-sbctl list chassis
4461 ovn-sbctl list encap
4462 echo "---------------------"
4463
4464 # Packet to Expect at alice1
4465 src_mac="000002010203"
4466 dst_mac="f00000010204"
4467 src_ip=`ip_to_hex 192 168 1 2`
4468 dst_ip=`ip_to_hex 172 16 1 2`
4469 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4470
4471
4472 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4473 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4474
4475 echo "------ hv1 dump after packet 1 ----------"
4476 as hv1 ovs-ofctl show br-int
4477 as hv1 ovs-ofctl dump-flows br-int
4478 echo "------ hv2 dump after packet 1 ----------"
4479 as hv2 ovs-ofctl show br-int
4480 as hv2 ovs-ofctl dump-flows br-int
4481 echo "----------------------------"
4482
4483 echo $expected > expected
4484 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4485
4486 # Delete the router and re-create it. Things should work as before.
4487 ovn-nbctl lr-del R2
4488 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4489 # Connect alice to R2
4490 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4491 # Connect R2 to join
4492 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4493
4494 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4495 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4496 R2 static_routes @lrt
4497
4498 # Wait for ovn-controller to catch up.
4499 sleep 1
4500
4501 # Send the packet again.
4502 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4503
4504 echo "------ hv1 dump after packet 2 ----------"
4505 as hv1 ovs-ofctl show br-int
4506 as hv1 ovs-ofctl dump-flows br-int
4507 echo "------ hv2 dump after packet 2 ----------"
4508 as hv2 ovs-ofctl show br-int
4509 as hv2 ovs-ofctl dump-flows br-int
4510 echo "----------------------------"
4511
4512 echo $expected >> expected
4513 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4514
4515 OVN_CLEANUP([hv1],[hv2])
4516
4517 AT_CLEANUP
4518
4519 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4520 AT_KEYWORDS([router-icmp-reply])
4521 AT_SKIP_IF([test $HAVE_PYTHON = no])
4522 ovn_start
4523
4524 # Logical network:
4525 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4526 # and has switch ls2 (172.16.1.0/24) connected to it.
4527
4528 ovn-nbctl lr-add R1
4529
4530 ovn-nbctl ls-add ls1
4531 ovn-nbctl ls-add ls2
4532
4533 # Connect ls1 to R1
4534 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4535 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4536 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4537
4538 # Connect ls2 to R1
4539 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4540 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4541 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4542
4543 # Create logical port ls1-lp1 in ls1
4544 ovn-nbctl lsp-add ls1 ls1-lp1 \
4545 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4546
4547 # Create logical port ls2-lp1 in ls2
4548 ovn-nbctl lsp-add ls2 ls2-lp1 \
4549 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4550
4551 # Create one hypervisor and create OVS ports corresponding to logical ports.
4552 net_add n1
4553
4554 sim_add hv1
4555 as hv1
4556 ovs-vsctl add-br br-phys
4557 ovn_attach n1 br-phys 192.168.0.1
4558 ovs-vsctl -- add-port br-int vif1 -- \
4559 set interface vif1 external-ids:iface-id=ls1-lp1 \
4560 options:tx_pcap=hv1/vif1-tx.pcap \
4561 options:rxq_pcap=hv1/vif1-rx.pcap \
4562 ofport-request=1
4563
4564 ovs-vsctl -- add-port br-int vif2 -- \
4565 set interface vif2 external-ids:iface-id=ls2-lp1 \
4566 options:tx_pcap=hv1/vif2-tx.pcap \
4567 options:rxq_pcap=hv1/vif2-rx.pcap \
4568 ofport-request=1
4569
4570
4571 # Allow some time for ovn-northd and ovn-controller to catch up.
4572 # XXX This should be more systematic.
4573 sleep 1
4574
4575
4576 ip_to_hex() {
4577 printf "%02x%02x%02x%02x" "$@"
4578 }
4579 for i in 1 2; do
4580 : > vif$i.expected
4581 done
4582 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4583 #
4584 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4585 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4586 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4587 # provided, then it should be the ip and icmp checksums of the packet
4588 # responded; otherwise, no reply is expected.
4589 # In the absence of an ip checksum calculation helpers, this relies
4590 # on the caller to provide the checksums for the ip and icmp headers.
4591 # XXX This should be more systematic.
4592 #
4593 # INPORT is an lport number, e.g. 11 for vif11.
4594 # ETH_SRC and ETH_DST are each 12 hex digits.
4595 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4596 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4597 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4598 test_ipv4_icmp_request() {
4599 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4600 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4601 shift; shift; shift; shift; shift; shift; shift
4602 shift; shift
4603
4604 # Use ttl to exercise section 4.2.2.9 of RFC1812
4605 local ip_ttl=01
4606 local icmp_id=5fbf
4607 local icmp_seq=0001
4608 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4609 local icmp_type_code_request=0800
4610 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4611 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4612
4613 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4614 if test X$exp_icmp_chksum != X; then
4615 # Expect to receive the reply, if any. In same port where packet was sent.
4616 # Note: src and dst fields are expected to be reversed.
4617 local icmp_type_code_response=0000
4618 local reply_icmp_ttl=fe
4619 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4620 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4621 echo $reply >> vif$inport.expected
4622 fi
4623 }
4624
4625 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4626 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4627 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4628 l1_ip=$(ip_to_hex 192 168 1 2)
4629 l2_ip=$(ip_to_hex 172 16 1 2)
4630
4631 # Ping router ip address that is on same subnet as the logical port
4632 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4633 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4634
4635 # Ping router ip address that is on the other side of the logical ports
4636 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4637 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4638
4639 echo "---------NB dump-----"
4640 ovn-nbctl show
4641 echo "---------------------"
4642 ovn-nbctl list logical_router
4643 echo "---------------------"
4644 ovn-nbctl list logical_router_port
4645 echo "---------------------"
4646
4647 echo "---------SB dump-----"
4648 ovn-sbctl list datapath_binding
4649 echo "---------------------"
4650 ovn-sbctl list logical_flow
4651 echo "---------------------"
4652
4653 echo "------ hv1 dump ----------"
4654 as hv1 ovs-ofctl dump-flows br-int
4655
4656 # Now check the packets actually received against the ones expected.
4657 for inport in 1 2; do
4658 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4659 done
4660
4661 OVN_CLEANUP([hv1])
4662
4663 AT_CLEANUP
4664
4665 # 1 hypervisor, 1 port
4666 # make sure that the port state is properly set to up and back down
4667 # when created and deleted.
4668 AT_SETUP([ovn -- port state up and down])
4669 ovn_start
4670
4671 ovn-nbctl ls-add ls1
4672 ovn-nbctl lsp-add ls1 lp1
4673 ovn-nbctl lsp-set-addresses lp1 unknown
4674
4675 net_add n1
4676 sim_add hv1
4677 as hv1 ovs-vsctl add-br br-phys
4678 as hv1 ovn_attach n1 br-phys 192.168.0.1
4679
4680 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4681 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4682
4683 as hv1 ovs-vsctl del-port br-int vif1
4684 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4685
4686 OVN_CLEANUP([hv1])
4687
4688 AT_CLEANUP
4689
4690 # 1 hypervisor, 1 port
4691 # make sure that the OF rules created to support a datapath are added/cleared
4692 # when logical switch is created and removed.
4693 AT_SETUP([ovn -- datapath rules added/removed])
4694 AT_KEYWORDS([cleanup])
4695 ovn_start
4696
4697 net_add n1
4698 sim_add hv1
4699 as hv1 ovs-vsctl add-br br-phys
4700 as hv1 ovn_attach n1 br-phys 192.168.0.1
4701
4702 # This shell function checks if OF rules in br-int have clauses
4703 # related to OVN datapaths. The caller determines if it should find
4704 # a match in the output, or not.
4705 #
4706 # EXPECT_DATAPATH param determines whether flows that refer to
4707 # datapath to should be present or not. 0 means
4708 # they should not be.
4709 # STAGE_INFO param is a simple string to help identify the stage
4710 # in the test when this function was invoked.
4711 test_datapath_in_of_rules() {
4712 local expect_datapath=$1 stage_info=$2
4713 echo "------ ovn-nbctl show ${stage_info} ------"
4714 ovn-nbctl show
4715 echo "------ ovn-sbctl show ${stage_info} ------"
4716 ovn-sbctl show
4717 echo "------ OF rules ${stage_info} ------"
4718 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4719 # if there is a datapath mentioned in the output, check for the
4720 # magic keyword that represents one, based on the exit status of
4721 # a quiet grep
4722 if test $expect_datapath != 0; then
4723 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4724 else
4725 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4726 fi
4727 }
4728
4729 test_datapath_in_of_rules 0 "before ls+port create"
4730
4731 ovn-nbctl ls-add ls1
4732 ovn-nbctl lsp-add ls1 lp1
4733 ovn-nbctl lsp-set-addresses lp1 unknown
4734
4735 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4736 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4737
4738 test_datapath_in_of_rules 1 "after port is bound"
4739
4740 as hv1 ovs-vsctl del-port br-int vif1
4741 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4742
4743 ovn-nbctl lsp-set-addresses lp1
4744 ovn-nbctl lsp-del lp1
4745 ovn-nbctl ls-del ls1
4746
4747 # wait for earlier changes to take effect
4748 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4749
4750 # ensure OF rules are no longer present. There used to be a bug here.
4751 test_datapath_in_of_rules 0 "after lport+ls removal"
4752
4753 OVN_CLEANUP([hv1])
4754
4755 AT_CLEANUP
4756
4757 AT_SETUP([ovn -- nd_na ])
4758 AT_SKIP_IF([test $HAVE_PYTHON = no])
4759 ovn_start
4760
4761 #TODO: since patch port for IPv6 logical router port is not ready not,
4762 # so we are not going to test vifs on different lswitches cases. Try
4763 # to update for that once relevant stuff implemented.
4764
4765 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4766 # with. NS packet we test, from one VIF for another VIF, will be replied
4767 # by local ovn-controller, but not by target VIF.
4768
4769 # Create hypervisors and logical switch lsw0.
4770 ovn-nbctl ls-add lsw0
4771 net_add n1
4772 sim_add hv1
4773 as hv1
4774 ovs-vsctl add-br br-phys
4775 ovn_attach n1 br-phys 192.168.0.2
4776
4777 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4778 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
4779 ovn-nbctl lsp-add lsw0 lp1
4780 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4781 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"
4782
4783 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4784 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
4785 ovn-nbctl lsp-add lsw0 lp2
4786 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4787 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"
4788
4789 # Add ACL rule for ICMPv6 on lsw0
4790 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4791 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4792 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4793
4794 # Allow some time for ovn-northd and ovn-controller to catch up.
4795 # XXX This should be more systematic.
4796 sleep 1
4797
4798 # Given the name of a logical port, prints the name of the hypervisor
4799 # on which it is located.
4800 vif_to_hv() {
4801 echo hv1${1%?}
4802 }
4803 for i in 1 2; do
4804 : > $i.expected
4805 done
4806
4807 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4808 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4809 # vif2 will not receive NS packet, since ovn-controller will reply for it.
4810 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4811 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4812
4813 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
4814 echo $na_packet >> 1.expected
4815
4816 echo "------ hv1 dump ------"
4817 as hv1 ovs-vsctl show
4818 as hv1 ovs-ofctl -O OpenFlow13 show br-int
4819 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4820
4821 for i in 1 2; do
4822 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
4823 done
4824
4825 OVN_CLEANUP([hv1])
4826
4827 AT_CLEANUP
4828
4829 AT_SETUP([ovn -- address sets modification/removal smoke test])
4830 ovn_start
4831
4832 net_add n1
4833
4834 sim_add hv1
4835 as hv1
4836 ovs-vsctl add-br br-phys
4837 ovn_attach n1 br-phys 192.168.0.1
4838
4839 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4840 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4841 ovn-nbctl destroy Address_Set $row
4842
4843 sleep 1
4844
4845 # A bug previously existed in the address set support code
4846 # that caused ovn-controller to crash after an address set
4847 # was updated and then removed. This test case ensures
4848 # that ovn-controller is at least still running after
4849 # creating, updating, and deleting an address set.
4850 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4851
4852 OVN_CLEANUP([hv1])
4853
4854 AT_CLEANUP
4855
4856 AT_SETUP([ovn -- ipam])
4857 AT_SKIP_IF([test $HAVE_PYTHON = no])
4858 ovn_start
4859
4860 # Add a port to a switch that does not have a subnet set, then set the
4861 # subnet which should result in an address being allocated for the port.
4862 ovn-nbctl ls-add sw0
4863 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
4864 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
4865 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4866 ["0a:00:00:00:00:01 192.168.1.2"
4867 ])
4868
4869 # Add 9 more ports to sw0, addresses should all be unique.
4870 for n in `seq 1 9`; do
4871 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
4872 done
4873 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4874 ["0a:00:00:00:00:02 192.168.1.3"
4875 ])
4876 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4877 ["0a:00:00:00:00:03 192.168.1.4"
4878 ])
4879 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4880 ["0a:00:00:00:00:04 192.168.1.5"
4881 ])
4882 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4883 ["0a:00:00:00:00:05 192.168.1.6"
4884 ])
4885 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4886 ["0a:00:00:00:00:06 192.168.1.7"
4887 ])
4888 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4889 ["0a:00:00:00:00:07 192.168.1.8"
4890 ])
4891 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4892 ["0a:00:00:00:00:08 192.168.1.9"
4893 ])
4894 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4895 ["0a:00:00:00:00:09 192.168.1.10"
4896 ])
4897 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4898 ["0a:00:00:00:00:0a 192.168.1.11"
4899 ])
4900
4901 # Trying similar tests with a second switch. MAC addresses should be unique
4902 # across both switches but IP's only need to be unique within the same switch.
4903 ovn-nbctl ls-add sw1
4904 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
4905 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
4906 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4907 ["0a:00:00:00:00:0b 192.168.1.2"
4908 ])
4909
4910 for n in `seq 11 19`; do
4911 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
4912 done
4913 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4914 ["0a:00:00:00:00:0c 192.168.1.3"
4915 ])
4916 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4917 ["0a:00:00:00:00:0d 192.168.1.4"
4918 ])
4919 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4920 ["0a:00:00:00:00:0e 192.168.1.5"
4921 ])
4922 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4923 ["0a:00:00:00:00:0f 192.168.1.6"
4924 ])
4925 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4926 ["0a:00:00:00:00:10 192.168.1.7"
4927 ])
4928 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4929 ["0a:00:00:00:00:11 192.168.1.8"
4930 ])
4931 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4932 ["0a:00:00:00:00:12 192.168.1.9"
4933 ])
4934 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4935 ["0a:00:00:00:00:13 192.168.1.10"
4936 ])
4937 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4938 ["0a:00:00:00:00:14 192.168.1.11"
4939 ])
4940
4941 # Change a port's address to test for multiple ip's for a single address entry
4942 # and addresses set by the user.
4943 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
4944 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
4945 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4946 ["0a:00:00:00:00:16 192.168.1.13"
4947 ])
4948
4949 # Test for logical router port address management.
4950 ovn-nbctl create Logical_Router name=R1
4951 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4952 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4953 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4954 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
4955 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
4956 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4957 ["0a:00:00:00:00:18 192.168.1.15"
4958 ])
4959
4960 # Test for address reuse after logical port is deleted.
4961 ovn-nbctl lsp-del p0
4962 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
4963 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4964 ["0a:00:00:00:00:19 192.168.1.2"
4965 ])
4966
4967 # Test for multiple addresses to one logical port.
4968 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4969 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
4970 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
4971 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4972 ["0a:00:00:00:00:1c 192.168.1.16"
4973 ])
4974
4975 # Test for exhausting subnet address space.
4976 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
4977 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
4978 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4979 ["0a:00:00:00:00:1d 172.16.1.2"
4980 ])
4981
4982 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
4983 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
4984 ["0a:00:00:00:00:1e"
4985 ])
4986
4987 # Test that address management does not add duplicate MAC for lsp/lrp peers.
4988 ovn-nbctl create Logical_Router name=R2
4989 ovn-nbctl ls-add sw3
4990 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
4991 "0a:00:00:00:00:1f"
4992 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4993 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4994 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4995 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
4996 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
4997 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4998 ["0a:00:00:00:00:20 192.168.1.17"
4999 ])
5000
5001 # Test static MAC address with dynamically allocated IP
5002 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5003 "fe:dc:ba:98:76:54 dynamic"
5004 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5005 ["fe:dc:ba:98:76:54 192.168.1.18"
5006 ])
5007
5008 # Update the static MAC address with dynamically allocated IP and check
5009 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5010 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5011 ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5012
5013 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5014 ["fe:dc:ba:98:76:55 192.168.1.18"
5015 ])
5016
5017 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5018 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5019 ["fe:dc:ba:98:76:55 192.168.1.18"
5020 ])
5021
5022 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5023 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5024 ["fe:dc:ba:98:76:56 192.168.1.18"
5025 ])
5026
5027
5028 # Test the exclude_ips from the IPAM list
5029 ovn-nbctl --wait=sb set logical_switch sw0 \
5030 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5031
5032 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5033 "dynamic"
5034 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5035 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5036 ["0a:00:00:00:00:21 192.168.1.20"
5037 ])
5038
5039 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5040 "dynamic"
5041 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5042 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5043 ["0a:00:00:00:00:22 192.168.1.22"
5044 ])
5045
5046 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5047 "dynamic"
5048 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5049 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5050 ["0a:00:00:00:00:23 192.168.1.51"
5051 ])
5052
5053 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5054 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5055 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5056 "dynamic"
5057 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5058 ["0a:00:00:00:00:24 192.168.1.19"
5059 ])
5060
5061 # Set invalid data in exclude_ips list. It should be ignored.
5062 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5063 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5064 "dynamic"
5065 # 192.168.1.21 should be assigned as that's the next free one.
5066 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5067 ["0a:00:00:00:00:25 192.168.1.21"
5068 ])
5069
5070 # Clear the dynamic addresses assignment request.
5071 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5072 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5073 [[[]]
5074 ])
5075
5076 # Set IPv6 prefix
5077 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5078 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5079 "dynamic"
5080
5081 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5082 # - aef0::800:ff:fe00:26 (EUI64)
5083 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5084 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5085 ])
5086
5087 ovn-nbctl --wait=sb ls-add sw4
5088 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5089 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5090 "dynamic"
5091
5092 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5093 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5094 ])
5095
5096 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5097 "f0:00:00:00:10:12 dynamic"
5098
5099 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5100 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5101 ])
5102
5103 # Clear the other_config for sw4. No dynamic ip should be assigned.
5104 ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5105 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5106 "dynamic"
5107
5108 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5109 [[[]]
5110 ])
5111
5112 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5113 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5114 -- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5115
5116 # Now p40 should be assigned with dynamic addresses.
5117 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5118 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5119 ])
5120
5121 ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5122 "dynamic"
5123 # p41 should not have IPv4 address (as the pool is exhausted).
5124 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5125 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5126 ])
5127
5128 as ovn-sb
5129 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5130
5131 as ovn-nb
5132 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5133
5134 as northd
5135 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5136
5137 AT_CLEANUP
5138
5139 AT_SETUP([ovn -- ipam connectivity])
5140 AT_SKIP_IF([test $HAVE_PYTHON = no])
5141 ovn_start
5142
5143 ovn-nbctl lr-add R1
5144
5145 # Test for a ping using dynamically allocated addresses.
5146 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5147 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5148
5149 # Connect foo to R1
5150 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5151 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5152 options:router-port=foo \
5153 -- lsp-set-addresses rp-foo router
5154
5155 # Connect alice to R1
5156 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5157 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5158 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5159
5160 # Create logical port foo1 in foo
5161 ovn-nbctl --wait=sb lsp-add foo foo1 \
5162 -- lsp-set-addresses foo1 "dynamic"
5163 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])
5164
5165 # Create logical port alice1 in alice
5166 ovn-nbctl --wait=sb lsp-add alice alice1 \
5167 -- lsp-set-addresses alice1 "dynamic"
5168 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5169
5170 # Create logical port foo2 in foo
5171 ovn-nbctl --wait=sb lsp-add foo foo2 \
5172 -- lsp-set-addresses foo2 "dynamic"
5173 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5174
5175 # Create a hypervisor and create OVS ports corresponding to logical ports.
5176 net_add n1
5177
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 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5183 set interface hv1-vif1 external-ids:iface-id=foo1 \
5184 options:tx_pcap=hv1/vif1-tx.pcap \
5185 options:rxq_pcap=hv1/vif1-rx.pcap \
5186 ofport-request=1
5187
5188 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5189 set interface hv1-vif2 external-ids:iface-id=foo2 \
5190 options:tx_pcap=hv1/vif2-tx.pcap \
5191 options:rxq_pcap=hv1/vif2-rx.pcap \
5192 ofport-request=2
5193
5194 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5195 set interface hv1-vif3 external-ids:iface-id=alice1 \
5196 options:tx_pcap=hv1/vif3-tx.pcap \
5197 options:rxq_pcap=hv1/vif3-rx.pcap \
5198 ofport-request=3
5199
5200 # Allow some time for ovn-northd and ovn-controller to catch up.
5201 # XXX This should be more systematic.
5202 sleep 1
5203
5204 ip_to_hex() {
5205 printf "%02x%02x%02x%02x" "$@"
5206 }
5207
5208 # Send ip packets between foo1 and foo2
5209 src_mac="0a0000000001"
5210 dst_mac="0a0000000003"
5211 src_ip=`ip_to_hex 192 168 1 2`
5212 dst_ip=`ip_to_hex 192 168 1 3`
5213 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5214 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5215
5216 # Send ip packets between foo1 and alice1
5217 src_mac="0a0000000001"
5218 dst_mac="000000010203"
5219 src_ip=`ip_to_hex 192 168 1 2`
5220 dst_ip=`ip_to_hex 192 168 2 2`
5221 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5222 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5223
5224 echo "---------NB dump-----"
5225 ovn-nbctl show
5226 echo "---------------------"
5227 ovn-nbctl list logical_router
5228 echo "---------------------"
5229 ovn-nbctl list logical_router_port
5230 echo "---------------------"
5231
5232 echo "---------SB dump-----"
5233 ovn-sbctl list datapath_binding
5234 echo "---------------------"
5235 ovn-sbctl list port_binding
5236 echo "---------------------"
5237
5238 echo "------ hv1 dump ----------"
5239 as hv1 ovs-ofctl dump-flows br-int
5240
5241 # Packet to Expect at foo2
5242 src_mac="0a0000000001"
5243 dst_mac="0a0000000003"
5244 src_ip=`ip_to_hex 192 168 1 2`
5245 dst_ip=`ip_to_hex 192 168 1 3`
5246 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5247
5248 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5249 echo $expected > expout
5250 AT_CHECK([cat received1.packets], [0], [expout])
5251
5252 # Packet to Expect at alice1
5253 src_mac="000000010204"
5254 dst_mac="0a0000000002"
5255 src_ip=`ip_to_hex 192 168 1 2`
5256 dst_ip=`ip_to_hex 192 168 2 2`
5257 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5258
5259 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5260 echo $expected > expout
5261 AT_CHECK([cat received2.packets], [0], [expout])
5262
5263 OVN_CLEANUP([hv1])
5264
5265 AT_CLEANUP
5266
5267 AT_SETUP([ovn -- ovs-vswitchd restart])
5268 AT_KEYWORDS([vswitchd])
5269 AT_SKIP_IF([test $HAVE_PYTHON = no])
5270 ovn_start
5271
5272 ovn-nbctl ls-add ls1
5273
5274 ovn-nbctl lsp-add ls1 ls1-lp1 \
5275 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5276
5277 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5278
5279 net_add n1
5280 sim_add hv1
5281
5282 as hv1
5283 ovs-vsctl add-br br-phys
5284 ovn_attach n1 br-phys 192.168.0.1
5285 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5286 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5287 options:tx_pcap=hv1/vif1-tx.pcap \
5288 options:rxq_pcap=hv1/vif1-rx.pcap \
5289 ofport-request=1
5290
5291 ovn_populate_arp
5292 sleep 2
5293
5294 as hv1 ovs-vsctl show
5295
5296 echo "---------------------"
5297 ovn-sbctl dump-flows
5298 echo "---------------------"
5299
5300 echo "------ hv1 dump ----------"
5301 as hv1 ovs-ofctl dump-flows br-int
5302 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5303
5304 echo "Total flows before vswitchd restart = " $total_flows
5305
5306 # Code taken from ovs-save utility
5307 save_flows () {
5308 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5309 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5310 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5311 echo "EOF" >> restore_flows.sh
5312 }
5313
5314 restart_vswitchd () {
5315 restore_flows=$1
5316
5317 if test $restore_flows = true; then
5318 save_flows
5319 fi
5320
5321 as hv1
5322 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5323
5324 if test $restore_flows = true; then
5325 as hv1
5326 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5327 fi
5328
5329 as hv1
5330 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5331 ovs-ofctl dump-flows br-int
5332
5333 if test $restore_flows = true; then
5334 sh ./restore_flows.sh
5335 echo "Flows after restore"
5336 as hv1
5337 ovs-ofctl dump-flows br-int
5338 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5339 flow-restore-wait="true"
5340 fi
5341 }
5342
5343 # Save the flows, restart vswitchd and restore the flows
5344 restart_vswitchd true
5345 OVS_WAIT_UNTIL([
5346 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5347 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5348 test "${total_flows}" = "${total_flows_after_restart}"
5349 ])
5350
5351 # Restart vswitchd without restoring
5352 restart_vswitchd false
5353 OVS_WAIT_UNTIL([
5354 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5355 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5356 test "${total_flows}" = "${total_flows_after_restart}"
5357 ])
5358
5359 OVN_CLEANUP([hv1])
5360 AT_CLEANUP
5361
5362 AT_SETUP([ovn -- send arp for nexthop])
5363 AT_SKIP_IF([test $HAVE_PYTHON = no])
5364 ovn_start
5365
5366 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5367
5368 # Create logical switches
5369 ovn-nbctl ls-add ls1
5370 ovn-nbctl ls-add ls2
5371
5372 # Create router
5373 ovn-nbctl create Logical_Router name=lr0
5374
5375 # Add router ls1p1 port to gateway router
5376 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5377 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5378 type=router options:router-port=lrp-ls1lp1 \
5379 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5380
5381 # Add router ls2p2 port to gateway router
5382 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5383 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5384 type=router options:router-port=lrp-ls2lp1 \
5385 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5386
5387 # Set default gateway (nexthop) to 192.168.1.254
5388 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5389
5390 # Create logical port ls1lp2 in ls1
5391 ovn-nbctl lsp-add ls1 ls1lp2 \
5392 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5393
5394 # Create logical port ls2lp2 in ls2
5395 ovn-nbctl lsp-add ls2 ls2lp2 \
5396 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5397
5398 net_add n1
5399 sim_add hv1
5400 as hv1
5401 ovs-vsctl add-br br-phys
5402 ovn_attach n1 br-phys 192.168.0.1
5403 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5404 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5405 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5406 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5407 ofport-request=1
5408 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5409 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5410 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5411 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5412 ofport-request=2
5413
5414 # Allow some time for ovn-northd and ovn-controller to catch up.
5415 # XXX This should be more systematic.
5416 sleep 1
5417
5418 echo "---------NB dump-----"
5419 ovn-nbctl show
5420 echo "---------------------"
5421 ovn-nbctl list logical_router
5422 echo "---------------------"
5423 ovn-nbctl list logical_router_port
5424 echo "---------------------"
5425
5426 echo "---------SB dump-----"
5427 ovn-sbctl list datapath_binding
5428 echo "---------------------"
5429 ovn-sbctl list port_binding
5430 echo "---------------------"
5431 ovn-sbctl dump-flows
5432 echo "---------------------"
5433 ovn-sbctl list chassis
5434 ovn-sbctl list encap
5435 echo "---------------------"
5436
5437 echo "------Flows dump-----"
5438 as hv1
5439 ovs-ofctl dump-flows
5440 echo "---------------------"
5441
5442 ip_to_hex() {
5443 printf "%02x%02x%02x%02x" "$@"
5444 }
5445
5446 src_mac="f00000000003"
5447 dst_mac="f00000000001"
5448 src_ip=`ip_to_hex 192 168 0 2`
5449 dst_ip=`ip_to_hex 8 8 8 8`
5450 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5451
5452 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5453 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5454
5455 trim_zeros() {
5456 sed 's/\(00\)\{1,\}$//'
5457 }
5458
5459 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5460 # not 8.8.8.8
5461
5462 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5463 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5464 echo $expected > expout
5465 AT_CHECK([cat packets], [0], [expout])
5466 cat packets
5467
5468 OVN_CLEANUP([hv1])
5469
5470 AT_CLEANUP
5471
5472 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5473 AT_SKIP_IF([test $HAVE_PYTHON = no])
5474 ovn_start
5475 # Create logical switch
5476 ovn-nbctl ls-add ls0
5477 # Create gateway router
5478 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5479 # Add router port to gateway router
5480 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5481 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5482 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5483 # Add nat-address option
5484 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5485
5486 net_add n1
5487 sim_add hv1
5488 as hv1
5489 ovs-vsctl \
5490 -- add-br br-phys \
5491 -- add-br br-eth0
5492
5493 ovn_attach n1 br-phys 192.168.0.1
5494
5495 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5496 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])
5497
5498 # Create a localnet port.
5499 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5500 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5501 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5502 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5503
5504
5505 # Wait for packet to be received.
5506 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5507 trim_zeros() {
5508 sed 's/\(00\)\{1,\}$//'
5509 }
5510 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5511 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5512 echo $expected > expout
5513 AT_CHECK([sort packets], [0], [expout])
5514 cat packets
5515
5516 OVN_CLEANUP([hv1])
5517
5518 AT_CLEANUP
5519
5520 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5521 AT_SKIP_IF([test $HAVE_PYTHON = no])
5522 ovn_start
5523 # Create logical switch
5524 ovn-nbctl ls-add ls0
5525 # Create gateway router
5526 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5527 # Add router port to gateway router
5528 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5529 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5530 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5531 # Add nat-address option
5532 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5533 # Add NAT rules
5534 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5535 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5536 # Add load balancers
5537 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5538 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5539 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5540 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5541
5542 net_add n1
5543 sim_add hv1
5544 as hv1
5545 ovs-vsctl \
5546 -- add-br br-phys \
5547 -- add-br br-eth0
5548
5549 ovn_attach n1 br-phys 192.168.0.1
5550
5551 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5552 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])
5553
5554 # Create a localnet port.
5555 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5556 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5557 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5558 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5559
5560
5561 # Wait for packet to be received.
5562 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5563 trim_zeros() {
5564 sed 's/\(00\)\{1,\}$//'
5565 }
5566 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5567 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5568 echo $expected > expout
5569 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5570 echo $expected >> expout
5571 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5572 echo $expected >> expout
5573 AT_CHECK([sort packets], [0], [expout])
5574 cat packets
5575
5576 OVN_CLEANUP([hv1])
5577
5578 AT_CLEANUP
5579
5580 AT_SETUP([ovn -- delete mac bindings])
5581 ovn_start
5582 net_add n1
5583 sim_add hv1
5584 as hv1
5585 ovs-vsctl -- add-br br-phys
5586 ovn_attach n1 br-phys 192.168.0.1
5587 # Create logical switch ls0
5588 ovn-nbctl ls-add ls0
5589 # Create ports lp0, lp1 in ls0
5590 ovn-nbctl lsp-add ls0 lp0
5591 ovn-nbctl lsp-add ls0 lp1
5592 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5593 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5594 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5595 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5596 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5597 ovn-sbctl find MAC_Binding
5598 # Delete port lp0 and check that its MAC_Binding is deleted.
5599 ovn-nbctl lsp-del lp0
5600 ovn-sbctl find MAC_Binding
5601 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5602 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5603 ovn-nbctl ls-del ls0
5604 ovn-sbctl find MAC_Binding
5605 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5606
5607 OVN_CLEANUP([hv1])
5608
5609 AT_CLEANUP
5610
5611 AT_SETUP([ovn -- conntrack zone allocation])
5612 AT_SKIP_IF([test $HAVE_PYTHON = no])
5613 ovn_start
5614
5615 # Logical network:
5616 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5617 # connected to a router R1.
5618 # foo has foo1 to act as a client.
5619 # bar has bar1, bar2, bar3 to act as servers.
5620
5621 net_add n1
5622
5623 sim_add hv1
5624 as hv1
5625 ovs-vsctl add-br br-phys
5626 ovn_attach n1 br-phys 192.168.0.1
5627 for i in foo1 bar1 bar2 bar3; do
5628 ovs-vsctl -- add-port br-int $i -- \
5629 set interface $i external-ids:iface-id=$i \
5630 options:tx_pcap=hv1/$i-tx.pcap \
5631 options:rxq_pcap=hv1/$i-rx.pcap
5632 done
5633
5634 ovn-nbctl create Logical_Router name=R1
5635 ovn-nbctl ls-add foo
5636 ovn-nbctl ls-add bar
5637
5638 # Connect foo to R1
5639 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5640 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5641 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5642
5643 # Connect bar to R1
5644 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5645 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5646 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5647
5648 # Create logical port foo1 in foo
5649 ovn-nbctl lsp-add foo foo1 \
5650 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5651
5652 # Create logical port bar1, bar2 and bar3 in bar
5653 for i in `seq 1 3`; do
5654 ip=`expr $i + 1`
5655 ovn-nbctl lsp-add bar bar$i \
5656 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5657 done
5658
5659 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5660
5661 OVN_CLEANUP([hv1])
5662
5663 AT_CLEANUP
5664
5665 AT_SETUP([ovn -- tag allocation])
5666 ovn_start
5667
5668 AT_CHECK([ovn-nbctl ls-add ls0])
5669 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5670 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5671 AT_CHECK([ovn-nbctl ls-add ls1])
5672
5673 dnl When a tag is provided, no allocation is done
5674 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5675 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5676 ])
5677 dnl The same 'tag' gets created in southbound database.
5678 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5679 logical_port="c0"], [0], [3
5680 ])
5681
5682 dnl Allocate tags and see it getting created in both NB and SB
5683 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5684 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5685 ])
5686 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5687 logical_port="c1"], [0], [1
5688 ])
5689
5690 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5691 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5692 ])
5693 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5694 logical_port="c2"], [0], [2
5695 ])
5696 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5697 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5698 ])
5699 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5700 logical_port="c3"], [0], [4
5701 ])
5702
5703 dnl A different parent.
5704 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5705 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5706 ])
5707 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5708 logical_port="c4"], [0], [1
5709 ])
5710
5711 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5712 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5713 ])
5714 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5715 logical_port="c5"], [0], [2
5716 ])
5717
5718 dnl Delete a logical port and create a new one.
5719 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5720 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5721 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5722 ])
5723 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5724 logical_port="c6"], [0], [1
5725 ])
5726
5727 dnl Restart northd to see that the same allocation remains.
5728 as northd
5729 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5730 start_daemon ovn-northd \
5731 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5732 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5733
5734 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5735 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5736 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5737 ])
5738 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5739 ])
5740 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5741 ])
5742 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5743 ])
5744 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5745 ])
5746 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5747 ])
5748
5749 dnl Create a switch port with a tag that has already been allocated.
5750 dnl It should go through fine with a duplicate tag.
5751 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5752 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5753 ])
5754 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5755 logical_port="c7"], [0], [2
5756 ])
5757 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5758 ])
5759
5760 AT_CHECK([ovn-nbctl ls-add ls2])
5761 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5762 dnl gets copied to 'tag'
5763 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5764 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5765 ])
5766 dnl The same 'tag' gets created in southbound database.
5767 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5768 logical_port="local0"], [0], [25
5769 ])
5770 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5771 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5772 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5773 dnl change the tag_request.
5774 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5775 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5776 ])
5777
5778 AT_CLEANUP
5779
5780 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5781 ovn_start
5782 ovn-nbctl ls-add lsw0
5783 net_add n1
5784 for i in 1 2; do
5785 sim_add hv$i
5786 as hv$i
5787 ovs-vsctl add-br br-phys
5788 ovn_attach n1 br-phys 192.168.0.$i
5789 ovs-vsctl add-br br-eth0
5790 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5791 done
5792
5793 # Create a localnet port.
5794 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5795 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5796 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5797 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5798
5799
5800 # Create 3 vifs.
5801 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5802 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5803 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5804 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5805 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5806 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5807 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5808 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5809 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5810
5811 # Bind the localvif1 to hv1.
5812 as hv1
5813 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5814
5815 # On hv1, check that there are no flows outputting bcast to tunnel
5816 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5817
5818 # On hv2, check that no flow outputs bcast to tunnel to hv1.
5819 as hv2
5820 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5821
5822 # Now bind vif2 on hv2.
5823 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5824
5825 # At this point, the broadcast flow on vif2 should be deleted.
5826 # because, there is now a localnet vif bound (table=32 programming logic)
5827 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5828
5829 # Verify that the local net patch port exists on hv2.
5830 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5831
5832 # Now bind vif3 on hv2.
5833 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5834
5835 # Verify that the local net patch port still exists on hv2
5836 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5837
5838 # Delete localvif2
5839 AT_CHECK([ovn-nbctl lsp-del localvif2])
5840
5841 # Verify that the local net patch port still exists on hv2,
5842 # because, localvif3 is still bound.
5843 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5844
5845 OVN_CLEANUP([hv1],[hv2])
5846
5847 AT_CLEANUP
5848
5849
5850 AT_SETUP([ovn -- ACL logging])
5851 AT_KEYWORDS([ovn])
5852 ovn_start
5853
5854 net_add n1
5855
5856 sim_add hv
5857 as hv
5858 ovs-vsctl add-br br-phys
5859 ovn_attach n1 br-phys 192.168.0.1
5860 for i in lp1 lp2; do
5861 ovs-vsctl -- add-port br-int $i -- \
5862 set interface $i external-ids:iface-id=$i \
5863 options:tx_pcap=hv/$i-tx.pcap \
5864 options:rxq_pcap=hv/$i-rx.pcap
5865 done
5866
5867 lp1_mac="f0:00:00:00:00:01"
5868 lp1_ip="192.168.1.2"
5869
5870 lp2_mac="f0:00:00:00:00:02"
5871 lp2_ip="192.168.1.3"
5872
5873 ovn-nbctl ls-add lsw0
5874 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5875 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5876 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
5877 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
5878 ovn-nbctl --wait=sb sync
5879
5880 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
5881 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
5882
5883 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
5884 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
5885
5886 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
5887 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
5888
5889 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
5890 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
5891
5892 ovn-sbctl dump-flows
5893
5894
5895 # Send packet that should be dropped without logging.
5896 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5897 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5898 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
5899 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5900
5901 # Send packet that should be dropped with logging.
5902 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5903 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5904 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
5905 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5906
5907 # Send packet that should be allowed without logging.
5908 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5909 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5910 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
5911 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5912
5913 # Send packet that should be allowed with logging.
5914 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5915 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5916 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
5917 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5918
5919 # Send packet that should allow related flows without logging.
5920 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5921 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5922 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
5923 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5924
5925 # Send packet that should allow related flows with logging.
5926 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5927 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5928 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
5929 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5930
5931 # Send packet that should be rejected without logging.
5932 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5933 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5934 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
5935 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5936
5937 # Send packet that should be rejected with logging.
5938 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5939 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5940 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
5941 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5942
5943 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
5944
5945 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
5946 name="drop-flow", verdict=drop, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4361,tp_dst=81,tcp_flags=syn
5947 name="allow-flow", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4363,tp_dst=83,tcp_flags=syn
5948 name="<unnamed>", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4365,tp_dst=85,tcp_flags=syn
5949 name="reject-flow", verdict=reject, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4367,tp_dst=87,tcp_flags=syn
5950 ])
5951
5952 OVN_CLEANUP([hv])
5953 AT_CLEANUP
5954
5955
5956 AT_SETUP([ovn -- DSCP marking check])
5957 AT_KEYWORDS([ovn])
5958 ovn_start
5959
5960 ovn-nbctl ls-add lsw0
5961 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5962 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5963 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5964 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5965 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5966 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5967 ovn-nbctl --wait=sb sync
5968 net_add n1
5969 sim_add hv
5970 as hv
5971 ovs-vsctl add-br br-phys
5972 ovn_attach n1 br-phys 192.168.0.1
5973 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
5974 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
5975
5976 AT_CAPTURE_FILE([trace])
5977 ovn_trace () {
5978 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5979 }
5980
5981 # Extracts nw_tos from the final flow from ofproto/trace output and prints
5982 # it on stdout. Prints "none" if no nw_tos was included.
5983 get_final_nw_tos() {
5984 if flow=$(grep '^Final flow:' stdout); then :; else
5985 # The output didn't have a final flow.
5986 return 99
5987 fi
5988
5989 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5990 case $tos in
5991 '') echo none ;;
5992 *) echo $tos ;;
5993 esac
5994 }
5995
5996 # check_tos TOS
5997 #
5998 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
5999 check_tos() {
6000 # First check with ovn-trace for logical flows.
6001 echo "checking for tos $1"
6002 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6003 echo 'output("lp2");') > expout
6004 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])
6005
6006 # Then re-check with ofproto/trace for a physical packet.
6007 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])
6008 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6009 ])
6010 }
6011
6012 # check at L2
6013 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");
6014 ])
6015 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])
6016 AT_CHECK([get_final_nw_tos], [0], [none
6017 ])
6018
6019 # check at L3 without dscp marking
6020 check_tos 0
6021
6022 # Mark DSCP with a valid value
6023 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)
6024 check_tos 48
6025
6026 # Update the DSCP marking
6027 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6028 check_tos 63
6029
6030 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6031 check_tos 63
6032
6033 # Disable DSCP marking
6034 ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
6035 check_tos 0
6036
6037 OVN_CLEANUP([hv])
6038 AT_CLEANUP
6039
6040 AT_SETUP([ovn -- read-only sb db:ptcp access])
6041 AT_SKIP_IF([test $HAVE_PYTHON = no])
6042
6043 : > .$1.db.~lock~
6044 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6045
6046 # Add read-only remote to sb ovsdb-server
6047 AT_CHECK(
6048 [ovsdb-tool transact ovn-sb.db \
6049 ['["OVN_Southbound",
6050 {"op": "insert",
6051 "table": "SB_Global",
6052 "row": {
6053 "connections": ["set", [["named-uuid", "xyz"]]]}},
6054 {"op": "insert",
6055 "table": "Connection",
6056 "uuid-name": "xyz",
6057 "row": {"target": "ptcp:0:127.0.0.1",
6058 "read_only": true}}]']], [0], [ignore], [ignore])
6059
6060 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6061
6062 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6063
6064 # read-only accesses should succeed
6065 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6066 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6067
6068 # write access should fail
6069 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6070 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6071 ])
6072
6073 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6074 AT_CLEANUP
6075
6076 AT_SETUP([ovn -- read-only sb db:pssl access])
6077 AT_SKIP_IF([test $HAVE_PYTHON = no])
6078 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6079 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6080 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6081 \\]"])
6082
6083 : > .$1.db.~lock~
6084 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6085
6086 # Add read-only remote to sb ovsdb-server
6087 AT_CHECK(
6088 [ovsdb-tool transact ovn-sb.db \
6089 ['["OVN_Southbound",
6090 {"op": "insert",
6091 "table": "SB_Global",
6092 "row": {
6093 "connections": ["set", [["named-uuid", "xyz"]]]}},
6094 {"op": "insert",
6095 "table": "Connection",
6096 "uuid-name": "xyz",
6097 "row": {"target": "pssl:0:127.0.0.1",
6098 "read_only": true}}]']], [0], [ignore], [ignore])
6099
6100 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6101 --remote=db:OVN_Southbound,SB_Global,connections \
6102 --private-key="$PKIDIR/testpki-privkey2.pem" \
6103 --certificate="$PKIDIR/testpki-cert2.pem" \
6104 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6105 ovn-sb.db
6106
6107 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6108
6109 # read-only accesses should succeed
6110 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6111 --private-key=$PKIDIR/testpki-privkey.pem \
6112 --certificate=$PKIDIR/testpki-cert.pem \
6113 --ca-cert=$PKIDIR/testpki-cacert.pem \
6114 list SB_Global], [0], [stdout], [ignore])
6115 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6116 --private-key=$PKIDIR/testpki-privkey.pem \
6117 --certificate=$PKIDIR/testpki-cert.pem \
6118 --ca-cert=$PKIDIR/testpki-cacert.pem \
6119 list Connection], [0], [stdout], [ignore])
6120
6121 # write access should fail
6122 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6123 --private-key=$PKIDIR/testpki-privkey.pem \
6124 --certificate=$PKIDIR/testpki-cert.pem \
6125 --ca-cert=$PKIDIR/testpki-cacert.pem \
6126 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6127 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6128 ])
6129
6130 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6131 AT_CLEANUP
6132
6133 AT_SETUP([ovn -- nb connection/ssl commands])
6134 AT_SKIP_IF([test $HAVE_PYTHON = no])
6135 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6136 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6137 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6138 \\]"])
6139
6140 : > .$1.db.~lock~
6141 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6142
6143 # Start nb db server using db connection/ssl entries (unpopulated initially)
6144 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6145 --remote=db:OVN_Northbound,NB_Global,connections \
6146 --private-key=db:OVN_Northbound,SSL,private_key \
6147 --certificate=db:OVN_Northbound,SSL,certificate \
6148 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6149 ovn-nb.db
6150
6151 # Populate SSL configuration entries in nb db
6152 AT_CHECK(
6153 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6154 $PKIDIR/testpki-cert.pem \
6155 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6156
6157 # Populate a passive SSL connection in nb db
6158 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6159
6160 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6161
6162 # Verify SSL connetivity to nb db server
6163 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6164 --private-key=$PKIDIR/testpki-privkey.pem \
6165 --certificate=$PKIDIR/testpki-cert.pem \
6166 --ca-cert=$PKIDIR/testpki-cacert.pem \
6167 list NB_Global],
6168 [0], [stdout], [ignore])
6169 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6170 --private-key=$PKIDIR/testpki-privkey.pem \
6171 --certificate=$PKIDIR/testpki-cert.pem \
6172 --ca-cert=$PKIDIR/testpki-cacert.pem \
6173 list Connection],
6174 [0], [stdout], [ignore])
6175 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6176 --private-key=$PKIDIR/testpki-privkey.pem \
6177 --certificate=$PKIDIR/testpki-cert.pem \
6178 --ca-cert=$PKIDIR/testpki-cacert.pem \
6179 get-connection],
6180 [0], [stdout], [ignore])
6181
6182 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6183 AT_CLEANUP
6184
6185 AT_SETUP([ovn -- sb connection/ssl commands])
6186 AT_SKIP_IF([test $HAVE_PYTHON = no])
6187 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6188 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6189 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6190 \\]"])
6191
6192 : > .$1.db.~lock~
6193 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6194
6195 # Start sb db server using db connection/ssl entries (unpopulated initially)
6196 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6197 --remote=db:OVN_Southbound,SB_Global,connections \
6198 --private-key=db:OVN_Southbound,SSL,private_key \
6199 --certificate=db:OVN_Southbound,SSL,certificate \
6200 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6201 ovn-sb.db
6202
6203 # Populate SSL configuration entries in sb db
6204 AT_CHECK(
6205 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6206 $PKIDIR/testpki-cert.pem \
6207 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6208
6209 # Populate a passive SSL connection in sb db
6210 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6211
6212 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6213
6214 # Verify SSL connetivity to sb db server
6215 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6216 --private-key=$PKIDIR/testpki-privkey.pem \
6217 --certificate=$PKIDIR/testpki-cert.pem \
6218 --ca-cert=$PKIDIR/testpki-cacert.pem \
6219 list SB_Global],
6220 [0], [stdout], [ignore])
6221 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6222 --private-key=$PKIDIR/testpki-privkey.pem \
6223 --certificate=$PKIDIR/testpki-cert.pem \
6224 --ca-cert=$PKIDIR/testpki-cacert.pem \
6225 list Connection],
6226 [0], [stdout], [ignore])
6227 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6228 --private-key=$PKIDIR/testpki-privkey.pem \
6229 --certificate=$PKIDIR/testpki-cert.pem \
6230 --ca-cert=$PKIDIR/testpki-cacert.pem \
6231 get-connection],
6232 [0], [stdout], [ignore])
6233
6234 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6235 AT_CLEANUP
6236
6237 AT_SETUP([ovn -- nested containers])
6238 ovn_start
6239
6240 # Physical network:
6241 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6242
6243 # Logical network:
6244 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6245 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6246
6247 ovn-nbctl lr-add R1
6248 ovn-nbctl ls-add mgmt
6249 ovn-nbctl ls-add foo
6250 ovn-nbctl ls-add bar
6251
6252 # Connect mgmt to R1
6253 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6254 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6255 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6256
6257 # Connect foo to R1
6258 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6259 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6260 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6261
6262 # Connect bar to R1
6263 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6264 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6265 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6266
6267 # "mgmt" has VM1 and VM2 connected
6268 ovn-nbctl lsp-add mgmt vm1 \
6269 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6270
6271 ovn-nbctl lsp-add mgmt vm2 \
6272 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6273
6274 # "foo1" and "foo2" are containers belonging to switch "foo"
6275 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6276 ovn-nbctl lsp-add foo foo1 vm1 1 \
6277 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6278
6279 ovn-nbctl lsp-add foo foo2 vm2 2 \
6280 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6281
6282 # "bar1" and "bar2" are containers belonging to switch "bar"
6283 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6284 ovn-nbctl lsp-add bar bar1 vm1 2 \
6285 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6286
6287 ovn-nbctl lsp-add bar bar2 vm2 1 \
6288 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6289
6290 # bar3 is a standalone VM belonging to switch "bar"
6291 ovn-nbctl lsp-add bar bar3 \
6292 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6293
6294 # Create two hypervisor and create OVS ports corresponding to logical ports.
6295 net_add n1
6296
6297 sim_add hv1
6298 as hv1
6299 ovs-vsctl add-br br-phys
6300 ovn_attach n1 br-phys 192.168.0.1
6301 ovs-vsctl -- add-port br-int vm1 -- \
6302 set interface vm1 external-ids:iface-id=vm1 \
6303 options:tx_pcap=hv1/vm1-tx.pcap \
6304 options:rxq_pcap=hv1/vm1-rx.pcap \
6305 ofport-request=1
6306
6307 ovs-vsctl -- add-port br-int bar3 -- \
6308 set interface bar3 external-ids:iface-id=bar3 \
6309 options:tx_pcap=hv1/bar3-tx.pcap \
6310 options:rxq_pcap=hv1/bar3-rx.pcap \
6311 ofport-request=2
6312
6313 sim_add hv2
6314 as hv2
6315 ovs-vsctl add-br br-phys
6316 ovn_attach n1 br-phys 192.168.0.2
6317 ovs-vsctl -- add-port br-int vm2 -- \
6318 set interface vm2 external-ids:iface-id=vm2 \
6319 options:tx_pcap=hv2/vm2-tx.pcap \
6320 options:rxq_pcap=hv2/vm2-rx.pcap \
6321 ofport-request=1
6322
6323 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6324 # packets for ARP resolution (native tunneling doesn't queue packets
6325 # for ARP resolution).
6326 ovn_populate_arp
6327
6328 # Allow some time for ovn-northd and ovn-controller to catch up.
6329 # XXX This should be more systematic.
6330 sleep 1
6331
6332 ip_to_hex() {
6333 printf "%02x%02x%02x%02x" "$@"
6334 }
6335
6336 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6337 # different VLAN tags).
6338 src_mac="f00000010205"
6339 dst_mac="f00000010206"
6340 src_ip=`ip_to_hex 192 168 1 2`
6341 dst_ip=`ip_to_hex 192 168 1 3`
6342 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6343 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6344
6345 # expected packet at foo2
6346 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6347 echo $packet > expected
6348 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6349
6350 # Send ip packets between foo1 and bar2 (different switch, different HV)
6351 src_mac="f00000010205"
6352 dst_mac="000000010203"
6353 src_ip=`ip_to_hex 192 168 1 2`
6354 dst_ip=`ip_to_hex 192 168 2 3`
6355 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6356 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6357
6358 # expected packet at bar2
6359 src_mac="000000010204"
6360 dst_mac="f00000010208"
6361 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6362 echo $packet >> expected
6363 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6364
6365 # Send ip packets between foo1 and bar1
6366 # (different switch, loopback to same vm but different tag)
6367 src_mac="f00000010205"
6368 dst_mac="000000010203"
6369 src_ip=`ip_to_hex 192 168 1 2`
6370 dst_ip=`ip_to_hex 192 168 2 2`
6371 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6372 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6373
6374 # expected packet at bar1
6375 src_mac="000000010204"
6376 dst_mac="f00000010207"
6377 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6378 echo $packet > expected1
6379 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6380
6381 # Send ip packets between bar1 and bar3
6382 # (same switch. But one is container and another is a standalone VM)
6383 src_mac="f00000010207"
6384 dst_mac="f00000010209"
6385 src_ip=`ip_to_hex 192 168 2 2`
6386 dst_ip=`ip_to_hex 192 168 2 3`
6387 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6388 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6389
6390 # expected packet at bar3
6391 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6392 echo $packet > expected
6393 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6394
6395 # Send ip packets between foo1 and vm1.
6396 (different switch, container to the VM hosting it.)
6397 src_mac="f00000010205"
6398 dst_mac="000000010203"
6399 src_ip=`ip_to_hex 192 168 1 2`
6400 dst_ip=`ip_to_hex 172 16 1 2`
6401 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6402 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6403
6404 # expected packet at vm1
6405 src_mac="000000010202"
6406 dst_mac="f00000010203"
6407 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6408 echo $packet >> expected1
6409 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6410
6411 # Send packets from vm1 to bar1.
6412 (different switch, A hosting VM to a container inside it)
6413 src_mac="f00000010203"
6414 dst_mac="000000010202"
6415 src_ip=`ip_to_hex 172 16 1 2`
6416 dst_ip=`ip_to_hex 192 168 2 2`
6417 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6418 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6419
6420 # expected packet at vm1
6421 src_mac="000000010204"
6422 dst_mac="f00000010207"
6423 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6424 echo $packet >> expected1
6425 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6426
6427 OVN_CLEANUP([hv1],[hv2])
6428
6429 AT_CLEANUP
6430
6431 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6432 AT_SKIP_IF([test $HAVE_PYTHON = no])
6433 ovn_start
6434
6435 # Logical network:
6436 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6437 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6438 # (192.168.2.0/24) connected to it.
6439 #
6440 # R2 and R3 are gateway routers.
6441 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6442 # connected to it. Note how both alice and bob have the same subnet behind it.
6443 # We are trying to simulate external network via those 2 switches. In real
6444 # world the switch ports of these switches will have addresses set as "unknown"
6445 # to make them learning switches. Or those switches will be "localnet" ones.
6446
6447 # Create three hypervisors and create OVS ports corresponding to logical ports.
6448 net_add n1
6449
6450 sim_add hv1
6451 as hv1
6452 ovs-vsctl add-br br-phys
6453 ovn_attach n1 br-phys 192.168.0.1
6454 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6455 set interface hv1-vif1 external-ids:iface-id=foo1 \
6456 options:tx_pcap=hv1/vif1-tx.pcap \
6457 options:rxq_pcap=hv1/vif1-rx.pcap \
6458 ofport-request=1
6459
6460 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6461 set interface hv1-vif2 external-ids:iface-id=bar1 \
6462 options:tx_pcap=hv1/vif2-tx.pcap \
6463 options:rxq_pcap=hv1/vif2-rx.pcap \
6464 ofport-request=2
6465
6466 sim_add hv2
6467 as hv2
6468 ovs-vsctl add-br br-phys
6469 ovn_attach n1 br-phys 192.168.0.2
6470 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6471 set interface hv2-vif1 external-ids:iface-id=alice1 \
6472 options:tx_pcap=hv2/vif1-tx.pcap \
6473 options:rxq_pcap=hv2/vif1-rx.pcap \
6474 ofport-request=1
6475
6476 sim_add hv3
6477 as hv3
6478 ovs-vsctl add-br br-phys
6479 ovn_attach n1 br-phys 192.168.0.3
6480 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6481 set interface hv3-vif1 external-ids:iface-id=bob1 \
6482 options:tx_pcap=hv3/vif1-tx.pcap \
6483 options:rxq_pcap=hv3/vif1-rx.pcap \
6484 ofport-request=1
6485
6486
6487 ovn-nbctl create Logical_Router name=R1
6488 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6489 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6490
6491 ovn-nbctl ls-add foo
6492 ovn-nbctl ls-add bar
6493 ovn-nbctl ls-add alice
6494 ovn-nbctl ls-add bob
6495 ovn-nbctl ls-add join
6496
6497 # Connect foo to R1
6498 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6499 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6500 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6501
6502 # Connect bar to R1
6503 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6504 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6505 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6506
6507 # Connect alice to R2
6508 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6509 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6510 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6511
6512 # Connect bob to R3
6513 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6514 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6515 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6516
6517 # Connect R1 to join
6518 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6519 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6520 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6521
6522 # Connect R2 to join
6523 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6524 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6525 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6526
6527 # Connect R3 to join
6528 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6529 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6530 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6531
6532 # Install static routes with source ip address as the policy for routing.
6533 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6534 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6535 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6536
6537 # Install static routes with destination ip address as the policy for routing.
6538 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6539
6540 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6541
6542 # Create logical port foo1 in foo
6543 ovn-nbctl lsp-add foo foo1 \
6544 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6545
6546 # Create logical port bar1 in bar
6547 ovn-nbctl lsp-add bar bar1 \
6548 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6549
6550 # Create logical port alice1 in alice
6551 ovn-nbctl lsp-add alice alice1 \
6552 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6553
6554 # Create logical port bob1 in bob
6555 ovn-nbctl lsp-add bob bob1 \
6556 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6557
6558 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6559 # packets for ARP resolution (native tunneling doesn't queue packets
6560 # for ARP resolution).
6561 ovn_populate_arp
6562
6563 # Allow some time for ovn-northd and ovn-controller to catch up.
6564 # XXX This should be more systematic.
6565 sleep 1
6566
6567 ip_to_hex() {
6568 printf "%02x%02x%02x%02x" "$@"
6569 }
6570 trim_zeros() {
6571 sed 's/\(00\)\{1,\}$//'
6572 }
6573
6574 # Send ip packets between foo1 and bar1
6575 # (East-west traffic should flow normally)
6576 src_mac="f00000010203"
6577 dst_mac="000001010203"
6578 src_ip=`ip_to_hex 192 168 1 2`
6579 dst_ip=`ip_to_hex 192 168 2 2`
6580 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6581 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6582
6583 # Send ip packets between foo1 and alice1
6584 src_mac="f00000010203"
6585 dst_mac="000001010203"
6586 src_ip=`ip_to_hex 192 168 1 2`
6587 dst_ip=`ip_to_hex 172 16 1 3`
6588 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6589 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6590 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6591
6592 # Send ip packets between bar1 and bob1
6593 src_mac="f00000010204"
6594 dst_mac="000001010204"
6595 src_ip=`ip_to_hex 192 168 2 2`
6596 dst_ip=`ip_to_hex 172 16 1 4`
6597 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6598 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6599 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6600
6601 # Packet to expect at bar1
6602 src_mac="000001010204"
6603 dst_mac="f00000010204"
6604 src_ip=`ip_to_hex 192 168 1 2`
6605 dst_ip=`ip_to_hex 192 168 2 2`
6606 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6607 echo $expected > expected
6608 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6609
6610 # Packet to Expect at alice1
6611 src_mac="000002010203"
6612 dst_mac="f00000010205"
6613 src_ip=`ip_to_hex 192 168 1 2`
6614 dst_ip=`ip_to_hex 172 16 1 3`
6615 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6616 echo $expected > expected
6617 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6618
6619 # Packet to Expect at bob1
6620 src_mac="000003010203"
6621 dst_mac="f00000010206"
6622 src_ip=`ip_to_hex 192 168 2 2`
6623 dst_ip=`ip_to_hex 172 16 1 4`
6624 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6625 echo $expected > expected
6626 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6627
6628 for sim in hv1 hv2 hv3; do
6629 as $sim
6630 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6631 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6632 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6633 done
6634
6635 as ovn-sb
6636 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6637
6638 as ovn-nb
6639 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6640
6641 as northd
6642 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6643
6644 as main
6645 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6646 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6647
6648 AT_CLEANUP
6649
6650 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6651 AT_SKIP_IF([test $HAVE_PYTHON = no])
6652 ovn_start
6653
6654 ovn-nbctl ls-add ls1
6655
6656 ovn-nbctl lsp-add ls1 ls1-lp1 \
6657 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6658
6659 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6660
6661 ovn-nbctl lsp-add ls1 ls1-lp2 \
6662 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6663
6664 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6665
6666 DNS1=`ovn-nbctl create DNS records={}`
6667 DNS2=`ovn-nbctl create DNS records={}`
6668
6669 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6670 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6671 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6672
6673 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6674
6675 net_add n1
6676 sim_add hv1
6677
6678 as hv1
6679 ovs-vsctl add-br br-phys
6680 ovn_attach n1 br-phys 192.168.0.1
6681 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6682 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6683 options:tx_pcap=hv1/vif1-tx.pcap \
6684 options:rxq_pcap=hv1/vif1-rx.pcap \
6685 ofport-request=1
6686
6687 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6688 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6689 options:tx_pcap=hv1/vif2-tx.pcap \
6690 options:rxq_pcap=hv1/vif2-rx.pcap \
6691 ofport-request=2
6692
6693 ovn_populate_arp
6694 sleep 2
6695 as hv1 ovs-vsctl show
6696
6697 echo "*************************"
6698 ovn-sbctl list DNS
6699 echo "*************************"
6700
6701 ip_to_hex() {
6702 printf "%02x%02x%02x%02x" "$@"
6703 }
6704
6705 reset_pcap_file() {
6706 local iface=$1
6707 local pcap_file=$2
6708 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6709 options:rxq_pcap=dummy-rx.pcap
6710 rm -f ${pcap_file}*.pcap
6711 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6712 options:rxq_pcap=${pcap_file}-rx.pcap
6713 }
6714
6715 # set_dns_params host_name
6716 # Sets the dns_req_data and dns_resp_data
6717 set_dns_params() {
6718 local hname=$1
6719 local ttl=00000e10
6720 an_count=0001
6721 type=0001
6722 case $hname in
6723 vm1)
6724 # vm1.ovn.org
6725 query_name=03766d31036f766e036f726700
6726 # IPv4 address - 10.0.0.4
6727 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6728 ;;
6729 vm2)
6730 # vm2.ovn.org
6731 query_name=03766d32036f766e036f726700
6732 # IPv4 address - 10.0.0.6
6733 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6734 # IPv4 address - 20.0.0.4
6735 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6736 an_count=0002
6737 ;;
6738 vm3)
6739 # vm3.ovn.org
6740 query_name=03766d33036f766e036f726700
6741 # IPv4 address - 40.0.0.4
6742 expected_dns_answer=${query_name}00010001${ttl}000428000004
6743 ;;
6744 vm1_ipv6_only)
6745 # vm1.ovn.org
6746 query_name=03766d31036f766e036f726700
6747 # IPv6 address - aef0::4
6748 type=001c
6749 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6750 ;;
6751 vm1_ipv4_v6)
6752 # vm1.ovn.org
6753 query_name=03766d31036f766e036f726700
6754 type=00ff
6755 an_count=0002
6756 # IPv4 address - 10.0.0.4
6757 # IPv6 address - aef0::4
6758 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6759 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
6760 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
6761 ;;
6762 vm1_invalid_type)
6763 # vm1.ovn.org
6764 query_name=03766d31036f766e036f726700
6765 # IPv6 address - aef0::4
6766 type=0002
6767 ;;
6768 vm1_incomplete)
6769 # set type to none
6770 type=''
6771 esac
6772 # TTL - 3600
6773 local dns_req_header=010201200001000000000000
6774 local dns_resp_header=010281200001${an_count}00000000
6775 dns_req_data=${dns_req_header}${query_name}${type}0001
6776 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
6777 }
6778
6779 # This shell function sends a DNS request packet
6780 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
6781 test_dns() {
6782 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6783 local dns_query_data=$7
6784 shift; shift; shift; shift; shift; shift; shift;
6785 # Packet size => IPv4 header (20) + UDP header (8) +
6786 # DNS data (header + query)
6787 ip_len=`expr 28 + ${#dns_query_data} / 2`
6788 udp_len=`expr $ip_len - 20`
6789 ip_len=$(printf "%x" $ip_len)
6790 udp_len=$(printf "%x" $udp_len)
6791 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
6792 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
6793 # dns data
6794 request=${request}${dns_query_data}
6795
6796 if test $dns_reply != 0; then
6797 local dns_reply=$1
6798 ip_len=`expr 28 + ${#dns_reply} / 2`
6799 udp_len=`expr $ip_len - 20`
6800 ip_len=$(printf "%x" $ip_len)
6801 udp_len=$(printf "%x" $udp_len)
6802 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
6803 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
6804 echo $reply >> $inport.expected
6805 else
6806 for outport; do
6807 echo $request >> $outport.expected
6808 done
6809 fi
6810 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6811 }
6812
6813 AT_CAPTURE_FILE([ofctl_monitor0.log])
6814 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
6815 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
6816
6817 set_dns_params vm2
6818 src_ip=`ip_to_hex 10 0 0 4`
6819 dst_ip=`ip_to_hex 10 0 0 1`
6820 dns_reply=1
6821 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6822
6823 # NXT_RESUMEs should be 1.
6824 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6825
6826 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6827 cat 1.expected | cut -c -48 > expout
6828 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6829 # Skipping the IPv4 checksum.
6830 cat 1.expected | cut -c 53- > expout
6831 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6832
6833 reset_pcap_file hv1-vif1 hv1/vif1
6834 reset_pcap_file hv1-vif2 hv1/vif2
6835 rm -f 1.expected
6836 rm -f 2.expected
6837
6838 set_dns_params vm1
6839 src_ip=`ip_to_hex 10 0 0 6`
6840 dst_ip=`ip_to_hex 10 0 0 1`
6841 dns_reply=1
6842 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6843
6844 # NXT_RESUMEs should be 2.
6845 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6846
6847 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6848 cat 2.expected | cut -c -48 > expout
6849 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6850 # Skipping the IPv4 checksum.
6851 cat 2.expected | cut -c 53- > expout
6852 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6853
6854 reset_pcap_file hv1-vif1 hv1/vif1
6855 reset_pcap_file hv1-vif2 hv1/vif2
6856 rm -f 1.expected
6857 rm -f 2.expected
6858
6859 # Clear the query name options for ls1-lp2
6860 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
6861
6862 set_dns_params vm2
6863 src_ip=`ip_to_hex 10 0 0 4`
6864 dst_ip=`ip_to_hex 10 0 0 1`
6865 dns_reply=0
6866 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
6867
6868 # NXT_RESUMEs should be 3.
6869 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6870
6871 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6872 AT_CHECK([cat 1.packets], [0], [])
6873
6874 reset_pcap_file hv1-vif1 hv1/vif1
6875 reset_pcap_file hv1-vif2 hv1/vif2
6876 rm -f 1.expected
6877 rm -f 2.expected
6878
6879 # Clear the query name for ls1-lp1
6880 # Since ls1 has no query names configued,
6881 # ovn-northd should not add the DNS flows.
6882 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
6883
6884 set_dns_params vm1
6885 src_ip=`ip_to_hex 10 0 0 6`
6886 dst_ip=`ip_to_hex 10 0 0 1`
6887 dns_reply=0
6888 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6889
6890 # NXT_RESUMEs should be 3 only.
6891 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6892
6893 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6894 AT_CHECK([cat 2.packets], [0], [])
6895
6896 reset_pcap_file hv1-vif1 hv1/vif1
6897 reset_pcap_file hv1-vif2 hv1/vif2
6898 rm -f 1.expected
6899 rm -f 2.expected
6900
6901 # Test IPv6 (AAAA records) using IPv4 packet.
6902 # Add back the DNS options for ls1-lp1.
6903 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6904
6905 set_dns_params vm1_ipv6_only
6906 src_ip=`ip_to_hex 10 0 0 6`
6907 dst_ip=`ip_to_hex 10 0 0 1`
6908 dns_reply=1
6909 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6910
6911 # NXT_RESUMEs should be 4.
6912 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6913
6914 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6915 cat 2.expected | cut -c -48 > expout
6916 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6917 # Skipping the IPv4 checksum.
6918 cat 2.expected | cut -c 53- > expout
6919 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6920
6921 reset_pcap_file hv1-vif1 hv1/vif1
6922 reset_pcap_file hv1-vif2 hv1/vif2
6923 rm -f 1.expected
6924 rm -f 2.expected
6925
6926 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
6927 set_dns_params vm1_ipv4_v6
6928 src_ip=`ip_to_hex 10 0 0 6`
6929 dst_ip=`ip_to_hex 10 0 0 1`
6930 dns_reply=1
6931 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6932
6933 # NXT_RESUMEs should be 5.
6934 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6935
6936 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6937 cat 2.expected | cut -c -48 > expout
6938 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6939 # Skipping the IPv4 checksum.
6940 cat 2.expected | cut -c 53- > expout
6941 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6942
6943 reset_pcap_file hv1-vif1 hv1/vif1
6944 reset_pcap_file hv1-vif2 hv1/vif2
6945 rm -f 1.expected
6946 rm -f 2.expected
6947
6948 # Invalid type.
6949 set_dns_params vm1_invalid_type
6950 src_ip=`ip_to_hex 10 0 0 6`
6951 dst_ip=`ip_to_hex 10 0 0 1`
6952 dns_reply=0
6953 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6954
6955 # NXT_RESUMEs should be 6.
6956 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6957
6958 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6959 AT_CHECK([cat 2.packets], [0], [])
6960
6961 reset_pcap_file hv1-vif1 hv1/vif1
6962 reset_pcap_file hv1-vif2 hv1/vif2
6963 rm -f 1.expected
6964 rm -f 2.expected
6965
6966 # Incomplete DNS packet.
6967 set_dns_params vm1_incomplete
6968 src_ip=`ip_to_hex 10 0 0 6`
6969 dst_ip=`ip_to_hex 10 0 0 1`
6970 dns_reply=0
6971 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6972
6973 # NXT_RESUMEs should be 7.
6974 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6975
6976 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6977 AT_CHECK([cat 2.packets], [0], [])
6978
6979 reset_pcap_file hv1-vif1 hv1/vif1
6980 reset_pcap_file hv1-vif2 hv1/vif2
6981 rm -f 1.expected
6982 rm -f 2.expected
6983
6984 # Add one more DNS record to the ls1.
6985 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
6986
6987 set_dns_params vm3
6988 src_ip=`ip_to_hex 10 0 0 4`
6989 dst_ip=`ip_to_hex 10 0 0 1`
6990 dns_reply=1
6991 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6992
6993 # NXT_RESUMEs should be 8.
6994 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6995
6996 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6997 cat 1.expected | cut -c -48 > expout
6998 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6999 # Skipping the IPv4 checksum.
7000 cat 1.expected | cut -c 53- > expout
7001 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7002
7003 reset_pcap_file hv1-vif1 hv1/vif1
7004 reset_pcap_file hv1-vif2 hv1/vif2
7005 rm -f 1.expected
7006 rm -f 2.expected
7007
7008 as hv1
7009 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7010 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7011 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7012
7013 as ovn-sb
7014 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7015
7016 as ovn-nb
7017 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7018
7019 as northd
7020 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7021
7022 as main
7023 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7024 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7025 AT_CLEANUP
7026
7027 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
7028 AT_SKIP_IF([test $HAVE_PYTHON = no])
7029 ovn_start
7030
7031 net_add n1
7032
7033 sim_add hv1
7034 as hv1
7035 ovs-vsctl add-br br-phys
7036 ovn_attach n1 br-phys 192.168.0.1
7037 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7038 set interface hv1-vif1 external-ids:iface-id=foo1 \
7039 options:tx_pcap=hv1/vif1-tx.pcap \
7040 options:rxq_pcap=hv1/vif1-rx.pcap \
7041 ofport-request=1
7042
7043 sim_add gw1
7044 as gw1
7045 ovs-vsctl add-br br-phys
7046 ovn_attach n1 br-phys 192.168.0.2
7047
7048 sim_add gw2
7049 as gw2
7050 ovs-vsctl add-br br-phys
7051 ovn_attach n1 br-phys 192.168.0.4
7052
7053 sim_add ext1
7054 as ext1
7055 ovs-vsctl add-br br-phys
7056 ovn_attach n1 br-phys 192.168.0.3
7057 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7058 set interface ext1-vif1 external-ids:iface-id=outside1 \
7059 options:tx_pcap=ext1/vif1-tx.pcap \
7060 options:rxq_pcap=ext1/vif1-rx.pcap \
7061 ofport-request=1
7062
7063 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7064 # packets for ARP resolution (native tunneling doesn't queue packets
7065 # for ARP resolution).
7066 ovn_populate_arp
7067
7068 ovn-nbctl create Logical_Router name=R1
7069
7070 ovn-nbctl ls-add foo
7071 ovn-nbctl ls-add alice
7072 ovn-nbctl ls-add outside
7073
7074 # Connect foo to R1
7075 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7076 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7077 type=router options:router-port=foo \
7078 -- lsp-set-addresses rp-foo router
7079
7080 # Connect alice to R1 as distributed router gateway port on gw1
7081 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7082
7083 ovn-nbctl \
7084 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7085 chassis_name=gw1 \
7086 priority=20 -- \
7087 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7088 chassis_name=gw2 \
7089 priority=10 -- \
7090 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7091
7092 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7093 type=router options:router-port=alice \
7094 -- lsp-set-addresses rp-alice router
7095
7096 # Create logical port foo1 in foo
7097 ovn-nbctl lsp-add foo foo1 \
7098 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7099
7100 # Create logical port outside1 in outside
7101 ovn-nbctl lsp-add outside outside1 \
7102 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7103
7104 # Create localnet port in alice
7105 ovn-nbctl lsp-add alice ln-alice
7106 ovn-nbctl lsp-set-addresses ln-alice unknown
7107 ovn-nbctl lsp-set-type ln-alice localnet
7108 ovn-nbctl lsp-set-options ln-alice network_name=phys
7109
7110 # Create localnet port in outside
7111 ovn-nbctl lsp-add outside ln-outside
7112 ovn-nbctl lsp-set-addresses ln-outside unknown
7113 ovn-nbctl lsp-set-type ln-outside localnet
7114 ovn-nbctl lsp-set-options ln-outside network_name=phys
7115
7116 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7117 # mapping to the external network, is the one generating packets
7118 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7119 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7120 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7121
7122 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7123
7124 # Allow some time for ovn-northd and ovn-controller to catch up.
7125 # XXX This should be more systematic.
7126 sleep 2
7127
7128 ip_to_hex() {
7129 printf "%02x%02x%02x%02x" "$@"
7130 }
7131
7132 reset_pcap_file() {
7133 local iface=$1
7134 local pcap_file=$2
7135 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7136 options:rxq_pcap=dummy-rx.pcap
7137 rm -f ${pcap_file}*.pcap
7138 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7139 options:rxq_pcap=${pcap_file}-rx.pcap
7140 }
7141
7142 test_ip_packet()
7143 {
7144 local active_gw=$1
7145 local backup_gw=$2
7146
7147 # Send ip packet between foo1 and outside1
7148 src_mac="f00000010203" # foo1 mac
7149 dst_mac="000001010203" # rp-foo mac (internal router leg)
7150 src_ip=`ip_to_hex 192 168 1 2`
7151 dst_ip=`ip_to_hex 172 16 1 3`
7152 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7153
7154 # ARP request packet to expect at outside1
7155 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7156
7157 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7158
7159 # Send ARP reply from outside1 back to the router
7160 # XXX: note, we could avoid this if we plug this port into a netns
7161 # and setup the IP address into the port, so the kernel would simply reply
7162 src_mac="000002010203"
7163 reply_mac="f00000010204"
7164 dst_ip=`ip_to_hex 172 16 1 3`
7165 src_ip=`ip_to_hex 172 16 1 1`
7166 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7167
7168 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7169
7170 # Packet to Expect at ext1 chassis, outside1 port
7171 src_mac="000002010203"
7172 dst_mac="f00000010204"
7173 src_ip=`ip_to_hex 192 168 1 2`
7174 dst_ip=`ip_to_hex 172 16 1 3`
7175 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7176 echo $expected > ext1-vif1.expected
7177
7178 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7179 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7180 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7181
7182 # Resend packet from foo1 to outside1
7183 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7184
7185 sleep 1
7186
7187 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7188 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7189 AT_CHECK([grep $expected packets | sort], [0], [expout])
7190 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7191 AT_CHECK([grep $expected packets | sort], [0], [])
7192 }
7193
7194 test_ip_packet gw1 gw2
7195
7196 ovn-nbctl --timeout=3 --wait=hv \
7197 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7198 chassis_name=gw1 \
7199 priority=10 -- \
7200 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7201 chassis_name=gw2 \
7202 priority=20 -- \
7203 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7204
7205 test_ip_packet gw2 gw1
7206
7207 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7208 AT_CLEANUP
7209
7210 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7211 AT_SKIP_IF([test $HAVE_PYTHON = no])
7212 ovn_start
7213
7214 net_add n1
7215
7216 sim_add hv1
7217 as hv1
7218 ovs-vsctl add-br br-phys
7219 ovn_attach n1 br-phys 192.168.0.1
7220 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7221 set interface hv1-vif1 external-ids:iface-id=foo1 \
7222 options:tx_pcap=hv1/vif1-tx.pcap \
7223 options:rxq_pcap=hv1/vif1-rx.pcap \
7224 ofport-request=1
7225
7226 sim_add gw1
7227 as gw1
7228 ovs-vsctl add-br br-phys
7229 ovn_attach n1 br-phys 192.168.0.2
7230
7231 sim_add gw2
7232 as gw2
7233 ovs-vsctl add-br br-phys
7234 ovn_attach n1 br-phys 192.168.0.4
7235
7236 sim_add ext1
7237 as ext1
7238 ovs-vsctl add-br br-phys
7239 ovn_attach n1 br-phys 192.168.0.3
7240 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7241 set interface ext1-vif1 external-ids:iface-id=outside1 \
7242 options:tx_pcap=ext1/vif1-tx.pcap \
7243 options:rxq_pcap=ext1/vif1-rx.pcap \
7244 ofport-request=1
7245
7246 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7247 # packets for ARP resolution (native tunneling doesn't queue packets
7248 # for ARP resolution).
7249 ovn_populate_arp
7250
7251 ovn-nbctl create Logical_Router name=R0
7252 ovn-nbctl create Logical_Router name=R1
7253
7254 ovn-nbctl ls-add foo
7255 ovn-nbctl ls-add join
7256 ovn-nbctl ls-add alice
7257 ovn-nbctl ls-add outside
7258
7259 #Connect foo to R0
7260 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7261 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7262 type=router options:router-port=R0-foo \
7263 -- lsp-set-addresses foo-R0 router
7264
7265 #Connect R0 to join
7266 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7267 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7268 type=router options:router-port=R0-join \
7269 -- lsp-set-addresses join-R0 router
7270
7271 #Connect join to R1
7272 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7273 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7274 type=router options:router-port=R1-join \
7275 -- lsp-set-addresses join-R1 router
7276
7277 #add route rules
7278 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7279 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7280
7281 # Connect alice to R1 as distributed router gateway port on gw1
7282 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7283
7284 ovn-nbctl \
7285 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7286 chassis_name=gw1 \
7287 priority=20 -- \
7288 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7289 chassis_name=gw2 \
7290 priority=10 -- \
7291 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7292
7293 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7294 type=router options:router-port=alice \
7295 -- lsp-set-addresses rp-alice router
7296
7297 # Create logical port foo1 in foo
7298 ovn-nbctl lsp-add foo foo1 \
7299 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7300
7301 # Create logical port outside1 in outside
7302 ovn-nbctl lsp-add outside outside1 \
7303 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7304
7305 # Create localnet port in alice
7306 ovn-nbctl lsp-add alice ln-alice
7307 ovn-nbctl lsp-set-addresses ln-alice unknown
7308 ovn-nbctl lsp-set-type ln-alice localnet
7309 ovn-nbctl lsp-set-options ln-alice network_name=phys
7310
7311 # Create localnet port in outside
7312 ovn-nbctl lsp-add outside ln-outside
7313 ovn-nbctl lsp-set-addresses ln-outside unknown
7314 ovn-nbctl lsp-set-type ln-outside localnet
7315 ovn-nbctl lsp-set-options ln-outside network_name=phys
7316
7317 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7318 # mapping to the external network, is the one generating packets
7319 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7320 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7321 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7322
7323 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7324
7325 # Allow some time for ovn-northd and ovn-controller to catch up.
7326 # XXX This should be more systematic.
7327 sleep 2
7328
7329 ip_to_hex() {
7330 printf "%02x%02x%02x%02x" "$@"
7331 }
7332
7333 reset_pcap_file() {
7334 local iface=$1
7335 local pcap_file=$2
7336 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7337 options:rxq_pcap=dummy-rx.pcap
7338 rm -f ${pcap_file}*.pcap
7339 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7340 options:rxq_pcap=${pcap_file}-rx.pcap
7341 }
7342
7343 test_ip_packet()
7344 {
7345 local active_gw=$1
7346 local backup_gw=$2
7347
7348 # Send ip packet between foo1 and outside1
7349 src_mac="f00000010203" # foo1 mac
7350 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7351 src_ip=`ip_to_hex 192 168 1 2`
7352 dst_ip=`ip_to_hex 172 16 1 3`
7353 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7354
7355 # ARP request packet to expect at outside1
7356 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7357
7358 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7359
7360 # Send ARP reply from outside1 back to the router
7361 # XXX: note, we could avoid this if we plug this port into a netns
7362 # and setup the IP address into the port, so the kernel would simply reply
7363 src_mac="000002010203"
7364 reply_mac="f00000010204"
7365 dst_ip=`ip_to_hex 172 16 1 3`
7366 src_ip=`ip_to_hex 172 16 1 1`
7367 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7368
7369 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7370
7371 # Packet to Expect at ext1 chassis, outside1 port
7372 src_mac="000002010203"
7373 dst_mac="f00000010204"
7374 src_ip=`ip_to_hex 192 168 1 2`
7375 dst_ip=`ip_to_hex 172 16 1 3`
7376 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7377 echo $expected > ext1-vif1.expected
7378
7379 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7380 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7381 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7382
7383 # Resend packet from foo1 to outside1
7384 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7385
7386 sleep 1
7387
7388 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7389 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7390 AT_CHECK([grep $expected packets | sort], [0], [expout])
7391 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7392 AT_CHECK([grep $expected packets | sort], [0], [])
7393 }
7394
7395 test_ip_packet gw1 gw2
7396
7397 ovn-nbctl --timeout=3 --wait=hv \
7398 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7399 chassis_name=gw1 \
7400 priority=10 -- \
7401 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7402 chassis_name=gw2 \
7403 priority=20 -- \
7404 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7405
7406 test_ip_packet gw2 gw1
7407
7408 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7409 AT_CLEANUP
7410
7411 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7412 AT_SKIP_IF([test $HAVE_PYTHON = no])
7413 ovn_start
7414
7415 # Logical network:
7416 # One LR R1 that has switches foo (192.168.1.0/24) and
7417 # alice (172.16.1.0/24) connected to it. The logical port
7418 # between R1 and alice has a "redirect-chassis" specified,
7419 # i.e. it is the distributed router gateway port.
7420 # Switch alice also has a localnet port defined.
7421 # An additional switch outside has a localnet port and the
7422 # same subnet as alice (172.16.1.0/24).
7423
7424 # Physical network:
7425 # Three hypervisors hv[123].
7426 # hv1 hosts vif foo1.
7427 # hv2 is the "redirect-chassis" that hosts the distributed
7428 # router gateway port.
7429 # hv3 hosts vif outside1.
7430 # In order to show that connectivity works only through hv2,
7431 # an initial round of tests is run without any bridge-mapping
7432 # defined for the localnet on hv2. These tests are expected
7433 # to fail.
7434 # Subsequent tests are run after defining the bridge-mapping
7435 # for the localnet on hv2. These tests are expected to succeed.
7436
7437 # Create three hypervisors and create OVS ports corresponding
7438 # to logical ports.
7439 net_add n1
7440
7441 sim_add hv1
7442 as hv1
7443 ovs-vsctl add-br br-phys
7444 ovn_attach n1 br-phys 192.168.0.1
7445 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7446 set interface hv1-vif1 external-ids:iface-id=foo1 \
7447 options:tx_pcap=hv1/vif1-tx.pcap \
7448 options:rxq_pcap=hv1/vif1-rx.pcap \
7449 ofport-request=1
7450
7451 sim_add hv2
7452 as hv2
7453 ovs-vsctl add-br br-phys
7454 ovn_attach n1 br-phys 192.168.0.2
7455
7456 sim_add hv3
7457 as hv3
7458 ovs-vsctl add-br br-phys
7459 ovn_attach n1 br-phys 192.168.0.3
7460 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7461 set interface hv3-vif1 external-ids:iface-id=outside1 \
7462 options:tx_pcap=hv3/vif1-tx.pcap \
7463 options:rxq_pcap=hv3/vif1-rx.pcap \
7464 ofport-request=1
7465
7466 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7467 # packets for ARP resolution (native tunneling doesn't queue packets
7468 # for ARP resolution).
7469 ovn_populate_arp
7470
7471 ovn-nbctl create Logical_Router name=R1
7472
7473 ovn-nbctl ls-add foo
7474 ovn-nbctl ls-add alice
7475 ovn-nbctl ls-add outside
7476
7477 # Connect foo to R1
7478 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7479 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7480 type=router options:router-port=foo \
7481 -- lsp-set-addresses rp-foo router
7482
7483 # Connect alice to R1 as distributed router gateway port on hv2
7484 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7485 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7486 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7487 type=router options:router-port=alice \
7488 -- lsp-set-addresses rp-alice router
7489
7490 # Create logical port foo1 in foo
7491 ovn-nbctl lsp-add foo foo1 \
7492 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7493
7494 # Create logical port outside1 in outside
7495 ovn-nbctl lsp-add outside outside1 \
7496 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7497
7498 # Create localnet port in alice
7499 ovn-nbctl lsp-add alice ln-alice
7500 ovn-nbctl lsp-set-addresses ln-alice unknown
7501 ovn-nbctl lsp-set-type ln-alice localnet
7502 ovn-nbctl lsp-set-options ln-alice network_name=phys
7503
7504 # Create localnet port in outside
7505 ovn-nbctl lsp-add outside ln-outside
7506 ovn-nbctl lsp-set-addresses ln-outside unknown
7507 ovn-nbctl lsp-set-type ln-outside localnet
7508 ovn-nbctl lsp-set-options ln-outside network_name=phys
7509
7510 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7511 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7512 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7513
7514
7515 # Allow some time for ovn-northd and ovn-controller to catch up.
7516 # XXX This should be more systematic.
7517 sleep 2
7518
7519 echo "---------NB dump-----"
7520 ovn-nbctl show
7521 echo "---------------------"
7522 ovn-nbctl list logical_router
7523 echo "---------------------"
7524 ovn-nbctl list logical_router_port
7525 echo "---------------------"
7526
7527 echo "---------SB dump-----"
7528 ovn-sbctl list datapath_binding
7529 echo "---------------------"
7530 ovn-sbctl list port_binding
7531 echo "---------------------"
7532 ovn-sbctl dump-flows
7533 echo "---------------------"
7534 ovn-sbctl list chassis
7535 ovn-sbctl list encap
7536 echo "------ Gateway_Chassis dump (SBDB) -------"
7537 ovn-sbctl list Gateway_Chassis
7538 echo "------ Port_Binding chassisredirect -------"
7539 ovn-sbctl find Port_Binding type=chassisredirect
7540 echo "-------------------------------------------"
7541
7542 echo "------ hv1 dump ----------"
7543 as hv1 ovs-ofctl show br-int
7544 as hv1 ovs-ofctl dump-flows br-int
7545 echo "------ hv2 dump ----------"
7546 as hv2 ovs-ofctl show br-int
7547 as hv2 ovs-ofctl dump-flows br-int
7548 echo "------ hv3 dump ----------"
7549 as hv3 ovs-ofctl show br-int
7550 as hv3 ovs-ofctl dump-flows br-int
7551 echo "--------------------------"
7552
7553
7554 # Check that redirect mapping is programmed only on hv2
7555 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7556 ])
7557 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7558 ])
7559 # Check that hv1 sends chassisredirect port traffic to hv2
7560 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7561 ])
7562 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7563 ])
7564 # Check that arp reply on distributed gateway port is only programmed on hv2
7565 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7566 ])
7567 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7568 ])
7569
7570
7571 ip_to_hex() {
7572 printf "%02x%02x%02x%02x" "$@"
7573 }
7574
7575
7576 : > hv2-vif1.expected
7577 : > hv3-vif1.expected
7578
7579 # test_arp INPORT SHA SPA TPA [REPLY_HA]
7580 #
7581 # Causes a packet to be received on INPORT. The packet is an ARP
7582 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7583 # it should be the hardware address of the target to expect to receive in an
7584 # ARP reply; otherwise no reply is expected.
7585 #
7586 # INPORT is an logical switch port number, e.g. 11 for vif11.
7587 # SHA and REPLY_HA are each 12 hex digits.
7588 # SPA and TPA are each 8 hex digits.
7589 test_arp() {
7590 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7591 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7592 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7593
7594 if test X$reply_ha != X; then
7595 # Expect to receive the reply, if any.
7596 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7597 echo $reply >> hv${hv}-vif$inport.expected
7598 fi
7599 }
7600
7601 rtr_ip=$(ip_to_hex 172 16 1 1)
7602 foo_ip=$(ip_to_hex 192 168 1 2)
7603 outside_ip=$(ip_to_hex 172 16 1 3)
7604
7605 echo $rtr_ip
7606 echo $foo_ip
7607 echo $outside_ip
7608
7609 # ARP for router IP address from outside1, no response expected
7610 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7611
7612 # Now check the packets actually received against the ones expected.
7613 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7614
7615 # Send ip packet between foo1 and outside1
7616 src_mac="f00000010203"
7617 dst_mac="000001010203"
7618 src_ip=`ip_to_hex 192 168 1 2`
7619 dst_ip=`ip_to_hex 172 16 1 3`
7620 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7621
7622 # Now check the packets actually received against the ones expected.
7623 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7624
7625 # Now add bridge-mappings on hv2, which should make everything work
7626 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7627
7628 # Allow some time for ovn-northd and ovn-controller to catch up.
7629 # XXX This should be more systematic.
7630 sleep 2
7631
7632 # ARP for router IP address from outside1
7633 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7634
7635 # Now check the packets actually received against the ones expected.
7636 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7637
7638 # Send ip packet between foo1 and outside1
7639 src_mac="f00000010203"
7640 dst_mac="000001010203"
7641 src_ip=`ip_to_hex 192 168 1 2`
7642 dst_ip=`ip_to_hex 172 16 1 3`
7643 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7644
7645 # ARP request packet to expect at outside1
7646 src_mac="000002010203"
7647 src_ip=`ip_to_hex 172 16 1 1`
7648 arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7649
7650 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7651
7652 echo $arp_request >> hv3-vif1.expected
7653 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7654
7655 # Send ARP reply from outside1 back to the router
7656 reply_mac="f00000010204"
7657 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7658
7659 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7660
7661 # Allow some time for ovn-northd and ovn-controller to catch up.
7662 # XXX This should be more systematic.
7663 sleep 1
7664
7665 # Packet to Expect at outside1
7666 src_mac="000002010203"
7667 dst_mac="f00000010204"
7668 src_ip=`ip_to_hex 192 168 1 2`
7669 dst_ip=`ip_to_hex 172 16 1 3`
7670 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7671
7672 # Resend packet from foo1 to outside1
7673 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7674
7675 echo "------ hv1 dump ----------"
7676 as hv1 ovs-ofctl show br-int
7677 as hv1 ovs-ofctl dump-flows br-int
7678 echo "------ hv2 dump ----------"
7679 as hv2 ovs-ofctl show br-int
7680 as hv2 ovs-ofctl dump-flows br-int
7681 echo "------ hv3 dump ----------"
7682 as hv3 ovs-ofctl show br-int
7683 as hv3 ovs-ofctl dump-flows br-int
7684 echo "----------------------------"
7685
7686 echo $expected >> hv3-vif1.expected
7687 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7688
7689 #Check ovn-trace over "chassisredirect" port
7690 AT_CAPTURE_FILE([trace])
7691 ovn_trace () {
7692 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7693 }
7694
7695 echo 'ip.ttl--;' > expout
7696 echo 'eth.src = 00:00:02:01:02:03;' >> expout
7697 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
7698 echo 'output("ln-alice");' >> expout
7699 AT_CHECK_UNQUOTED([ovn_trace foo 'inport == "foo1" && eth.src == f0:00:00:01:02:03 && eth.dst == 00:00:01:01:02:03 && ip4.src == 192.168.1.2 && ip4.dst == 172.16.1.3 && ip.ttl == 0xff'], [0], [expout])
7700
7701 # Create logical port alice1 in alice on hv1
7702 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7703 set interface hv1-vif2 external-ids:iface-id=alice1 \
7704 options:tx_pcap=hv1/vif2-tx.pcap \
7705 options:rxq_pcap=hv1/vif2-rx.pcap \
7706 ofport-request=1
7707
7708 ovn-nbctl lsp-add alice alice1 \
7709 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
7710
7711 # Create logical port foo2 in foo on hv2
7712 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7713 set interface hv2-vif1 external-ids:iface-id=foo2 \
7714 options:tx_pcap=hv2/vif1-tx.pcap \
7715 options:rxq_pcap=hv2/vif1-rx.pcap \
7716 ofport-request=1
7717
7718 ovn-nbctl lsp-add foo foo2 \
7719 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7720
7721 # Allow some time for ovn-northd and ovn-controller to catch up.
7722 # XXX This should be more systematic.
7723 sleep 1
7724
7725 : > hv1-vif2.expected
7726
7727 # Send ip packet between alice1 and foo2
7728 src_mac="f00000010205"
7729 dst_mac="000002010203"
7730 src_ip=`ip_to_hex 172 16 1 4`
7731 dst_ip=`ip_to_hex 192 168 1 3`
7732 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7733
7734 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7735
7736 # Packet to Expect at foo2
7737 src_mac="000001010203"
7738 dst_mac="f00000010206"
7739 src_ip=`ip_to_hex 172 16 1 4`
7740 dst_ip=`ip_to_hex 192 168 1 3`
7741 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7742
7743 echo $expected >> hv2-vif1.expected
7744 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
7745
7746 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
7747 ])
7748
7749 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
7750
7751 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
7752 ])
7753
7754 OVN_CLEANUP([hv1],[hv2],[hv3])
7755
7756 AT_CLEANUP
7757
7758 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7759 AT_SKIP_IF([test $HAVE_PYTHON = no])
7760 ovn_start
7761 # Create logical switches
7762 ovn-nbctl ls-add ls0
7763 ovn-nbctl ls-add ls1
7764 # Create distributed router
7765 ovn-nbctl create Logical_Router name=lr0
7766 # Add distributed gateway port to distributed router
7767 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
7768 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
7769 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
7770 type=router options:router-port=lrp0 addresses="router"
7771 # Add router port to ls1
7772 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
7773 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
7774 type=router options:router-port=lrp1 addresses="router"
7775 # Add logical ports for NAT rules
7776 ovn-nbctl lsp-add ls1 foo1 \
7777 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
7778 ovn-nbctl lsp-add ls1 foo2 \
7779 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
7780 # Add nat-addresses option
7781 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7782 # Add NAT rules
7783 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
7784 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
7785 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.3 10.0.0.3 foo1 f0:00:00:00:00:03])
7786 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.4 10.0.0.4 foo2 f0:00:00:00:00:04])
7787
7788 net_add n1
7789 sim_add hv1
7790 as hv1
7791 ovs-vsctl add-br br-phys
7792 ovn_attach n1 br-phys 192.168.0.1
7793
7794 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7795 AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
7796
7797 sim_add hv2
7798 as hv2
7799 ovs-vsctl add-br br-phys
7800 ovn_attach n1 br-phys 192.168.0.2
7801 # Initially test with no bridge-mapping on hv2, expect to receive no packets
7802
7803 sim_add hv3
7804 as hv3
7805 ovs-vsctl add-br br-phys
7806 ovn_attach n1 br-phys 192.168.0.3
7807 # Initially test with no bridge-mapping on hv3
7808
7809 # Create a localnet port.
7810 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
7811 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7812 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7813 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7814
7815 # Allow some time for ovn-northd and ovn-controller to catch up.
7816 # XXX This should be more systematic.
7817 sleep 2
7818
7819 # Expect no packets when hv2 bridge-mapping is not present
7820 : > packets
7821 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
7822
7823 # Add bridge-mapping on hv2
7824 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7825
7826 # Wait for packets to be received.
7827 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
7828 trim_zeros() {
7829 sed 's/\(00\)\{1,\}$//'
7830 }
7831 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7832 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
7833 echo $expected > expout
7834 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
7835 echo $expected >> expout
7836 AT_CHECK([sort packets], [0], [expout])
7837 sort packets | cat
7838
7839 # Temporarily remove nat-addresses option to avoid race conditions
7840 # due to GARP backoff
7841 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
7842
7843 reset_pcap_file() {
7844 local iface=$1
7845 local pcap_file=$2
7846 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7847 options:rxq_pcap=dummy-rx.pcap
7848 rm -f ${pcap_file}*.pcap
7849 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7850 options:rxq_pcap=${pcap_file}-rx.pcap
7851 }
7852
7853 as hv1 reset_pcap_file snoopvif hv1/snoopvif
7854
7855 # Add OVS ports for foo1 and foo2 on hv3
7856 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7857 set interface hv3-vif1 external-ids:iface-id=foo1 \
7858 ofport-request=1
7859 ovs-vsctl -- add-port br-int hv3-vif2 -- \
7860 set interface hv3-vif2 external-ids:iface-id=foo2 \
7861 ofport-request=2
7862
7863 # Add bridge-mapping on hv3
7864 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7865
7866 # Re-add nat-addresses option
7867 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7868
7869 # Wait for packets to be received.
7870 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
7871 trim_zeros() {
7872 sed 's/\(00\)\{1,\}$//'
7873 }
7874
7875 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7876 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
7877 echo $expected >> expout
7878 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
7879 echo $expected >> expout
7880 AT_CHECK([sort packets], [0], [expout])
7881 sort packets | cat
7882
7883 OVN_CLEANUP([hv1],[hv2],[hv3])
7884
7885 AT_CLEANUP
7886
7887 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
7888 AT_KEYWORDS([ovn-nd_ra])
7889 AT_SKIP_IF([test $HAVE_PYTHON = no])
7890 ovn_start
7891
7892 # In this test case we create 1 lswitch with 3 VIF ports attached,
7893 # and a lrouter connected to the lswitch.
7894 # We generate the Router solicitation packet and verify the Router Advertisement
7895 # reply packet from the ovn-controller.
7896
7897 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
7898 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
7899 # 'slaac' to allow lrp0 send RA for SLAAC mode.
7900 ovn-nbctl ls-add lsw0
7901 ovn-nbctl lr-add lr0
7902 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
7903 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
7904 ovn-nbctl \
7905 -- lsp-add lsw0 lsp0 \
7906 -- set Logical_Switch_Port lsp0 type=router \
7907 options:router-port=lrp0 \
7908 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
7909 net_add n1
7910 sim_add hv1
7911 as hv1
7912 ovs-vsctl add-br br-phys
7913 ovn_attach n1 br-phys 192.168.0.2
7914
7915 ovn-nbctl lsp-add lsw0 lp1
7916 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
7917 ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
7918
7919 ovn-nbctl lsp-add lsw0 lp2
7920 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
7921 ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
7922
7923 ovn-nbctl lsp-add lsw0 lp3
7924 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
7925 ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
7926
7927 # Add ACL rule for ICMPv6 on lsw0
7928 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
7929 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
7930 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
7931 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
7932
7933 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7934 set interface hv1-vif1 external-ids:iface-id=lp1 \
7935 options:tx_pcap=hv1/vif1-tx.pcap \
7936 options:rxq_pcap=hv1/vif1-rx.pcap \
7937 ofport-request=1
7938
7939 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7940 set interface hv1-vif2 external-ids:iface-id=lp2 \
7941 options:tx_pcap=hv1/vif2-tx.pcap \
7942 options:rxq_pcap=hv1/vif2-rx.pcap \
7943 ofport-request=2
7944
7945 ovs-vsctl -- add-port br-int hv1-vif3 -- \
7946 set interface hv1-vif3 external-ids:iface-id=lp3 \
7947 options:tx_pcap=hv1/vif3-tx.pcap \
7948 options:rxq_pcap=hv1/vif3-rx.pcap \
7949 ofport-request=3
7950
7951 # Allow some time for ovn-northd and ovn-controller to catch up.
7952 # XXX This should be more systematic.
7953 sleep 1
7954
7955 reset_pcap_file() {
7956 local iface=$1
7957 local pcap_file=$2
7958 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7959 options:rxq_pcap=dummy-rx.pcap
7960 rm -f ${pcap_file}*.pcap
7961 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7962 options:rxq_pcap=${pcap_file}-rx.pcap
7963 }
7964
7965 # Make sure that ovn-controller has installed the corresponding OF Flow.
7966 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
7967
7968 # This shell function sends a Router Solicitation packet.
7969 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
7970 test_ipv6_ra() {
7971 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
7972 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
7973
7974 local len=24
7975 local mtu_opt=""
7976 if test $mtu != 0; then
7977 len=`expr $len + 8`
7978 mtu_opt=05010000${mtu}
7979 fi
7980
7981 if test ${#prefix_opt} != 0; then
7982 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
7983 len=`expr $len + ${#prefix_opt} / 2`
7984 fi
7985
7986 len=$(printf "%x" $len)
7987 local lrp_mac=fa163e000001
7988 local lrp_lla=fe80000000000000f8163efffe000001
7989 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
7990 echo $reply >> $inport.expected
7991
7992 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
7993 }
7994
7995 AT_CAPTURE_FILE([ofctl_monitor0.log])
7996 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7997 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7998
7999 # MTU is not set and the address mode is set to slaac
8000 addr_mode=00
8001 default_prefix_option_config=030440c0ffffffffffffffff00000000
8002 src_mac=fa163e000002
8003 src_lla=fe80000000000000f8163efffe000002
8004 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8005
8006 # NXT_RESUME should be 1.
8007 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8008
8009 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8010
8011 cat 1.expected | cut -c -112 > expout
8012 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8013
8014 # Skipping the ICMPv6 checksum.
8015 cat 1.expected | cut -c 117- > expout
8016 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8017
8018 rm -f *.expected
8019 reset_pcap_file hv1-vif1 hv1/vif1
8020 reset_pcap_file hv1-vif2 hv1/vif2
8021 reset_pcap_file hv1-vif3 hv1/vif3
8022
8023 # Set the MTU to 1500
8024 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8025
8026 # Make sure that ovn-controller has installed the corresponding OF Flow.
8027 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8028
8029 addr_mode=00
8030 default_prefix_option_config=030440c0ffffffffffffffff00000000
8031 src_mac=fa163e000003
8032 src_lla=fe80000000000000f8163efffe000003
8033 mtu=000005dc
8034
8035 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8036
8037 # NXT_RESUME should be 2.
8038 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8039
8040 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8041
8042 cat 2.expected | cut -c -112 > expout
8043 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8044
8045 # Skipping the ICMPv6 checksum.
8046 cat 2.expected | cut -c 117- > expout
8047 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8048
8049 rm -f *.expected
8050 reset_pcap_file hv1-vif1 hv1/vif1
8051 reset_pcap_file hv1-vif2 hv1/vif2
8052 reset_pcap_file hv1-vif3 hv1/vif3
8053
8054 # Set the address mode to dhcpv6_stateful
8055 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8056 # Make sure that ovn-controller has installed the corresponding OF Flow.
8057 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8058
8059 addr_mode=80
8060 default_prefix_option_config=""
8061 src_mac=fa163e000004
8062 src_lla=fe80000000000000f8163efffe000004
8063 mtu=000005dc
8064
8065 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8066
8067 # NXT_RESUME should be 3.
8068 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8069
8070 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8071
8072 cat 3.expected | cut -c -112 > expout
8073 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8074
8075 # Skipping the ICMPv6 checksum.
8076 cat 3.expected | cut -c 117- > expout
8077 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8078
8079 rm -f *.expected
8080 reset_pcap_file hv1-vif1 hv1/vif1
8081 reset_pcap_file hv1-vif2 hv1/vif2
8082 reset_pcap_file hv1-vif3 hv1/vif3
8083
8084 # Set the address mode to dhcpv6_stateless
8085 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8086 # Make sure that ovn-controller has installed the corresponding OF Flow.
8087 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8088
8089 addr_mode=40
8090 default_prefix_option_config=030440c0ffffffffffffffff00000000
8091 src_mac=fa163e000002
8092 src_lla=fe80000000000000f8163efffe000002
8093 mtu=000005dc
8094
8095 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8096
8097 # NXT_RESUME should be 4.
8098 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8099
8100 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8101
8102 cat 1.expected | cut -c -112 > expout
8103 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8104
8105 # Skipping the ICMPv6 checksum.
8106 cat 1.expected | cut -c 117- > expout
8107 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8108
8109 rm -f *.expected
8110 reset_pcap_file hv1-vif1 hv1/vif1
8111 reset_pcap_file hv1-vif2 hv1/vif2
8112 reset_pcap_file hv1-vif3 hv1/vif3
8113
8114 # Set the address mode to invalid.
8115 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8116 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8117 OVS_WAIT_UNTIL([test 0 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8118
8119 addr_mode=40
8120 default_prefix_option_config=""
8121 src_mac=fa163e000002
8122 src_lla=fe80000000000000f8163efffe000002
8123 mtu=000005dc
8124
8125 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8126
8127 # NXT_RESUME should be 4 only.
8128 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8129
8130 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8131 AT_CHECK([cat 1.packets], [0], [])
8132
8133 OVN_CLEANUP([hv1])
8134 AT_CLEANUP
8135
8136 AT_SETUP([ovn -- /32 router IP address])
8137 AT_SKIP_IF([test $HAVE_PYTHON = no])
8138 ovn_start
8139
8140 # Logical network:
8141 # 2 LS 'foo' and 'alice' connected via router R1.
8142 # R1 connects to 'alice' with a /32 IP address. We use static routes and
8143 # nexthop to push traffic to a logical port in switch 'alice'
8144
8145 ovn-nbctl lr-add R1
8146
8147 ovn-nbctl ls-add foo
8148 ovn-nbctl ls-add alice
8149
8150 # Connect foo to R1
8151 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8152 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8153 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8154
8155 # Connect alice to R1.
8156 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8157 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8158 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8159
8160 # Create logical port foo1 in foo
8161 ovn-nbctl lsp-add foo foo1 \
8162 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8163
8164 # Create logical port alice1 in alice
8165 ovn-nbctl lsp-add alice alice1 \
8166 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8167
8168 #install default route in R1 to use alice1's IP address as nexthop
8169 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8170
8171 # Create two hypervisor and create OVS ports corresponding to logical ports.
8172 net_add n1
8173
8174 sim_add hv1
8175 as hv1
8176 ovs-vsctl add-br br-phys
8177 ovn_attach n1 br-phys 192.168.0.1
8178 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8179 set interface hv1-vif1 external-ids:iface-id=foo1 \
8180 options:tx_pcap=hv1/vif1-tx.pcap \
8181 options:rxq_pcap=hv1/vif1-rx.pcap \
8182 ofport-request=1
8183
8184 sim_add hv2
8185 as hv2
8186 ovs-vsctl add-br br-phys
8187 ovn_attach n1 br-phys 192.168.0.2
8188 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8189 set interface hv2-vif1 external-ids:iface-id=alice1 \
8190 options:tx_pcap=hv2/vif1-tx.pcap \
8191 options:rxq_pcap=hv2/vif1-rx.pcap \
8192 ofport-request=1
8193
8194
8195 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8196 # packets for ARP resolution (native tunneling doesn't queue packets
8197 # for ARP resolution).
8198 ovn_populate_arp
8199
8200 # Allow some time for ovn-northd and ovn-controller to catch up.
8201 # XXX This should be more systematic.
8202 sleep 1
8203
8204 ip_to_hex() {
8205 printf "%02x%02x%02x%02x" "$@"
8206 }
8207
8208 # Send ip packets between foo1 and alice1
8209 src_mac="f00000010203"
8210 dst_mac="000000010203"
8211 src_ip=`ip_to_hex 192 168 1 2`
8212 dst_ip=`ip_to_hex 10 0 0 2`
8213 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8214
8215 # Send the first packet to trigger a ARP response and population of
8216 # mac_bindings table.
8217 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8218 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8219
8220 # Send the second packet to reach the destination.
8221 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8222
8223 # Packet to Expect at 'alice1'
8224 src_mac="000000010204"
8225 dst_mac="f00000010204"
8226 src_ip=`ip_to_hex 192 168 1 2`
8227 dst_ip=`ip_to_hex 10 0 0 2`
8228 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8229
8230 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8231
8232 OVN_CLEANUP([hv1],[hv2])
8233
8234 AT_CLEANUP
8235
8236 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8237 AT_SKIP_IF([test $HAVE_PYTHON = no])
8238 ovn_start
8239
8240 ovn-nbctl ls-add ls1
8241
8242 # Add localport to the switch
8243 ovn-nbctl lsp-add ls1 lp01
8244 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8245 ovn-nbctl lsp-set-type lp01 localport
8246
8247 net_add n1
8248
8249 for i in 1 2; do
8250 sim_add hv$i
8251 as hv$i
8252 ovs-vsctl add-br br-phys
8253 ovn_attach n1 br-phys 192.168.0.$i
8254 ovs-vsctl add-port br-int vif01 -- \
8255 set Interface vif01 external-ids:iface-id=lp01 \
8256 options:tx_pcap=hv${i}/vif01-tx.pcap \
8257 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8258 ofport-request=${i}0
8259
8260 ovs-vsctl add-port br-int vif${i}1 -- \
8261 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8262 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8263 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8264 ofport-request=${i}1
8265
8266 ovn-nbctl lsp-add ls1 lp${i}1
8267 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8268 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8269
8270 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8271 done
8272
8273 ovn-nbctl --wait=sb sync
8274 ovn-sbctl dump-flows
8275
8276 ovn_populate_arp
8277
8278 # Given the name of a logical port, prints the name of the hypervisor
8279 # on which it is located.
8280 vif_to_hv() {
8281 echo hv${1%?}
8282 }
8283 #
8284 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8285 #
8286 # This shell function causes a packet to be received on INPORT. The packet's
8287 # content has Ethernet destination DST and source SRC (each exactly 12 hex
8288 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8289 # logical switch port numbers, e.g. 11 for vif11.
8290 #
8291 # EOUT is the end-to-end output port, that is, where the packet will end up
8292 # after possibly bouncing through one or more localnet ports. LOUT is the
8293 # logical output port, which might be a localnet port, as seen by ovn-trace
8294 # (which doesn't know what localnet ports are connected to and therefore can't
8295 # figure out the end-to-end answer).
8296 #
8297 # DEFHV is the default hypervisor from where the packet is going to be sent
8298 # if the source port is a localport.
8299 for i in 1 2; do
8300 for j in 0 1; do
8301 : > $i$j.expected
8302 done
8303 done
8304 test_packet() {
8305 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8306 echo "$@"
8307
8308 # First try tracing the packet.
8309 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8310 if test $lout != drop; then
8311 echo "output(\"$lout\");"
8312 fi > expout
8313 AT_CAPTURE_FILE([trace])
8314 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8315
8316 # Then actually send a packet, for an end-to-end test.
8317 local packet=$(echo $dst$src | sed 's/://g')${eth}
8318 hv=`vif_to_hv $inport`
8319 # If hypervisor 0 (localport) use the defhv parameter
8320 if test $hv = hv0; then
8321 hv=$defhv
8322 fi
8323 vif=vif$inport
8324 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8325 if test $eout != drop; then
8326 echo $packet >> ${eout#lp}.expected
8327 fi
8328 }
8329
8330
8331 # lp11 and lp21 are on different hypervisors
8332 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8333 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8334
8335 # Both VIFs should be able to reach the localport on their own HV
8336 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8337 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8338
8339 # Packet sent from localport on same hv should reach the vif
8340 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8341 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8342
8343 # Packet sent from localport on different hv should be dropped
8344 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8345 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8346
8347 # Now check the packets actually received against the ones expected.
8348 for i in 1 2; do
8349 for j in 0 1; do
8350 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8351 done
8352 done
8353
8354 OVN_CLEANUP([hv1],[hv2])
8355
8356 AT_CLEANUP
8357
8358 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8359 AT_SKIP_IF([test $HAVE_PYTHON = no])
8360 ovn_start
8361
8362 net_add n1
8363
8364 # create gateways with external network connectivity
8365
8366 for i in 1 2; do
8367 sim_add gw$i
8368 as gw$i
8369 ovs-vsctl add-br br-phys
8370 ovn_attach n1 br-phys 192.168.0.$i
8371 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8372 done
8373
8374 ovn-nbctl ls-add inside
8375 ovn-nbctl ls-add outside
8376
8377 # create hypervisors with a vif port each to an internal network
8378
8379 for i in 1 2; do
8380 sim_add hv$i
8381 as hv$i
8382 ovs-vsctl add-br br-phys
8383 ovn_attach n1 br-phys 192.168.0.1$i
8384 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8385 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8386 options:tx_pcap=hv$i/vif1-tx.pcap \
8387 options:rxq_pcap=hv$i/vif1-rx.pcap \
8388 ofport-request=1
8389
8390 ovn-nbctl lsp-add inside inside$i \
8391 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8392
8393 done
8394
8395 ovn_populate_arp
8396
8397 ovn-nbctl create Logical_Router name=R1
8398
8399 # Connect inside to R1
8400 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8401 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8402 type=router options:router-port=inside \
8403 -- lsp-set-addresses rp-inside router
8404
8405 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8406 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8407
8408 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8409 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8410 --id=@gc1 create Gateway_Chassis \
8411 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8412 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8413
8414 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8415 type=router options:router-port=outside \
8416 -- lsp-set-addresses rp-outside router
8417
8418 # Create localnet port in outside
8419 ovn-nbctl lsp-add outside ln-outside
8420 ovn-nbctl lsp-set-addresses ln-outside unknown
8421 ovn-nbctl lsp-set-type ln-outside localnet
8422 ovn-nbctl lsp-set-options ln-outside network_name=phys
8423
8424 # Allow some time for ovn-northd and ovn-controller to catch up.
8425 # XXX This should be more systematic.
8426 ovn-nbctl --wait=hv --timeout=3 sync
8427
8428 echo "---------NB dump-----"
8429 ovn-nbctl show
8430 echo "---------------------"
8431 ovn-nbctl list logical_router
8432 echo "---------------------"
8433 ovn-nbctl list logical_router_port
8434 echo "---------------------"
8435
8436 echo "---------SB dump-----"
8437 ovn-sbctl list datapath_binding
8438 echo "---------------------"
8439 ovn-sbctl list port_binding
8440 echo "---------------------"
8441 ovn-sbctl dump-flows
8442 echo "---------------------"
8443 ovn-sbctl list chassis
8444 ovn-sbctl list encap
8445 echo "---------------------"
8446 echo "------ Gateway_Chassis dump (SBDB) -------"
8447 ovn-sbctl list Gateway_Chassis
8448 echo "------ Port_Binding chassisredirect -------"
8449 ovn-sbctl find Port_Binding type=chassisredirect
8450 echo "-------------------------------------------"
8451
8452 for chassis in gw1 gw2 hv1 hv2; do
8453 as $chassis
8454 echo "------ $chassis dump ----------"
8455 ovs-ofctl show br-int
8456 ovs-ofctl dump-flows br-int
8457 echo "--------------------------"
8458 done
8459 function bfd_dump() {
8460 for chassis in gw1 gw2 hv1 hv2; do
8461 as $chassis
8462 echo "------ $chassis dump (BFD)----"
8463 echo "BFD (from $chassis):"
8464 # dump BFD config and status to the other chassis
8465 for chassis2 in gw1 gw2 hv1 hv2; do
8466 if [[ "$chassis" != "$chassis2" ]]; then
8467 echo " -> $chassis2:"
8468 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8469 fi
8470 done
8471 echo "--------------------------"
8472 done
8473 }
8474
8475 bfd_dump
8476
8477 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8478 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8479 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8480 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8481
8482 echo $hv1_gw1_ofport
8483 echo $hv1_gw2_ofport
8484 echo $hv2_gw1_ofport
8485 echo $hv2_gw2_ofport
8486
8487 echo "--- hv1 ---"
8488 as hv1 ovs-ofctl dump-flows br-int table=32
8489
8490 echo "--- hv2 ---"
8491 as hv2 ovs-ofctl dump-flows br-int table=32
8492
8493 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8494 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8495
8496 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport | wc -l], [0], [1
8497 ])
8498
8499 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport | wc -l], [0], [1
8500 ])
8501
8502 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8503
8504 # make sure that flows for handling the outside router port reside on gw1
8505 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8506 ]])
8507 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8508 ]])
8509
8510 # make sure ARP responder flows for outside router port reside on gw1 too
8511 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8512 ]])
8513 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8514 ]])
8515
8516
8517
8518 # check that the chassis redirect port has been claimed by the gw1 chassis
8519 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8520 [0],[[1
8521 ]])
8522
8523
8524 # at this point, we invert the priority of the gw chassis between gw1 and gw2
8525
8526 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8527 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8528 --id=@gc1 create Gateway_Chassis \
8529 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8530 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8531
8532
8533 # XXX: Let the change propagate down to the ovn-controllers
8534 ovn-nbctl --wait=hv --timeout=3 sync
8535
8536 # we make sure that the hypervisors noticed, and inverted the slave ports
8537 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport | wc -l], [0], [1
8538 ])
8539
8540 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport | wc -l], [0], [1
8541 ])
8542
8543 # check that the chassis redirect port has been reclaimed by the gw2 chassis
8544 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8545 [0],[[1
8546 ]])
8547
8548 # check BFD enablement on tunnel ports from gw1 #########
8549 as gw1
8550 for chassis in gw2 hv1 hv2; do
8551 echo "checking gw1 -> $chassis"
8552 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8553 [[enable=true
8554 ]])
8555 done
8556
8557
8558 # check BFD enablement on tunnel ports from gw2 ##########
8559 as gw2
8560 for chassis in gw1 hv1 hv2; do
8561 echo "checking gw2 -> $chassis"
8562 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8563 [[enable=true
8564 ]])
8565 done
8566
8567 # check BFD enablement on tunnel ports from hv1 ###########
8568 as hv1
8569 for chassis in gw1 gw2; do
8570 echo "checking hv1 -> $chassis"
8571 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8572 [[enable=true
8573 ]])
8574 done
8575 # make sure BFD is not enabled to hv2, we don't need it
8576 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8577 [[enable=false
8578 ]])
8579
8580
8581 # check BFD enablement on tunnel ports from hv2 ##########
8582 as hv2
8583 for chassis in gw1 gw2; do
8584 echo "checking hv2 -> $chassis"
8585 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8586 [[enable=true
8587 ]])
8588 done
8589 # make sure BFD is not enabled to hv1, we don't need it
8590 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8591 [[enable=false
8592 ]])
8593
8594 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8595
8596 # make sure that flows for handling the outside router port reside on gw2 now
8597 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8598 ]])
8599 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8600 ]])
8601
8602 # disconnect GW2 from the network, GW1 should take over
8603 as gw2
8604 port=${sandbox}_br-phys
8605 as main ovs-vsctl del-port n1 $port
8606 sleep 4
8607
8608 bfd_dump
8609
8610 # make sure that flows for handling the outside router port reside on gw2 now
8611 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8612 ]])
8613 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8614 ]])
8615
8616 # check that the chassis redirect port has been reclaimed by the gw1 chassis
8617 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8618 [0],[[1
8619 ]])
8620
8621 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8622
8623 AT_CLEANUP
8624
8625 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8626 AT_SKIP_IF([test $HAVE_PYTHON = no])
8627 ovn_start
8628 ovn-nbctl ls-add ls0
8629 ovn-nbctl ls-add ls1
8630 ovn-nbctl create Logical_Router name=lr0
8631 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8632
8633 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8634 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8635 --id=@gc1 create Gateway_Chassis \
8636 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8637 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8638
8639 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8640 type=router options:router-port=lrp0 addresses="router"
8641 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8642 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8643 type=router options:router-port=lrp1 addresses="router"
8644
8645 # Add NAT rules
8646 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8647
8648 net_add n1
8649 sim_add hv1
8650 as hv1
8651 ovs-vsctl add-br br-phys
8652 ovn_attach n1 br-phys 192.168.0.1
8653 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8654 AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
8655
8656 sim_add hv2
8657 as hv2
8658 ovs-vsctl add-br br-phys
8659 ovn_attach n1 br-phys 192.168.0.2
8660 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8661
8662 sim_add hv3
8663 as hv3
8664 ovs-vsctl add-br br-phys
8665 ovn_attach n1 br-phys 192.168.0.3
8666 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8667
8668 # Create a localnet port.
8669 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8670 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8671 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8672 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8673
8674 # wait for earlier changes to take effect
8675 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8676
8677 reset_pcap_file() {
8678 local iface=$1
8679 local pcap_file=$2
8680 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8681 options:rxq_pcap=dummy-rx.pcap
8682 rm -f ${pcap_file}*.pcap
8683 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8684 options:rxq_pcap=${pcap_file}-rx.pcap
8685 }
8686
8687 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8688 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8689 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8690 # add nat-addresses option
8691 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8692
8693 # Wait for packets to be received through hv2.
8694 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8695 trim_zeros() {
8696 sed 's/\(00\)\{1,\}$//'
8697 }
8698
8699 only_broadcast_from_lrp1() {
8700 grep "fffffffffffff00000000001"
8701 }
8702
8703 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
8704 echo $garp > expout
8705
8706 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
8707 echo "packets on hv1-snoopvif:"
8708 cat hv1_snoop_tx
8709 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
8710 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8711 echo "packets on hv2 br-phys tx"
8712 cat hv2_br_phys_tx
8713 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
8714 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8715 echo "packets on hv3 br-phys tx"
8716 cat hv3_br_phys_tx
8717 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8718
8719
8720 # at this point, we invert the priority of the gw chassis between hv2 and hv3
8721
8722 ovn-nbctl --wait=hv \
8723 --id=@gc0 create Gateway_Chassis \
8724 name=outside_gw1 chassis_name=hv2 priority=1 -- \
8725 --id=@gc1 create Gateway_Chassis \
8726 name=outside_gw2 chassis_name=hv3 priority=10 -- \
8727 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8728
8729
8730 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8731 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8732 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8733
8734 # Wait for packets to be received.
8735 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8736 trim_zeros() {
8737 sed 's/\(00\)\{1,\}$//'
8738 }
8739
8740 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8741 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8742 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8743 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8744 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8745 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8746
8747 # change localnet port tag.
8748 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
8749
8750 # wait for earlier changes to take effect
8751 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8752
8753 # update nat-addresses option
8754 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0
8755 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8756
8757 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8758 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8759 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8760
8761 # Wait for packets to be received.
8762 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8763 trim_zeros() {
8764 sed 's/\(00\)\{1,\}$//'
8765 }
8766
8767 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
8768 echo $garp > expout
8769
8770 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8771 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8772 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8773 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8774 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8775 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8776
8777 OVN_CLEANUP([hv1],[hv2],[hv3])
8778
8779 AT_CLEANUP
8780
8781 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8782 AT_SKIP_IF([test $HAVE_PYTHON = no])
8783 ovn_start
8784
8785 net_add n1
8786
8787 # create two gateways with external network connectivity
8788 for i in 1 2; do
8789 sim_add gw$i
8790 as gw$i
8791 ovs-vsctl add-br br-phys
8792 ovn_attach n1 br-phys 192.168.0.$i
8793 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8794 done
8795
8796 ovn-nbctl ls-add inside
8797 ovn-nbctl ls-add outside
8798
8799 # create one hypervisors with a vif port the internal network
8800 sim_add hv1
8801 as hv1
8802 ovs-vsctl add-br br-phys
8803 ovn_attach n1 br-phys 192.168.0.11
8804 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8805 set interface hv1-vif1 external-ids:iface-id=inside1 \
8806 options:tx_pcap=hv1/vif1-tx.pcap \
8807 options:rxq_pcap=hv1/vif1-rx.pcap \
8808 ofport-request=1
8809
8810 ovn-nbctl lsp-add inside inside1 \
8811 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
8812
8813
8814 ovn_populate_arp
8815
8816 ovn-nbctl create Logical_Router name=R1
8817
8818 # Connect inside to R1
8819 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8820 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8821 type=router options:router-port=inside \
8822 -- lsp-set-addresses rp-inside router
8823
8824 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8825 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8826
8827 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8828 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8829 --id=@gc1 create Gateway_Chassis \
8830 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8831 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8832
8833 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8834 type=router options:router-port=outside \
8835 -- lsp-set-addresses rp-outside router
8836
8837 # Create localnet port in outside
8838 ovn-nbctl lsp-add outside ln-outside
8839 ovn-nbctl lsp-set-addresses ln-outside unknown
8840 ovn-nbctl lsp-set-type ln-outside localnet
8841 ovn-nbctl lsp-set-options ln-outside network_name=phys
8842
8843 # Allow some time for ovn-northd and ovn-controller to catch up.
8844 ovn-nbctl --wait=hv --timeout=3 sync
8845
8846 # currently when ovn-controller is restarted, the old entry is deleted
8847 # and a new one is created, which leaves the Gateway_Chassis with
8848 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
8849 # doesn't have the same effect because "name" is conserved, and the
8850 # Chassis entry is not replaced.
8851
8852 > gw1/ovn-controller.log
8853
8854 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8855 ovn-sbctl destroy Chassis $gw2_chassis
8856
8857 # Ensure ovn-controller has processed latest sbdb update
8858 # ovn-nbctl --wait=hv sync
8859
8860 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
8861
8862 OVN_CLEANUP([gw1],[gw2],[hv1])
8863
8864 AT_CLEANUP
8865
8866 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
8867 AT_KEYWORDS([ovn-nd_ns for unknown mac])
8868 AT_SKIP_IF([test $HAVE_PYTHON = no])
8869 ovn_start
8870
8871 ovn-nbctl ls-add sw0_ip6
8872 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
8873 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
8874 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
8875
8876 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
8877 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
8878
8879 ovn-nbctl lr-add lr0_ip6
8880 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
8881 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
8882 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
8883 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
8884 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
8885 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
8886
8887 ovn-nbctl ls-add public
8888 ovn-nbctl lsp-add public ln-public
8889 ovn-nbctl lsp-set-addresses ln-public unknown
8890 ovn-nbctl lsp-set-type ln-public localnet
8891 ovn-nbctl lsp-set-options ln-public network_name=phys
8892
8893 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
8894 2001:db8:1:0:200:02ff:fe01:0204/64 \
8895 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
8896
8897
8898 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
8899 rp-ip6_public type=router options:router-port=ip6_public \
8900 -- lsp-set-addresses rp-ip6_public router
8901
8902 net_add n1
8903 sim_add hv1
8904 as hv1
8905 ovs-vsctl add-br br-phys
8906 ovn_attach n1 br-phys 192.168.0.2
8907
8908 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8909 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
8910 options:tx_pcap=hv1/vif1-tx.pcap \
8911 options:rxq_pcap=hv1/vif1-rx.pcap \
8912 ofport-request=1
8913 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8914
8915 # Allow some time for ovn-northd and ovn-controller to catch up.
8916 # XXX This should be more systematic.
8917 sleep 1
8918
8919 trim_zeros() {
8920 sed 's/\(00\)\{1,\}$//'
8921 }
8922
8923 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
8924 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
8925 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
8926 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
8927 # This function sends ipv6 packet
8928 test_ipv6() {
8929 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
8930 dst_ip=20010db800010000020002fffe010205
8931
8932 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
8933 packet=${packet}8000000000000000
8934 shift; shift; shift; shift
8935
8936 dst_mac=3333ff010205
8937 src_mac=000002010204
8938 mcast_node_ip=ff0200000000000000000001ff010205
8939 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
8940 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
8941 expected_packet=${expected_packet}0101${src_mac}
8942
8943 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
8944 echo $expected_packet >> ipv6_ns.expected
8945 }
8946
8947 src_mac=506400000002
8948 dst_mac=00000000af01
8949 src_ip=aef0000000000000526400fffe000002
8950 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
8951 # should be received by the ports attached to br-phys.
8952 test_ipv6 1 $src_mac $dst_mac $src_ip 2
8953
8954 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
8955 trim_zeros > 1.packets
8956 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
8957 trim_zeros > 2.packets
8958
8959 cat ipv6_ns.expected | cut -c -112 > expout
8960 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8961 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8962
8963 # Skipping the ICMPv6 checksum
8964 cat ipv6_ns.expected | cut -c 117- > expout
8965 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8966 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8967
8968 OVN_CLEANUP([hv1])
8969
8970 AT_CLEANUP
8971
8972 AT_SETUP([ovn -- options:requested-chassis for logical port])
8973 ovn_start
8974
8975 net_add n1
8976
8977 ovn-nbctl ls-add ls0
8978 ovn-nbctl lsp-add ls0 lsp0
8979
8980 # create two hypervisors, each with one vif port
8981 sim_add hv1
8982 as hv1
8983 ovs-vsctl add-br br-phys
8984 ovn_attach n1 br-phys 192.168.0.11
8985 ovs-vsctl -- add-port br-int hv1-vif0
8986
8987 sim_add hv2
8988 as hv2
8989 ovs-vsctl add-br br-phys
8990 ovn_attach n1 br-phys 192.168.0.12
8991 ovs-vsctl -- add-port br-int hv2-vif0
8992
8993 # Allow only chassis hv1 to bind logical port lsp0.
8994 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
8995
8996 # Allow some time for ovn-northd and ovn-controller to catch up.
8997 ovn-nbctl --wait=hv --timeout=3 sync
8998
8999 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
9000 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9001 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9002
9003 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9004 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9005 as hv2
9006 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9007
9008 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9009 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9010
9011 # (2) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9012 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9013 as hv1
9014 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9015
9016 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9017 AT_CHECK([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv1_uuid"], [0], [])
9018
9019 # (3) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9020 # the requested chassis for lsp0 is changed from hv1 to hv2.
9021 echo "verifying that lsp0 binding moves when requested-chassis is changed"
9022
9023 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9024 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9025 OVS_WAIT_UNTIL([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv2_uuid"])
9026
9027 OVN_CLEANUP([hv1],[hv2])
9028
9029 AT_CLEANUP
9030
9031 AT_SETUP([ovn -- options:requested-chassis with hostname])
9032
9033 ovn_start
9034
9035 ovn-nbctl ls-add ls0
9036 ovn-nbctl lsp-add ls0 lsp0
9037
9038 net_add n1
9039 sim_add hv1
9040 as hv1
9041 ovs-vsctl add-br br-phys
9042 ovn_attach n1 br-phys 192.168.0.11
9043 ovs-vsctl -- add-port br-int hv1-vif0
9044
9045 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9046 echo "hv1_hostname=${hv1_hostname}"
9047 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9048 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9049
9050 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9051 echo "hv1_uuid=${hv1_uuid}"
9052 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9053 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9054
9055 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9056 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9057 ovn-nbctl --wait=hv --timeout=3 sync
9058 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9059
9060 OVN_CLEANUP([hv1])
9061
9062 AT_CLEANUP