]> git.proxmox.com Git - mirror_ovs.git/blob - tests/ovn.at
OVN: introduce mac_prefix support to IPAM
[mirror_ovs.git] / tests / ovn.at
1 # OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2 #
3 # This compares packets read from PCAP, in pcap format, to those read
4 # from EXPECTED, which is a text file containing packets as hex
5 # strings, one per line. If PCAP contains fewer packets than
6 # EXPECTED, it waits up to 10 seconds for more packets to appear.
7 #
8 # The implementation is an m4 macro that is mostly implemented in
9 # terms of a shell function. This reduces the size of the generated
10 # testsuite file since the shell function is only emitted once even
11 # when this macro is invoked many times.
12 m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
20 OVS_WAIT_UNTIL(
21 [$PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 echo "rcv_n=$rcv_n exp_n=$exp_n"
24 test $rcv_n -ge $exp_n])
25 sort $exp_text > expout
26 }
27 ])
28 m4_define([OVN_CHECK_PACKETS],
29 [ovn_check_packets__ "$1" "$2"
30 AT_CHECK([sort $rcv_text], [0], [expout])])
31
32 AT_BANNER([OVN components])
33
34 AT_SETUP([ovn -- lexer])
35 dnl For lines without =>, input and expected output are identical.
36 dnl For lines with =>, input precedes => and expected output follows =>.
37 AT_DATA([test-cases.txt], [dnl
38 foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
39 "abc\u0020def" => "abc def"
40 " => error("Input ends inside quoted string.")dnl "
41
42 $foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
43 $1 => error("`$' must be followed by a valid identifier.") 1
44
45 a/*b*/c => a c
46 a//b c => a
47 a/**/b => a b
48 a/*/b => a error("`/*' without matching `*/'.")
49 a/*/**/b => a b
50 a/b => a error("`/' is only valid as part of `//' or `/*'.") b
51
52 0 1 12345 18446744073709551615
53 18446744073709551616 => error("Decimal constants must be less than 2**64.")
54 9999999999999999999999 => error("Decimal constants must be less than 2**64.")
55 01 => error("Decimal constants must not have leading zeros.")
56
57 0/0
58 0/1
59 1/0 => error("Value contains unmasked 1-bits.")
60 1/1
61 128/384
62 1/3
63 1/ => error("Integer constant expected.")
64
65 1/0x123 => error("Value and mask have incompatible formats.")
66
67 0x1234
68 0x01234 => 0x1234
69 0x0 => 0
70 0x000 => 0
71 0xfedcba9876543210
72 0XFEDCBA9876543210 => 0xfedcba9876543210
73 0xfedcba9876543210fedcba9876543210
74 0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
75 0x => error("Hex digits expected following 0x.")
76 0X => error("Hex digits expected following 0X.")
77 0x0/0x0 => 0/0
78 0x0/0x1 => 0/0x1
79 0x1/0x0 => error("Value contains unmasked 1-bits.")
80 0xffff/0x1ffff
81 0x. => error("Invalid syntax in hexadecimal constant.")
82
83 192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
84 256.1.2.3 => error("Invalid numeric constant.")
85 192.168.0.0/16
86 192.168.0.0/255.255.0.0 => 192.168.0.0/16
87 192.168.0.0/255.255.255.0 => 192.168.0.0/24
88 192.168.0.0/255.255.0.255
89 192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
90 192.168.0.0/32
91 192.168.0.0/255.255.255.255 => 192.168.0.0/32
92 1.2.3.4:5 => 1.2.3.4 : 5
93
94 ::
95 ::1
96 ff00::1234 => ff00::1234
97 2001:db8:85a3::8a2e:370:7334
98 2001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
99 2001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
100 ::ffff:192.0.2.128
101 ::ffff:c000:0280 => ::ffff:192.0.2.128
102 ::1/::1
103 ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
104 ::1/128
105 ff00::/8
106 ff00::/ff00:: => ff00::/8
107
108 01:23:45:67:ab:cd
109 01:23:45:67:AB:CD => 01:23:45:67:ab:cd
110 fe:dc:ba:98:76:54
111 FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
112 01:00:00:00:00:00/01:00:00:00:00:00
113 ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
114 fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
115 ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
116 fe:x => error("Invalid numeric constant.")
117 00:01:02:03:04:x => error("Invalid numeric constant.")
118
119 # Test that operators are tokenized as expected, even without white space.
120 (){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
121 & => error("`&' is only valid as part of `&&'.")
122 | => error("`|' is only valid as part of `||'.")
123 - => error("`-' is only valid as part of `--'.")
124
125 ^ => error("Invalid character `^' in input.")
126 ])
127 AT_CAPTURE_FILE([input.txt])
128 sed 's/ =>.*//' test-cases.txt > input.txt
129 sed 's/.* => //' test-cases.txt > expout
130 AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
131 AT_CLEANUP
132
133 dnl The OVN expression parser needs to know what fields overlap with one
134 dnl another. This test therefore verifies that all the smaller registers
135 dnl are defined as terms of subfields of the larger ones.
136 dnl
137 dnl When we add or remove registers this test needs to be updated, of course.
138 AT_SETUP([ovn -- registers])
139 AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
140 [[reg0 = xxreg0[96..127]
141 reg1 = xxreg0[64..95]
142 reg2 = xxreg0[32..63]
143 reg3 = xxreg0[0..31]
144 reg4 = xxreg1[96..127]
145 reg5 = xxreg1[64..95]
146 reg6 = xxreg1[32..63]
147 reg7 = xxreg1[0..31]
148 reg8 = xreg4[32..63]
149 reg9 = xreg4[0..31]
150 xreg0 = xxreg0[64..127]
151 xreg1 = xxreg0[0..63]
152 xreg2 = xxreg1[64..127]
153 xreg3 = xxreg1[0..63]
154 xreg4 = OXM_OF_PKT_REG4
155 xxreg0 = NXM_NX_XXREG0
156 xxreg1 = NXM_NX_XXREG1
157 ]])
158 AT_CLEANUP
159
160 dnl Check that the OVN conntrack field definitions are correct.
161 AT_SETUP([ovn -- conntrack fields])
162 AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
163 [[ct.dnat = ct_state[7]
164 ct.est = ct_state[1]
165 ct.inv = ct_state[4]
166 ct.new = ct_state[0]
167 ct.rel = ct_state[2]
168 ct.rpl = ct_state[3]
169 ct.snat = ct_state[6]
170 ct.trk = ct_state[5]
171 ct_label = NXM_NX_CT_LABEL
172 ct_label.blocked = ct_label[0]
173 ct_mark = NXM_NX_CT_MARK
174 ct_state = NXM_NX_CT_STATE
175 ]])
176 AT_CLEANUP
177
178 AT_SETUP([ovn -- composition])
179 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
180 AT_CLEANUP
181
182 AT_SETUP([ovn -- expression parser])
183 dnl For lines without =>, input and expected output are identical.
184 dnl For lines with =>, input precedes => and expected output follows =>.
185 AT_DATA([test-cases.txt], [[
186 eth.type == 0x800
187 eth.type==0x800 => eth.type == 0x800
188 eth.type[0..15] == 0x800 => eth.type == 0x800
189
190 vlan.present
191 vlan.present == 1 => vlan.present
192 !(vlan.present == 0) => vlan.present
193 !(vlan.present != 1) => vlan.present
194 !vlan.present
195 vlan.present == 0 => !vlan.present
196 vlan.present != 1 => !vlan.present
197 !(vlan.present == 1) => !vlan.present
198 !(vlan.present != 0) => !vlan.present
199
200 eth.dst[0]
201 eth.dst[0] == 1 => eth.dst[0]
202 eth.dst[0] != 0 => eth.dst[0]
203 !(eth.dst[0] == 0) => eth.dst[0]
204 !(eth.dst[0] != 1) => eth.dst[0]
205
206 !eth.dst[0]
207 eth.dst[0] == 0 => !eth.dst[0]
208 eth.dst[0] != 1 => !eth.dst[0]
209 !(eth.dst[0] == 1) => !eth.dst[0]
210 !(eth.dst[0] != 0) => !eth.dst[0]
211
212 vlan.tci[12..15] == 0x3
213 vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
214 vlan.tci[12..15] != 0x3
215 vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
216
217 !vlan.pcp => vlan.pcp == 0
218 !(vlan.pcp) => vlan.pcp == 0
219 vlan.pcp == 0x4
220 vlan.pcp != 0x4
221 vlan.pcp > 0x4
222 vlan.pcp >= 0x4
223 vlan.pcp < 0x4
224 vlan.pcp <= 0x4
225 !(vlan.pcp != 0x4) => vlan.pcp == 0x4
226 !(vlan.pcp == 0x4) => vlan.pcp != 0x4
227 !(vlan.pcp <= 0x4) => vlan.pcp > 0x4
228 !(vlan.pcp < 0x4) => vlan.pcp >= 0x4
229 !(vlan.pcp >= 0x4) => vlan.pcp < 0x4
230 !(vlan.pcp > 0x4) => vlan.pcp <= 0x4
231 0x4 == vlan.pcp => vlan.pcp == 0x4
232 0x4 != vlan.pcp => vlan.pcp != 0x4
233 0x4 < vlan.pcp => vlan.pcp > 0x4
234 0x4 <= vlan.pcp => vlan.pcp >= 0x4
235 0x4 > vlan.pcp => vlan.pcp < 0x4
236 0x4 >= vlan.pcp => vlan.pcp <= 0x4
237 !(0x4 != vlan.pcp) => vlan.pcp == 0x4
238 !(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
244 1 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
245 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
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 4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
250 4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
251 4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
252 4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
253 !(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
254 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
255 !(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
256 !(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
257 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
258 !(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
259 !(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
260 !(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
261 !(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
262
263 vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
264 vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
265
266 vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
267 vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
268
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 vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
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
273 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
274 ip6.src == ::1 => ip6.src == 0x1
275
276 ip4.src == 1.2.3.4 => ip4.src == 0x1020304
277 ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
278 ip6.src == ::1 => ip6.src == 0x1
279
280 1
281 0
282 !1 => 0
283 !0 => 1
284
285 inport == "eth0"
286 !(inport != "eth0") => inport == "eth0"
287
288 (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => 0
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 @name => Syntax error at `@name' expecting port group name.
308
309 123 == xyzzy => Syntax error at `xyzzy' expecting field name.
310 xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311
312 inport[1] == 1 => Cannot select subfield of string field inport.
313
314 eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
315 eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
316 eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317
318 eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319
320 eth.type[5..1] => Invalid bit range 5 to 1.
321
322 eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323
324 eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325
326 eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327
328 !(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329
330 123 => Syntax error at end of input expecting relational operator.
331
332 123 x => Syntax error at `x' expecting relational operator.
333
334 {1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335
336 eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337
338 (1 x) => Syntax error at `x' expecting `)'.
339
340 !0x800 != eth.type => Missing parentheses around operand of !.
341
342 eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343
344 eth.dst == {} => Syntax error at `}' expecting constant.
345
346 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).
347
348 ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
349
350 1 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
351
352 eth.dst[40] x => Syntax error at `x' expecting end of input.
353
354 ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
355 eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
356
357 ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => Parentheses nested too deeply.
358
359 ct_label > $set4 => Only == and != operators may be used to compare a field against an empty value set.
360 ]])
361 sed 's/ =>.*//' test-cases.txt > input.txt
362 sed 's/.* => //' test-cases.txt > expout
363 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
364 AT_CLEANUP
365
366 AT_SETUP([ovn -- expression annotation])
367 dnl Input precedes =>, expected output follows =>.
368 dnl Empty lines and lines starting with # are ignored.
369 AT_DATA([test-cases.txt], [[
370 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
371 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
372 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
373 ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
374 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
375
376 # Nested expressions over a single symbol should be annotated with symbol's
377 # prerequisites only once, at the top level.
378 tcp.dst == 1 || (tcp.dst >= 2 && tcp.dst <= 3) => (tcp.dst == 0x1 || (tcp.dst >= 0x2 && tcp.dst <= 0x3)) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
379
380 ip => eth.type == 0x800 || eth.type == 0x86dd
381 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
382 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
383 ip > 0 => Only == and != operators may be used with nominal field ip.
384 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
385 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
386
387 vlan.present => vlan.tci[12]
388 !vlan.present => !vlan.tci[12]
389
390 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
391 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
392 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
393
394 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
395 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
396 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
397
398 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
399 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
400 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'.
401 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'.
402 ]])
403 sed 's/ =>.*//' test-cases.txt > input.txt
404 sed 's/.* => //' test-cases.txt > expout
405 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
406 AT_CLEANUP
407
408 AT_SETUP([ovn -- 1-term expression conversion])
409 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
410 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
411 ])
412 AT_CLEANUP
413
414 AT_SETUP([ovn -- 2-term expression conversion])
415 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
416 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
417 ])
418 AT_CLEANUP
419
420 AT_SETUP([ovn -- 3-term expression conversion])
421 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
422 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
423 ])
424 AT_CLEANUP
425
426 AT_SETUP([ovn -- 3-term numeric expression simplification])
427 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
428 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
429 ])
430 AT_CLEANUP
431
432 AT_SETUP([ovn -- 4-term string expression simplification])
433 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
434 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
435 ])
436 AT_CLEANUP
437
438 AT_SETUP([ovn -- 3-term mixed expression simplification])
439 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
440 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
441 ])
442 AT_CLEANUP
443
444 AT_SETUP([ovn -- simplification special cases])
445 simplify() {
446 echo "$1" | ovstest test-ovn simplify-expr
447 }
448 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
449 ])
450 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
451 ])
452 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
453 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
454 ])
455 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
456 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
457 ])
458 AT_CHECK([simplify 'tcp.dst > 0'], [0],
459 [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
460 ]])
461 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
462 [[(!tcp.dst[0] || !tcp.dst[1] || !tcp.dst[2] || !tcp.dst[3] || !tcp.dst[4] || !tcp.dst[5] || !tcp.dst[6] || !tcp.dst[7] || !tcp.dst[8] || !tcp.dst[9] || !tcp.dst[10] || !tcp.dst[11] || !tcp.dst[12] || !tcp.dst[13] || !tcp.dst[14] || !tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
463 ]])
464 AT_CLEANUP
465
466 AT_SETUP([ovn -- is_chassis_resident simplification])
467 simplify() {
468 echo "$1" | ovstest test-ovn simplify-expr
469 }
470 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
471 ])
472 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
473 ])
474 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
475 ])
476 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
477 ])
478 AT_CLEANUP
479
480 AT_SETUP([ovn -- 4-term numeric expression normalization])
481 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
482 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
483 ])
484 AT_CLEANUP
485
486 AT_SETUP([ovn -- 4-term string expression normalization])
487 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
488 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
489 ])
490 AT_CLEANUP
491
492 AT_SETUP([ovn -- 4-term mixed expression normalization])
493 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
494 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
495 ])
496 AT_CLEANUP
497
498 AT_SETUP([ovn -- 5-term numeric expression normalization])
499 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
500 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
501 ])
502 AT_CLEANUP
503
504 AT_SETUP([ovn -- 5-term string expression normalization])
505 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
506 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
507 ])
508 AT_CLEANUP
509
510 AT_SETUP([ovn -- 5-term mixed expression normalization])
511 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
512 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
513 ])
514 AT_CLEANUP
515
516 AT_SETUP([ovn -- 4-term numeric expressions to flows])
517 AT_KEYWORDS([expression])
518 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
519 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
520 ])
521 AT_CLEANUP
522
523 AT_SETUP([ovn -- 4-term string expressions to flows])
524 AT_KEYWORDS([expression])
525 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
526 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
527 ])
528 AT_CLEANUP
529
530 AT_SETUP([ovn -- 4-term mixed expressions to flows])
531 AT_KEYWORDS([expression])
532 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
533 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
534 ])
535 AT_CLEANUP
536
537 AT_SETUP([ovn -- 3-term numeric expressions to flows])
538 AT_KEYWORDS([expression])
539 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
540 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
541 ])
542 AT_CLEANUP
543
544 AT_SETUP([ovn -- converting expressions to flows -- string fields])
545 AT_KEYWORDS([expression])
546 expr_to_flow () {
547 echo "$1" | ovstest test-ovn expr-to-flows | sort
548 }
549 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
550 ])
551 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
552 ])
553 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
554 ])
555 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
556 ip,reg14=0x5
557 ipv6,reg14=0x5
558 ])
559 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
560 ip,reg14=0x6
561 ipv6,reg14=0x6
562 ])
563 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
564 ])
565 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
566 [reg14=0x5
567 reg14=0x6
568 reg14=0xfffe
569 ])
570 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
571 ip,reg14=0x5
572 ip,reg14=0x6
573 ipv6,reg14=0x5
574 ipv6,reg14=0x6
575 ])
576 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
577 (no flows)
578 ])
579 AT_CLEANUP
580
581 AT_SETUP([ovn -- converting expressions to flows -- address sets])
582 AT_KEYWORDS([expression])
583 expr_to_flow () {
584 echo "$1" | ovstest test-ovn expr-to-flows | sort
585 }
586 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
587 ip,nw_src=10.0.0.1
588 ip,nw_src=10.0.0.2
589 ip,nw_src=10.0.0.3
590 ])
591 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
592 ip,nw_src=10.0.0.1
593 ip,nw_src=10.0.0.2
594 ip,nw_src=10.0.0.3
595 ])
596 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
597 ip,nw_src=1.2.3.4
598 ip,nw_src=10.0.0.1
599 ip,nw_src=10.0.0.2
600 ip,nw_src=10.0.0.3
601 ])
602 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
603 ip,nw_src=1.2.0.0/20
604 ip,nw_src=10.0.0.1
605 ip,nw_src=10.0.0.2
606 ip,nw_src=10.0.0.3
607 ip,nw_src=5.5.5.0/24
608 ])
609 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
610 ipv6,ipv6_src=::1
611 ipv6,ipv6_src=::2
612 ipv6,ipv6_src=::3
613 ])
614 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
615 ipv6,ipv6_src=::1
616 ipv6,ipv6_src=::2
617 ipv6,ipv6_src=::3
618 ipv6,ipv6_src=::4
619 ])
620 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
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 ])
625 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
626 dl_src=00:00:00:00:00:01
627 dl_src=00:00:00:00:00:02
628 dl_src=00:00:00:00:00:03
629 ])
630 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
631 dl_src=00:00:00:00:00:01
632 dl_src=00:00:00:00:00:02
633 dl_src=00:00:00:00:00:03
634 dl_src=ba:be:be:ef:de:ad
635 ])
636 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
637 (no flows)
638 ])
639 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
640 ip,nw_src=1.2.3.4
641 ])
642 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
643 ip,nw_src=1.2.3.4
644 ])
645 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
646
647 ])
648 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $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_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
659 ip,nw_src=0.0.0.0/1.0.0.0
660 ip,nw_src=128.0.0.0/1
661 ip,nw_src=16.0.0.0/16.0.0.0
662 ip,nw_src=2.0.0.0/2.0.0.0
663 ip,nw_src=32.0.0.0/32.0.0.0
664 ip,nw_src=4.0.0.0/4.0.0.0
665 ip,nw_src=64.0.0.0/64.0.0.0
666 ip,nw_src=8.0.0.0/8.0.0.0
667 ])
668 AT_CLEANUP
669
670 AT_SETUP([ovn -- converting expressions to flows -- port groups])
671 AT_KEYWORDS([expression])
672 expr_to_flow () {
673 echo "$1" | ovstest test-ovn expr-to-flows | sort
674 }
675 AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
676 reg15=0x11
677 reg15=0x12
678 reg15=0x13
679 ])
680 AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
681 (no flows)
682 ])
683 AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
684 reg15=0x11
685 ])
686 AT_CLEANUP
687
688 AT_SETUP([ovn -- converting expressions to flows -- conjunction])
689 AT_KEYWORDS([conjunction])
690 expr_to_flow () {
691 echo "$1" | ovstest test-ovn expr-to-flows | sort
692 }
693
694 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
695 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
696 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
697 conj_id=1,ip
698 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
699 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
700 ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
701 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
702 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
703 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
704 ])
705
706 lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
707 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
708 ct_state=+est+trk,ct_label=0x1/0x1,ip
709 ct_state=+est+trk,ct_label=0x1/0x1,ipv6
710 ct_state=-est+trk,ip
711 ct_state=-est+trk,ipv6
712 ])
713
714 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
715 ip4.dst == {20.0.0.1, 20.0.0.2}"
716 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
717 conj_id=1,ip
718 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
719 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
720 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
721 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
722 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
723 ])
724
725 lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
726 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
727 tcp.dst >= 1000 && tcp.dst <= 1010"
728
729 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
730 conj_id=1,tcp
731 tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
732 tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
733 tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
734 tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
735 tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
736 tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
737 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
738 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
739 tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
740 tcp,tp_dst=1000: conjunction(1, 2/3)
741 tcp,tp_dst=1001: conjunction(1, 2/3)
742 tcp,tp_dst=1010: conjunction(1, 2/3)
743 ])
744
745 lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
746 ((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
747 tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
748 || ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
749
750 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
751 conj_id=1,tcp
752 ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
753 ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
754 ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
755 ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
756 ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
757 ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
758 tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
759 tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
760 tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
761 tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
762 tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
763 tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
764 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
765 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
766 tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
767 tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
768 tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
769 tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
770 tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
771 tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
772 tcp,tp_dst=1000: conjunction(1, 2/4)
773 tcp,tp_dst=1001: conjunction(1, 2/4)
774 tcp,tp_dst=2000: conjunction(1, 2/4)
775 tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
776 tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
777 tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
778 tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
779 tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
780 tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
781 tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
782 tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
783 tcp,tp_src=1000: conjunction(1, 3/4)
784 tcp,tp_src=1001: conjunction(1, 3/4)
785 tcp,tp_src=2000: conjunction(1, 3/4)
786 ])
787 AT_CLEANUP
788
789 AT_SETUP([ovn -- action parsing])
790 dnl Unindented text is input (a set of OVN logical actions).
791 dnl Indented text is expected output.
792 AT_DATA([test-cases.txt],
793 [[# drop
794 drop;
795 encodes as drop
796 drop; next;
797 Syntax error at `next' expecting end of input.
798 next; drop;
799 Syntax error at `drop' expecting action.
800
801 # output
802 output;
803 encodes as resubmit(,64)
804
805 # next
806 next;
807 encodes as resubmit(,19)
808 next(11);
809 formats as next;
810 encodes as resubmit(,19)
811 next(0);
812 encodes as resubmit(,8)
813 next(23);
814 encodes as resubmit(,31)
815
816 next();
817 Syntax error at `)' expecting "pipeline" or "table".
818 next(10;
819 Syntax error at `;' expecting `)'.
820 next(24);
821 "next" action cannot advance beyond table 23.
822
823 next(table=11);
824 formats as next;
825 encodes as resubmit(,19)
826 next(pipeline=ingress);
827 formats as next;
828 encodes as resubmit(,19)
829 next(table=11, pipeline=ingress);
830 formats as next;
831 encodes as resubmit(,19)
832 next(pipeline=ingress, table=11);
833 formats as next;
834 encodes as resubmit(,19)
835
836 next(pipeline=egress);
837 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
838
839 next(table=10);
840 formats as next(10);
841 encodes as resubmit(,18)
842
843 # Loading a constant value.
844 tcp.dst=80;
845 formats as tcp.dst = 80;
846 encodes as set_field:80->tcp_dst
847 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
848 eth.dst[40] = 1;
849 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
850 vlan.pcp = 2;
851 encodes as set_field:0x4000/0xe000->vlan_tci
852 has prereqs vlan.tci[12]
853 vlan.tci[13..15] = 2;
854 encodes as set_field:0x4000/0xe000->vlan_tci
855 inport = "";
856 encodes as set_field:0->reg14
857 ip.ttl=4;
858 formats as ip.ttl = 4;
859 encodes as set_field:4->nw_ttl
860 has prereqs eth.type == 0x800 || eth.type == 0x86dd
861 outport="eth0"; next; outport="LOCAL"; next;
862 formats as outport = "eth0"; next; outport = "LOCAL"; next;
863 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
864
865 inport[1] = 1;
866 Cannot select subfield of string field inport.
867 ip.proto[1] = 1;
868 Cannot select subfield of nominal field ip.proto.
869 eth.dst[40] == 1;
870 Syntax error at `==' expecting `=' or `<->'.
871 ip = 1;
872 Predicate symbol ip used where lvalue required.
873 ip.proto = 6;
874 Field ip.proto is not modifiable.
875 inport = {"a", "b"};
876 Syntax error at `{' expecting constant.
877 inport = {};
878 Syntax error at `{' expecting constant.
879 bad_prereq = 123;
880 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
881 self_recurse = 123;
882 Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
883 vlan.present = 0;
884 Predicate symbol vlan.present used where lvalue required.
885
886 # Moving one field into another.
887 reg0=reg1;
888 formats as reg0 = reg1;
889 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
890 vlan.pcp = reg0[0..2];
891 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
892 has prereqs vlan.tci[12]
893 reg0[10] = vlan.pcp[1];
894 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
895 has prereqs vlan.tci[12]
896 outport = inport;
897 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
898
899 reg0[0] = vlan.present;
900 Predicate symbol vlan.present used where lvalue required.
901 reg0 = reg1[0..10];
902 Can't assign 11-bit value to 32-bit destination.
903 inport = reg0;
904 Can't assign integer field (reg0) to string field (inport).
905 inport = big_string;
906 String fields inport and big_string are incompatible for assignment.
907 ip.proto = reg0[0..7];
908 Field ip.proto is not modifiable.
909
910 # Exchanging fields.
911 reg0 <-> reg1;
912 encodes as push:NXM_NX_XXREG0[64..95],push:NXM_NX_XXREG0[96..127],pop:NXM_NX_XXREG0[64..95],pop:NXM_NX_XXREG0[96..127]
913 vlan.pcp <-> reg0[0..2];
914 encodes as push:NXM_NX_XXREG0[96..98],push:NXM_OF_VLAN_TCI[13..15],pop:NXM_NX_XXREG0[96..98],pop:NXM_OF_VLAN_TCI[13..15]
915 has prereqs vlan.tci[12]
916 reg0[10] <-> vlan.pcp[1];
917 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
918 has prereqs vlan.tci[12]
919 outport <-> inport;
920 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
921
922 reg0[0] <-> vlan.present;
923 Predicate symbol vlan.present used where lvalue required.
924 reg0 <-> reg1[0..10];
925 Can't exchange 32-bit field with 11-bit field.
926 inport <-> reg0;
927 Can't exchange string field (inport) with integer field (reg0).
928 inport <-> big_string;
929 String fields inport and big_string are incompatible for exchange.
930 ip.proto <-> reg0[0..7];
931 Field ip.proto is not modifiable.
932 reg0[0..7] <-> ip.proto;
933 Field ip.proto is not modifiable.
934
935 # TTL decrement.
936 ip.ttl--;
937 encodes as dec_ttl
938 has prereqs ip
939 ip.ttl
940 Syntax error at end of input expecting `--'.
941
942 # load balancing.
943 ct_lb;
944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
945 has prereqs ip
946 ct_lb();
947 formats as ct_lb;
948 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
949 has prereqs ip
950 ct_lb(192.168.1.2:80, 192.168.1.3:80);
951 encodes as group:1
952 has prereqs ip
953 ct_lb(192.168.1.2, 192.168.1.3, );
954 formats as ct_lb(192.168.1.2, 192.168.1.3);
955 encodes as group:2
956 has prereqs ip
957 ct_lb(fd0f::2, fd0f::3, );
958 formats as ct_lb(fd0f::2, fd0f::3);
959 encodes as group:3
960 has prereqs ip
961
962 ct_lb(192.168.1.2:);
963 Syntax error at `)' expecting port number.
964 ct_lb(192.168.1.2:123456);
965 Syntax error at `123456' expecting port number.
966 ct_lb(foo);
967 Syntax error at `foo' expecting IP address.
968 ct_lb([192.168.1.2]);
969 Syntax error at `192.168.1.2' expecting IPv6 address.
970
971 # ct_next
972 ct_next;
973 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
974 has prereqs ip
975
976 # ct_commit
977 ct_commit;
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
979 has prereqs ip
980 ct_commit();
981 formats as ct_commit;
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
983 has prereqs ip
984 ct_commit(ct_mark=1);
985 formats as ct_commit(ct_mark=0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
987 has prereqs ip
988 ct_commit(ct_mark=1/1);
989 formats as ct_commit(ct_mark=0x1/0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
991 has prereqs ip
992 ct_commit(ct_label=1);
993 formats as ct_commit(ct_label=0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
995 has prereqs ip
996 ct_commit(ct_label=1/1);
997 formats as ct_commit(ct_label=0x1/0x1);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
999 has prereqs ip
1000 ct_commit(ct_mark=1, ct_label=2);
1001 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
1002 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
1003 has prereqs ip
1004
1005 ct_commit(ct_label=0x01020304050607080910111213141516);
1006 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1008 has prereqs ip
1009 ct_commit(ct_label=0x181716151413121110090807060504030201);
1010 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1011 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1012 has prereqs ip
1013 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1015 has prereqs ip
1016 ct_commit(ct_label=18446744073709551615);
1017 formats as ct_commit(ct_label=0xffffffffffffffff);
1018 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1019 has prereqs ip
1020 ct_commit(ct_label=18446744073709551616);
1021 Decimal constants must be less than 2**64.
1022
1023 # ct_dnat
1024 ct_dnat;
1025 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
1026 has prereqs ip
1027 ct_dnat(192.168.1.2);
1028 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
1029 has prereqs ip
1030
1031 ct_dnat(192.168.1.2, 192.168.1.3);
1032 Syntax error at `,' expecting `)'.
1033 ct_dnat(foo);
1034 Syntax error at `foo' expecting IPv4 address.
1035 ct_dnat(foo, bar);
1036 Syntax error at `foo' expecting IPv4 address.
1037 ct_dnat();
1038 Syntax error at `)' expecting IPv4 address.
1039
1040 # ct_snat
1041 ct_snat;
1042 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
1043 has prereqs ip
1044 ct_snat(192.168.1.2);
1045 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
1046 has prereqs ip
1047
1048 ct_snat(192.168.1.2, 192.168.1.3);
1049 Syntax error at `,' expecting `)'.
1050 ct_snat(foo);
1051 Syntax error at `foo' expecting IPv4 address.
1052 ct_snat(foo, bar);
1053 Syntax error at `foo' expecting IPv4 address.
1054 ct_snat();
1055 Syntax error at `)' expecting IPv4 address.
1056
1057 # ct_clear
1058 ct_clear;
1059 encodes as ct_clear
1060
1061 # clone
1062 clone { ip4.dst = 255.255.255.255; output; }; next;
1063 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
1064 has prereqs eth.type == 0x800
1065
1066 # arp
1067 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1068 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1069 has prereqs ip4
1070 arp { };
1071 formats as arp { drop; };
1072 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1073 has prereqs ip4
1074
1075 # get_arp
1076 get_arp(outport, ip4.dst);
1077 encodes as push:NXM_NX_REG0[],push:NXM_OF_IP_DST[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[]
1078 has prereqs eth.type == 0x800
1079 get_arp(inport, reg0);
1080 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG0[],push:NXM_NX_XXREG0[96..127],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[],pop:NXM_NX_REG15[]
1081
1082 get_arp;
1083 Syntax error at `;' expecting `('.
1084 get_arp();
1085 Syntax error at `)' expecting field name.
1086 get_arp(inport);
1087 Syntax error at `)' expecting `,'.
1088 get_arp(inport ip4.dst);
1089 Syntax error at `ip4.dst' expecting `,'.
1090 get_arp(inport, ip4.dst;
1091 Syntax error at `;' expecting `)'.
1092 get_arp(inport, eth.dst);
1093 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1094 get_arp(inport, outport);
1095 Cannot use string field outport where numeric field is required.
1096 get_arp(reg0, ip4.dst);
1097 Cannot use numeric field reg0 where string field is required.
1098
1099 # put_arp
1100 put_arp(inport, arp.spa, arp.sha);
1101 encodes as push:NXM_NX_REG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ARP_SHA[],push:NXM_OF_ARP_SPA[],pop:NXM_NX_REG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.01.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_REG0[]
1102 has prereqs eth.type == 0x806 && eth.type == 0x806
1103
1104 # put_dhcp_opts
1105 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1106 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.40.01.02.03.04.03.04.0a.00.00.01,pause)
1107 reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org",wpad="https://example.org");
1108 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain = "ovn.org", wpad = "https://example.org");
1109 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67,pause)
1110 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);
1111 formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, ethernet_encap = 1, router_discovery = 0);
1112 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00,pause)
1113
1114 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1115 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1116 reg1[0] = put_dhcp_opts();
1117 put_dhcp_opts requires offerip to be specified.
1118 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1119 Syntax error at `x' expecting DHCPv4 option name.
1120 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1121 put_dhcp_opts requires offerip to be specified.
1122 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1123 Syntax error at `"hi"'.
1124 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1125 Syntax error at `xyzzy' expecting DHCPv4 option name.
1126 reg1[0] = put_dhcp_opts(offerip="xyzzy");
1127 DHCPv4 option offerip requires numeric value.
1128 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1129 DHCPv4 option domain requires string value.
1130
1131 # nd_ns
1132 nd_ns { nd.target = xxreg0; output; };
1133 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1134 has prereqs ip6
1135
1136 nd_ns { };
1137 formats as nd_ns { drop; };
1138 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1139 has prereqs ip6
1140
1141 # nd_na
1142 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; };
1143 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1144 encodes as controller(userdata=00.00.00.03.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1145 has prereqs nd_ns
1146 # nd_na_router
1147 nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1148 formats as nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1149 encodes as controller(userdata=00.00.00.0c.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1150 has prereqs nd_ns
1151
1152 # get_nd
1153 get_nd(outport, ip6.dst);
1154 encodes as push:NXM_NX_XXREG0[],push:NXM_NX_IPV6_DST[],pop:NXM_NX_XXREG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_XXREG0[]
1155 has prereqs eth.type == 0x86dd
1156 get_nd(inport, xxreg0);
1157 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG15[]
1158 get_nd;
1159 Syntax error at `;' expecting `('.
1160 get_nd();
1161 Syntax error at `)' expecting field name.
1162 get_nd(inport);
1163 Syntax error at `)' expecting `,'.
1164 get_nd(inport ip6.dst);
1165 Syntax error at `ip6.dst' expecting `,'.
1166 get_nd(inport, ip6.dst;
1167 Syntax error at `;' expecting `)'.
1168 get_nd(inport, eth.dst);
1169 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1170 get_nd(inport, outport);
1171 Cannot use string field outport where numeric field is required.
1172 get_nd(xxreg0, ip6.dst);
1173 Cannot use numeric field xxreg0 where string field is required.
1174
1175 # put_nd
1176 put_nd(inport, nd.target, nd.sll);
1177 encodes as push:NXM_NX_XXREG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ND_SLL[],push:NXM_NX_ND_TARGET[],pop:NXM_NX_XXREG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.04.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_XXREG0[]
1178 has prereqs (icmp6.type == 0x87 || icmp6.type == 0x88) && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
1179
1180 # put_dhcpv6_opts
1181 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1182 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.05.00.10.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.00.02.00.06.00.00.00.00.10.02,pause)
1183 reg1[0] = put_dhcpv6_opts();
1184 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1185 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1186 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1187 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
1188 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1189 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1190 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.02.00.06.12.34.56.78.9a.bc.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.89.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
1191 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1192 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.18.00.07.6f.76.6e.2e.6f.72.67,pause)
1193 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1194 Syntax error at `x' expecting DHCPv6 option name.
1195 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1196 Syntax error at `"hi"'.
1197 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1198 Syntax error at `xyzzy' expecting DHCPv6 option name.
1199 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1200 DHCPv6 option ia_addr requires numeric value.
1201 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1202 DHCPv6 option domain_search requires string value.
1203
1204 # set_queue
1205 set_queue(0);
1206 encodes as set_queue:0
1207 set_queue(61440);
1208 encodes as set_queue:61440
1209 set_queue(65535);
1210 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1211
1212 # dns_lookup
1213 reg1[0] = dns_lookup();
1214 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1215 has prereqs udp
1216 reg1[0] = dns_lookup("foo");
1217 dns_lookup doesn't take any parameters
1218
1219 # set_meter
1220 set_meter(0);
1221 Rate 0 for set_meter is not in valid.
1222 set_meter(1);
1223 encodes as meter:1
1224 set_meter(100, 1000);
1225 encodes as meter:2
1226 set_meter(100, 1000, );
1227 Syntax error at `,' expecting `)'.
1228 set_meter(4294967295, 4294967295);
1229 encodes as meter:3
1230
1231 # log
1232 log(verdict=allow, severity=warning);
1233 encodes as controller(userdata=00.00.00.07.00.00.00.00.00.04)
1234 log(name="test1", verdict=drop, severity=info);
1235 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31)
1236 log(verdict=drop, severity=info, meter="meter1");
1237 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06,meter_id=4)
1238 log(name="test1", verdict=drop, severity=info, meter="meter1");
1239 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31,meter_id=4)
1240 log(verdict=drop);
1241 formats as log(verdict=drop, severity=info);
1242 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06)
1243 log(verdict=bad_verdict, severity=info);
1244 Syntax error at `bad_verdict' unknown verdict.
1245 log(verdict=drop, severity=bad_severity);
1246 Syntax error at `bad_severity' unknown severity.
1247 log(severity=notice);
1248 Syntax error at `;' expecting verdict.
1249
1250 # put_nd_ra_opts
1251 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1252 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
1253 has prereqs ip6
1254 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1255 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
1256 has prereqs ip6
1257 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1258 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
1259 has prereqs ip6
1260 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1261 slla option not present
1262 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);
1263 prefix option can't be set when address mode is dhcpv6_stateful.
1264 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);
1265 prefix option can't be set when address mode is dhcpv6_stateful.
1266 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1267 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1268 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1269 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1270 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1271 Syntax error at `dhcpv6_stateless' expecting constant.
1272 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1273 Invalid value for "prefix" option
1274 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1275 Invalid value for "addr_mode" option
1276 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1277 IPv6 ND RA option mtu requires numeric value.
1278 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1279 Invalid value for "mtu" option
1280
1281 # icmp4
1282 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1283 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1284 has prereqs ip4
1285
1286 icmp4 { };
1287 formats as icmp4 { drop; };
1288 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1289 has prereqs ip4
1290
1291 # icmp6
1292 icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1293 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1294 has prereqs ip6
1295
1296 icmp6 { };
1297 formats as icmp6 { drop; };
1298 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1299 has prereqs ip6
1300
1301 # tcp_reset
1302 tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1303 encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1304 has prereqs tcp
1305
1306 tcp_reset { };
1307 formats as tcp_reset { drop; };
1308 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1309 has prereqs tcp
1310
1311 # Contradictionary prerequisites (allowed but not useful):
1312 ip4.src = ip6.src[0..31];
1313 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1314 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1315 ip4.src <-> ip6.src[0..31];
1316 encodes as push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[]
1317 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1318
1319 # Miscellaneous negative tests.
1320 ;
1321 Syntax error at `;'.
1322 xyzzy;
1323 Syntax error at `xyzzy' expecting action.
1324 next; 123;
1325 Syntax error at `123'.
1326 next; xyzzy;
1327 Syntax error at `xyzzy' expecting action.
1328 next
1329 Syntax error at end of input expecting `;'.
1330 ]])
1331 sed '/^[[ ]]/d' test-cases.txt > input.txt
1332 cp test-cases.txt expout
1333 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1334 AT_CLEANUP
1335
1336 AT_BANNER([OVN end-to-end tests])
1337
1338 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1339 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1340 AT_KEYWORDS([ovnarp])
1341 AT_SKIP_IF([test $HAVE_PYTHON = no])
1342 ovn_start
1343
1344 # Create hypervisors hv[123].
1345 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1346 # Add all of the vifs to a single logical switch lsw0.
1347 # Turn on port security on all the vifs except vif[123]1.
1348 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1349 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1350 ovn-nbctl ls-add lsw0
1351 net_add n1
1352 for i in 1 2 3; do
1353 sim_add hv$i
1354 as hv$i
1355 ovs-vsctl add-br br-phys
1356 ovn_attach n1 br-phys 192.168.0.$i
1357
1358 for j in 1 2 3; do
1359 ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
1360 ovn-nbctl lsp-add lsw0 lp$i$j
1361 if test $j = 1; then
1362 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1363 else
1364 if test $j = 3; then
1365 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1366 else
1367 ip_addrs="192.168.0.$i$j"
1368 fi
1369 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1370 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1371 fi
1372 done
1373 done
1374 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1375 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1376 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1377 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\"
1378 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1379
1380 get_lsp_uuid () {
1381 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1382 }
1383
1384 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1385 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1386
1387 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1388 # packets for ARP resolution (native tunneling doesn't queue packets
1389 # for ARP resolution).
1390 OVN_POPULATE_ARP
1391
1392 # Allow some time for ovn-northd and ovn-controller to catch up.
1393 # XXX This should be more systematic.
1394 sleep 1
1395
1396 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1397 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1398 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1399 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1400
1401 # Given the name of a logical port, prints the name of the hypervisor
1402 # on which it is located.
1403 vif_to_hv() {
1404 echo hv${1%?}
1405 }
1406
1407 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1408 #
1409 # This shell function causes a packet to be received on INPORT. The packet's
1410 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1411 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1412 # more) list the VIFs on which the packet should be received. INPORT and the
1413 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1414 for i in 1 2 3; do
1415 for j in 1 2 3; do
1416 : > $i$j.expected
1417 done
1418 done
1419 test_packet() {
1420 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1421 hv=`vif_to_hv $inport`
1422 vif=vif$inport
1423 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1424 for outport; do
1425 echo $packet >> $outport.expected
1426 done
1427 }
1428
1429 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1430 #
1431 # Causes a packet to be received on INPORT. The packet is an ARP
1432 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1433 # it should be the hardware address of the target to expect to receive in an
1434 # ARP reply; otherwise no reply is expected.
1435 #
1436 # INPORT is an logical switch port number, e.g. 11 for vif11.
1437 # SHA and REPLY_HA are each 12 hex digits.
1438 # SPA and TPA are each 8 hex digits.
1439 test_arp() {
1440 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1441 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1442 hv=`vif_to_hv $inport`
1443 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1444
1445 if test X$reply_ha = X; then
1446 # Expect to receive the broadcast ARP on the other logical switch ports
1447 # if no reply is expected.
1448 local i j
1449 for i in 1 2 3; do
1450 for j in 1 2 3; do
1451 if test $i$j != $inport; then
1452 echo $request >> $i$j.expected
1453 fi
1454 done
1455 done
1456 else
1457 # Expect to receive the reply, if any.
1458 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1459 echo $reply >> $inport.expected
1460 fi
1461 }
1462
1463 ip_to_hex() {
1464 printf "%02x%02x%02x%02x" "$@"
1465 }
1466
1467 # Send packets between all pairs of source and destination ports:
1468 #
1469 # 1. Unicast packets are delivered to exactly one logical switch port
1470 # (except that packets destined to their input ports are dropped).
1471 #
1472 # 2. Broadcast and multicast are delivered to all logical switch ports
1473 # except the input port.
1474 #
1475 # 3. When port security is turned on, the switch drops packets from the wrong
1476 # MAC address.
1477 #
1478 # 4. The switch drops all packets with a VLAN tag.
1479 #
1480 # 5. The switch drops all packets with a multicast source address. (This only
1481 # affects behavior when port security is turned off, since otherwise port
1482 # security would drop the packet anyway.)
1483 #
1484 # 6. The switch delivers packets with an unknown destination to logical
1485 # switch ports with "unknown" among their MAC addresses (and port
1486 # security disabled).
1487 #
1488 # 7. The switch drops unicast packets that violate an ACL.
1489 #
1490 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1491 #
1492 # 9. OVN generates responses to ARP requests for known IPs, except for
1493 # requests from a port for the port's own IP.
1494 #
1495 # 10. No response to ARP requests for unknown IPs.
1496
1497 for is in 1 2 3; do
1498 for js in 1 2 3; do
1499 s=$is$js
1500 bcast=
1501 unknown=
1502 bacl2=
1503 bacl3=
1504 for id in 1 2 3; do
1505 for jd in 1 2 3; do
1506 d=$id$jd
1507
1508 if test $d != $s; then unicast=$d; else unicast=; fi
1509 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1510
1511 if test $d != $s && test $js = 1; then
1512 impersonate=$d
1513 else
1514 impersonate=
1515 fi
1516 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1517
1518 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1519 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1520 if test $d = $s || (test $js = 1 && test $d = 33); then
1521 # Source of 11, 21, or 31 and dest of 33 should be dropped
1522 # due to the 4th ACL that uses address_set(set1).
1523 acl4=
1524 else
1525 acl4=$d
1526 fi
1527 if test $d = $s || test $d = 22 || test $d = 33; then
1528 # dest of 22 and 33 should be dropped
1529 # due to the 5th ACL that uses port_group(pg1).
1530 acl5=
1531 else
1532 acl5=$d
1533 fi
1534 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1535 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1536 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1537 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1538 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
1539
1540 test_packet $s f000000000$d f00000000055 810000091234 #4
1541 test_packet $s f000000000$d 0100000000$s $s$d #5
1542
1543 if test $d != $s && test $jd = 1; then
1544 unknown="$unknown $d"
1545 fi
1546 bcast="$bcast $unicast"
1547 bacl2="$bacl2 $acl2"
1548 bacl3="$bacl3 $acl3"
1549
1550 sip=`ip_to_hex 192 168 0 $is$js`
1551 tip=`ip_to_hex 192 168 0 $id$jd`
1552 tip_unknown=`ip_to_hex 11 11 11 11`
1553 if test $d != $s; then
1554 reply_ha=f000000000$d
1555 else
1556 reply_ha=
1557 fi
1558 test_arp $s f000000000$s $sip $tip $reply_ha #9
1559 test_arp $s f000000000$s $sip $tip_unknown #10
1560
1561 if test $jd = 3; then
1562 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1563 tip=`ip_to_hex 192 169 0 $id$jd`
1564 test_arp $s f000000000$s $sip $tip $reply_ha #9
1565 fi
1566 done
1567 done
1568
1569 # Broadcast and multicast.
1570 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1571 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1572 if test $js = 1; then
1573 bcast_impersonate=$bcast
1574 else
1575 bcast_impersonate=
1576 fi
1577 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1578
1579 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1580
1581 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1582 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1583 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1584 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1585 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1586 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1587 done
1588 done
1589
1590 # set address for lp13 with invalid characters.
1591 # lp13 should be configured with only 192.168.0.13.
1592 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1593
1594 # Allow some time for ovn-northd and ovn-controller to catch up.
1595 # XXX This should be more systematic.
1596 sleep 1
1597
1598 sip=`ip_to_hex 192 168 0 11`
1599 tip=`ip_to_hex 192 168 0 13`
1600 test_arp 11 f00000000011 $sip $tip f00000000013
1601
1602 tip=`ip_to_hex 192 169 0 13`
1603 #arp request for 192.169.0.13 should be flooded
1604 test_arp 11 f00000000011 $sip $tip
1605
1606 # dump information and flows with counters
1607 ovn-sbctl dump-flows -- list multicast_group
1608
1609 echo "------ hv1 dump ------"
1610 as hv1 ovs-vsctl show
1611 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1612
1613 echo "------ hv2 dump ------"
1614 as hv2 ovs-vsctl show
1615 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1616
1617 echo "------ hv3 dump ------"
1618 as hv3 ovs-vsctl show
1619 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1620
1621 # Now check the packets actually received against the ones expected.
1622 for i in 1 2 3; do
1623 for j in 1 2 3; do
1624 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1625 done
1626 done
1627
1628 OVN_CLEANUP([hv1],[hv2],[hv3])
1629
1630 AT_CLEANUP
1631
1632 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1633 AT_SKIP_IF([test $HAVE_PYTHON = no])
1634 ovn_start
1635
1636 # Create a logical switch and some logical ports.
1637 # Turn on port security on all lports except ls1.
1638 # Make ls1 a destination for unknown MACs.
1639 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1640 ovn-nbctl ls-add lsw0
1641 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1642 for i in 1 2 3; do
1643 ovn-nbctl lsp-add lsw0 lp$i
1644 done
1645 ovn-nbctl --wait=sb sync
1646 for i in 1 2 3; do
1647 ovn-sbctl lsp-bind lp$i hv0
1648 if test $i = 1; then
1649 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1650 else
1651 if test $i = 3; then
1652 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1653 else
1654 ip_addrs="192.168.0.$i"
1655 fi
1656 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1657 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1658 fi
1659 done
1660 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1661 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1662 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1663 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1664 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1665
1666 ovn-nbctl --wait=sb sync
1667 on_exit 'kill `cat ovn-trace.pid`'
1668 ovn-trace --detach --pidfile --no-chdir
1669
1670 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1671 #
1672 # This shell function causes a packet to be received on INPORT. The packet's
1673 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1674 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1675 # more) list the VIFs on which the packet should be received. INPORT and the
1676 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1677 test_packet() {
1678 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1679 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1680 while :; do
1681 case $1 in # (
1682 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1683 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1684 *) break ;;
1685 esac
1686 done
1687 for outport; do
1688 echo "output(\"lp$outport\");"
1689 done > expout
1690
1691 AT_CAPTURE_FILE([trace])
1692 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1693 }
1694
1695 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1696 #
1697 # Causes a packet to be received on INPORT. The packet is an ARP
1698 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1699 # it should be the hardware address of the target to expect to receive in an
1700 # ARP reply; otherwise no reply is expected.
1701 #
1702 # INPORT is an logical switch port number, e.g. 11 for vif11.
1703 # SHA and REPLY_HA are each 12 hex digits.
1704 # SPA and TPA are each 8 hex digits.
1705 test_arp() {
1706 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1707
1708 local request="inport == \"lp$inport\"
1709 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1710 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1711 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1712
1713 if test -z "$reply_ha"; then
1714 reply=
1715 local i
1716 for i in 1 2 3; do
1717 if test $i != $inport; then
1718 reply="${reply}output(\"lp$i\");
1719 "
1720 fi
1721 done
1722 else
1723 reply="\
1724 eth.dst = $sha;
1725 eth.src = $reply_ha;
1726 arp.op = 2;
1727 arp.tha = $sha;
1728 arp.sha = $reply_ha;
1729 arp.tpa = $spa;
1730 arp.spa = $tpa;
1731 output(\"lp$inport\");
1732 "
1733 fi
1734
1735 AT_CAPTURE_FILE([trace])
1736 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1737 }
1738
1739 # Send packets between all pairs of source and destination ports:
1740 #
1741 # 1. Unicast packets are delivered to exactly one logical switch port
1742 # (except that packets destined to their input ports are dropped).
1743 #
1744 # 2. Broadcast and multicast are delivered to all logical switch ports
1745 # except the input port.
1746 #
1747 # 3. When port security is turned on, the switch drops packets from the wrong
1748 # MAC address.
1749 #
1750 # 4. The switch drops all packets with a VLAN tag.
1751 #
1752 # 5. The switch drops all packets with a multicast source address. (This only
1753 # affects behavior when port security is turned off, since otherwise port
1754 # security would drop the packet anyway.)
1755 #
1756 # 6. The switch delivers packets with an unknown destination to logical
1757 # switch ports with "unknown" among their MAC addresses (and port
1758 # security disabled).
1759 #
1760 # 7. The switch drops unicast packets that violate an ACL.
1761 #
1762 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1763 #
1764 # 9. OVN generates responses to ARP requests for known IPs, except for
1765 # requests from a port for the port's own IP.
1766 #
1767 # 10. No response to ARP requests for unknown IPs.
1768
1769 for s in 1 2 3; do
1770 bcast=
1771 unknown=
1772 bacl2=
1773 bacl3=
1774 for d in 1 2 3; do
1775 echo
1776 echo "lp$s -> lp$d"
1777 if test $d != $s; then unicast=$d; else unicast=; fi
1778 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1779
1780 if test $d != $s && test $s = 1; then
1781 impersonate=$d
1782 else
1783 impersonate=
1784 fi
1785 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1786
1787 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1788 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1789 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1790 # Source of 1 or 2 and dest of 3 should be dropped
1791 # due to the 4th ACL that uses address_set(set1).
1792 acl4=
1793 else
1794 acl4=$d
1795 fi
1796
1797 #7, acl1 to acl4:
1798 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1799 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1800 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1801 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1802
1803 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1804 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1805
1806 if test $d != $s && test $d = 1; then
1807 unknown="$unknown $d"
1808 fi
1809 bcast="$bcast $unicast"
1810 bacl2="$bacl2 $acl2"
1811 bacl3="$bacl3 $acl3"
1812
1813 sip=192.168.0.$s
1814 tip=192.168.0.$d
1815 tip_unknown=11.11.11.11
1816 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1817 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1818 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1819
1820 if test $d = 3; then
1821 # lp3 has an additional ip 192.169.0.[123]3.
1822 tip=192.169.0.$d
1823 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1824 fi
1825 done
1826
1827 # Broadcast and multicast.
1828 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1829 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1830 if test $s = 1; then
1831 bcast_impersonate=$bcast
1832 else
1833 bcast_impersonate=
1834 fi
1835 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1836
1837 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1838
1839 #8, acl1 to acl3:
1840 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1841 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1842 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1843
1844 #8, acl1 to acl3:
1845 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1846 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1847 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1848 done
1849
1850 AT_CLEANUP
1851
1852 # 2 hypervisors, 4 logical ports per HV
1853 # 2 locally attached networks (one flat, one vlan tagged over same device)
1854 # 2 ports per HV on each network
1855 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1856 AT_SKIP_IF([test $HAVE_PYTHON = no])
1857 ovn_start
1858
1859 # In this test cases we create 3 switches, all connected to same
1860 # physical network (through br-phys on each HV). Each switch has
1861 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1862 # of VIF port name indicates the hypervisor it is bound to, e.g.
1863 # lp23 means VIF 3 on hv2.
1864 #
1865 # Each switch's VLAN tag and their logical switch ports are:
1866 # - ls1:
1867 # - untagged
1868 # - ports: lp11, lp12, lp21, lp22
1869 #
1870 # - ls2:
1871 # - tagged with VLAN 101
1872 # - ports: lp13, lp14, lp23, lp24
1873 # - ls3:
1874 # - untagged
1875 # - ports: lp15, lp25
1876 #
1877 # Note: a localnet port is created for each switch to connect to
1878 # physical network.
1879
1880 for i in 1 2 3; do
1881 ls_name=ls$i
1882 ovn-nbctl ls-add $ls_name
1883 ln_port_name=ln$i
1884 if test $i -eq 2; then
1885 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1886 else
1887 ovn-nbctl lsp-add $ls_name $ln_port_name
1888 fi
1889 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1890 ovn-nbctl lsp-set-type $ln_port_name localnet
1891 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1892 done
1893
1894 # lsp_to_ls LSP
1895 #
1896 # Prints the name of the logical switch that contains LSP.
1897 lsp_to_ls () {
1898 case $1 in dnl (
1899 lp?[[12]]) echo ls1 ;; dnl (
1900 lp?[[34]]) echo ls2 ;; dnl (
1901 lp?5) echo ls3 ;; dnl (
1902 *) AT_FAIL_IF([:]) ;;
1903 esac
1904 }
1905
1906 net_add n1
1907 for i in 1 2; do
1908 sim_add hv$i
1909 as hv$i
1910 ovs-vsctl add-br br-phys
1911 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1912 ovn_attach n1 br-phys 192.168.0.$i
1913
1914 for j in 1 2 3 4 5; do
1915 ovs-vsctl add-port br-int vif$i$j -- \
1916 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1917 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1918 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1919 ofport-request=$i$j
1920
1921 lsp_name=lp$i$j
1922 ls_name=$(lsp_to_ls $lsp_name)
1923
1924 ovn-nbctl lsp-add $ls_name $lsp_name
1925 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1926 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1927
1928 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1929 done
1930 done
1931 ovn-nbctl --wait=sb sync
1932 ovn-sbctl dump-flows
1933
1934 OVN_POPULATE_ARP
1935
1936 # XXX This is now the 3rd copy of these functions in this file ...
1937
1938 # Given the name of a logical port, prints the name of the hypervisor
1939 # on which it is located.
1940 vif_to_hv() {
1941 echo hv${1%?}
1942 }
1943 #
1944 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1945 #
1946 # This shell function causes a packet to be received on INPORT. The packet's
1947 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1948 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1949 # logical switch port numbers, e.g. 11 for vif11.
1950 #
1951 # EOUT is the end-to-end output port, that is, where the packet will end up
1952 # after possibly bouncing through one or more localnet ports. LOUT is the
1953 # logical output port, which might be a localnet port, as seen by ovn-trace
1954 # (which doesn't know what localnet ports are connected to and therefore can't
1955 # figure out the end-to-end answer).
1956 for i in 1 2; do
1957 for j in 1 2 3 4 5; do
1958 : > $i$j.expected
1959 done
1960 done
1961 test_packet() {
1962 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1963 echo "$@"
1964
1965 # First try tracing the packet.
1966 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1967 if test $lout != drop; then
1968 echo "output(\"$lout\");"
1969 fi > expout
1970 AT_CAPTURE_FILE([trace])
1971 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1972
1973 # Then actually send a packet, for an end-to-end test.
1974 local packet=$(echo $dst$src | sed 's/://g')${eth}
1975 hv=`vif_to_hv $inport`
1976 vif=vif$inport
1977 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1978 if test $eout != drop; then
1979 echo $packet >> ${eout#lp}.expected
1980 fi
1981 }
1982
1983 # lp11 and lp21 are on the same network (phys, untagged)
1984 # and on different hypervisors
1985 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1986 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1987
1988 # lp11 and lp12 are on the same network (phys, untagged)
1989 # and on the same hypervisor
1990 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1991 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1992
1993 # lp13 and lp23 are on the same network (phys, VLAN 101)
1994 # and on different hypervisors
1995 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1996 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1997
1998 # lp13 and lp14 are on the same network (phys, VLAN 101)
1999 # and on the same hypervisor
2000 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
2001 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
2002
2003 # lp11 and lp15 are on the same network (phys, untagged),
2004 # same hypervisor, and on different switches
2005 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2006 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
2007
2008 # lp11 and lp25 are on the same network (phys, untagged),
2009 # different hypervisors, and on different switches
2010 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2011 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
2012
2013 # Ports that should not be able to communicate
2014 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2015 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2016 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2017 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2018 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2019 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2020 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2021 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
2022
2023 # Dump a bunch of info helpful for debugging if there's a failure.
2024
2025 echo "------ OVN dump ------"
2026 ovn-nbctl show
2027 ovn-sbctl show
2028
2029 echo "------ hv1 dump ------"
2030 as hv1 ovs-vsctl show
2031 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2032
2033 echo "------ hv2 dump ------"
2034 as hv2 ovs-vsctl show
2035 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2036
2037 # Now check the packets actually received against the ones expected.
2038 for i in 1 2; do
2039 for j in 1 2 3 4 5; do
2040 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2041 done
2042 done
2043
2044 OVN_CLEANUP([hv1],[hv2])
2045
2046 AT_CLEANUP
2047
2048 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2049 AT_KEYWORDS([vtep])
2050 AT_SKIP_IF([test $HAVE_PYTHON = no])
2051 ovn_start
2052
2053 # Configure the Northbound database
2054 ovn-nbctl ls-add lsw0
2055
2056 ovn-nbctl lsp-add lsw0 lp1
2057 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2058
2059 ovn-nbctl lsp-add lsw0 lp2
2060 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2061
2062 ovn-nbctl lsp-add lsw0 lp-vtep
2063 ovn-nbctl lsp-set-type lp-vtep vtep
2064 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2065 ovn-nbctl lsp-set-addresses lp-vtep unknown
2066
2067 # lpr, lr and lrp1 are used for the ARP request handling test only.
2068 ovn-nbctl lsp-add lsw0 lpr
2069 ovn-nbctl lr-add lr
2070 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2071 ovn-nbctl set Logical_Switch_Port lpr type=router \
2072 options:router-port=lrp1 \
2073 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2074
2075
2076 net_add n1 # Network to connect hv1, hv2, and vtep
2077 net_add n2 # Network to connect vtep and hv3
2078
2079 # Create hypervisor hv1 connected to n1
2080 sim_add hv1
2081 as hv1
2082 ovs-vsctl add-br br-phys
2083 ovn_attach n1 br-phys 192.168.0.1
2084 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
2085
2086 # Create hypervisor hv2 connected to n1
2087 sim_add hv2
2088 as hv2
2089 ovs-vsctl add-br br-phys
2090 ovn_attach n1 br-phys 192.168.0.2
2091 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
2092
2093
2094 # Start the vtep emulator with a leg in both networks
2095 sim_add vtep
2096 as vtep
2097
2098 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2099 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2100
2101 ovs-vsctl add-br br-phys
2102 net_attach n1 br-phys
2103
2104 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2105 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2106 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2107 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2108
2109 ovs-vsctl add-br br-vtep
2110 net_attach n2 br-vtep
2111
2112 vtep-ctl add-ps br-vtep
2113 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2114 vtep-ctl add-ls lsw0
2115
2116 start_daemon ovs-vtep br-vtep
2117 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2118
2119 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
2120
2121 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2122 grep -- source`"])
2123 # It takes more time for the update to be processed by ovs-vtep.
2124 sleep 1
2125
2126 # Add hv3 on the other side of the vtep
2127 sim_add hv3
2128 as hv3
2129 ovs-vsctl add-br br-phys
2130 net_attach n2 br-phys
2131
2132 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
2133
2134 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2135 # packets for ARP resolution (native tunneling doesn't queue packets
2136 # for ARP resolution).
2137 OVN_POPULATE_ARP
2138
2139 # Allow some time for ovn-northd and ovn-controller to catch up.
2140 # XXX This should be more systematic.
2141 sleep 1
2142
2143 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2144 #
2145 # This shell function causes a packet to be received on INPORT. The packet's
2146 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2147 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2148 # more) list the VIFs on which the packet should be received. INPORT and the
2149 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
2150 for i in 1 2 3; do
2151 : > $i.expected
2152 done
2153 test_packet() {
2154 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2155 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2156 hv=hv$inport
2157 vif=vif$inport
2158 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2159 for outport; do
2160 echo $packet >> $outport.expected
2161 done
2162 }
2163
2164 # Send packets between all pairs of source and destination ports:
2165 #
2166 # 1. Unicast packets are delivered to exactly one logical switch port
2167 # (except that packets destined to their input ports are dropped).
2168 #
2169 # 2. Broadcast and multicast are delivered to all logical switch ports
2170 # except the input port.
2171 #
2172 # 3. The switch delivers packets with an unknown destination to logical
2173 # switch ports with "unknown" among their MAC addresses (and port
2174 # security disabled).
2175 for s in 1 2 3; do
2176 bcast=
2177 unknown=
2178 for d in 1 2 3; do
2179 if test $d != $s; then unicast=$d; else unicast=; fi
2180 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2181
2182 # The vtep (vif3) is the only one configured for "unknown"
2183 if test $d != $s && test $d = 3; then
2184 unknown="$unknown $d"
2185 fi
2186 bcast="$bcast $unicast"
2187 done
2188
2189 # Broadcast and multicast.
2190 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2191 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2192
2193 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2194 done
2195
2196 # ARP request should not be responded to by logical switch router
2197 # type arp responder on HV1 and HV2 and should reach directly to
2198 # vif1 and vif2
2199 ip_to_hex() {
2200 printf "%02x%02x%02x%02x" "$@"
2201 }
2202 sha=f00000000003
2203 spa=`ip_to_hex 192 168 1 2`
2204 tpa=`ip_to_hex 192 168 1 1`
2205 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2206 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2207 echo $request >> 1.expected
2208 echo $request >> 2.expected
2209
2210 # dump information with counters
2211 echo "------ OVN dump ------"
2212 ovn-nbctl show
2213 ovn-sbctl show
2214
2215 echo "---------SB dump-----"
2216 ovn-sbctl list datapath_binding
2217 echo "---------------------"
2218 ovn-sbctl list port_binding
2219 echo "---------------------"
2220 ovn-sbctl dump-flows
2221
2222 echo "------ hv1 dump ------"
2223 as hv1 ovs-vsctl show
2224 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2225 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2226
2227 echo "------ hv2 dump ------"
2228 as hv2 ovs-vsctl show
2229 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2230 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2231
2232 echo "------ hv3 dump ------"
2233 as hv3 ovs-vsctl show
2234 # note: hv3 has no logical port bind, thus it should not have br-int
2235 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2236 [ovs-ofctl: br-int is not a bridge or a socket
2237 ])
2238
2239 # Now check the packets actually received against the ones expected.
2240 for i in 1 2 3; do
2241 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2242 done
2243
2244 # Gracefully terminate daemons
2245 OVN_CLEANUP([hv1],[hv2],[vtep])
2246 OVN_CLEANUP_VSWITCH([hv3])
2247
2248 AT_CLEANUP
2249
2250 # Similar test to "hardware GW"
2251 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2252 AT_SKIP_IF([test $HAVE_PYTHON = no])
2253 ovn_start
2254
2255 # Configure the Northbound database
2256 ovn-nbctl ls-add lsw0
2257
2258 ovn-nbctl lsp-add lsw0 lp1
2259 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2260
2261 ovn-nbctl lsp-add lsw0 lp2
2262 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2263
2264 ovn-nbctl lsp-add lsw0 lp-gw
2265 ovn-nbctl lsp-set-type lp-gw l2gateway
2266 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2267 ovn-nbctl lsp-set-addresses lp-gw unknown
2268
2269 net_add n1 # Network to connect hv1, hv2, and gw
2270 net_add n2 # Network to connect gw and hv3
2271
2272 # Create hypervisor hv1 connected to n1
2273 sim_add hv1
2274 as hv1
2275 ovs-vsctl add-br br-phys
2276 ovn_attach n1 br-phys 192.168.0.1
2277 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
2278
2279 # Create hypervisor hv2 connected to n1
2280 sim_add hv2
2281 as hv2
2282 ovs-vsctl add-br br-phys
2283 ovn_attach n1 br-phys 192.168.0.2
2284 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
2285
2286 # Create hypervisor hv_gw connected to n1 and n2
2287 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2288 sim_add hv_gw
2289 as hv_gw
2290 ovs-vsctl add-br br-phys
2291 ovn_attach n1 br-phys 192.168.0.3
2292 ovs-vsctl add-br br-phys2
2293 net_attach n2 br-phys2
2294 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2295
2296 # Add hv3 on the other side of the GW
2297 sim_add hv3
2298 as hv3
2299 ovs-vsctl add-br br-phys
2300 net_attach n2 br-phys
2301 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
2302
2303
2304 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2305 # packets for ARP resolution (native tunneling doesn't queue packets
2306 # for ARP resolution).
2307 OVN_POPULATE_ARP
2308
2309 # Allow some time for ovn-northd and ovn-controller to catch up.
2310 # XXX This should be more systematic.
2311 sleep 1
2312
2313 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2314 #
2315 # This shell function causes a packet to be received on INPORT. The packet's
2316 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2317 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2318 # more) list the VIFs on which the packet should be received. INPORT and the
2319 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2320 for i in 1 2 3; do
2321 : > $i.expected
2322 done
2323 test_packet() {
2324 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2325 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2326 hv=hv$inport
2327 vif=vif$inport
2328 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2329 for outport; do
2330 echo $packet >> $outport.expected
2331 done
2332 }
2333
2334 # Send packets between all pairs of source and destination ports:
2335 #
2336 # 1. Unicast packets are delivered to exactly one lport (except that packets
2337 # destined to their input ports are dropped).
2338 #
2339 # 2. Broadcast and multicast are delivered to all lports except the input port.
2340 #
2341 # 3. The lswitch delivers packets with an unknown destination to lports with
2342 # "unknown" among their MAC addresses (and port security disabled).
2343 for s in 1 2 3 ; do
2344 bcast=
2345 unknown=
2346 for d in 1 2 3 ; do
2347 if test $d != $s; then unicast=$d; else unicast=; fi
2348 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2349
2350 # The vtep (vif3) is the only one configured for "unknown"
2351 if test $d != $s && test $d = 3; then
2352 unknown="$unknown $d"
2353 fi
2354 bcast="$bcast $unicast"
2355 done
2356
2357 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2358 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2359 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2360 done
2361
2362 echo "------ ovn-nbctl show ------"
2363 ovn-nbctl show
2364 echo "------ ovn-sbctl show ------"
2365 ovn-sbctl show
2366
2367 echo "------ hv1 ------"
2368 as hv1 ovs-vsctl show
2369 echo "------ hv1 br-int ------"
2370 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2371 echo "------ hv1 br-phys ------"
2372 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2373
2374 echo "------ hv2 ------"
2375 as hv2 ovs-vsctl show
2376 echo "------ hv2 br-int ------"
2377 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2378 echo "------ hv2 br-phys ------"
2379 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2380
2381 echo "------ hv_gw ------"
2382 as hv_gw ovs-vsctl show
2383 echo "------ hv_gw br-phys ------"
2384 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2385 echo "------ hv_gw br-phys2 ------"
2386 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2387
2388 echo "------ hv3 ------"
2389 as hv3 ovs-vsctl show
2390 echo "------ hv3 br-phys ------"
2391 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2392
2393 # Now check the packets actually received against the ones expected.
2394 for i in 1 2 3; do
2395 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2396 done
2397 AT_CLEANUP
2398
2399 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2400 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2401 AT_SKIP_IF([test $HAVE_PYTHON = no])
2402 ovn_start
2403
2404 # Logical network:
2405 #
2406 # Three logical switches ls1, ls2, ls3.
2407 # One logical router lr0 connected to ls[123],
2408 # with nine subnets, three per logical switch:
2409 #
2410 # lrp11 on ls1 for subnet 192.168.11.0/24
2411 # lrp12 on ls1 for subnet 192.168.12.0/24
2412 # lrp13 on ls1 for subnet 192.168.13.0/24
2413 # ...
2414 # lrp33 on ls3 for subnet 192.168.33.0/24
2415 #
2416 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2417 # digits are the subnet and the last digit distinguishes the VIF.
2418 for i in 1 2 3; do
2419 ovn-nbctl ls-add ls$i
2420 for j in 1 2 3; do
2421 for k in 1 2 3; do
2422 # Add "unknown" to MAC addresses for lp?11, so packets for
2423 # MAC-IP bindings discovered via ARP later have somewhere to go.
2424 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2425
2426 ovn-nbctl \
2427 -- lsp-add ls$i lp$i$j$k \
2428 -- lsp-set-addresses lp$i$j$k \
2429 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
2430 done
2431 done
2432 done
2433
2434 ovn-nbctl lr-add lr0
2435 for i in 1 2 3; do
2436 for j in 1 2 3; do
2437 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2438 ovn-nbctl \
2439 -- lsp-add ls$i lrp$i$j-attachment \
2440 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2441 options:router-port=lrp$i$j \
2442 addresses='"00:00:00:00:ff:'$i$j'"'
2443 done
2444 done
2445
2446 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2447 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2448
2449 # Physical network:
2450 #
2451 # Three hypervisors hv[123].
2452 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2453 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2454 # lp?3[123] all on hv3.
2455
2456
2457 # Given the name of a logical port, prints the name of the hypervisor
2458 # on which it is located.
2459 vif_to_hv() {
2460 case $1 in dnl (
2461 ?11) echo 1 ;; dnl (
2462 ?12 | ?21 | ?22) echo 2 ;; dnl (
2463 ?13 | ?23 | ?3?) echo 3 ;;
2464 esac
2465 }
2466
2467 # Given the name of a logical port, prints the name of its logical router
2468 # port, e.g. "vif_to_lrp 123" yields 12.
2469 vif_to_lrp() {
2470 echo ${1%?}
2471 }
2472
2473 # Given the name of a logical port, prints the name of its logical
2474 # switch, e.g. "vif_to_ls 123" yields 1.
2475 vif_to_ls() {
2476 echo ${1%??}
2477 }
2478
2479 net_add n1
2480 for i in 1 2 3; do
2481 sim_add hv$i
2482 as hv$i
2483 ovs-vsctl add-br br-phys
2484 ovn_attach n1 br-phys 192.168.0.$i
2485 done
2486 for i in 1 2 3; do
2487 for j in 1 2 3; do
2488 for k in 1 2 3; do
2489 hv=`vif_to_hv $i$j$k`
2490 as hv$hv ovs-vsctl \
2491 -- add-port br-int vif$i$j$k \
2492 -- set Interface vif$i$j$k \
2493 external-ids:iface-id=lp$i$j$k \
2494 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2495 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2496 ofport-request=$i$j$k
2497 done
2498 done
2499 done
2500
2501 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2502 # packets for ARP resolution (native tunneling doesn't queue packets
2503 # for ARP resolution).
2504 OVN_POPULATE_ARP
2505
2506 # Allow some time for ovn-northd and ovn-controller to catch up.
2507 # XXX This should be more systematic.
2508 sleep 1
2509
2510 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2511 #
2512 # This shell function causes a packet to be received on INPORT. The packet's
2513 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2514 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2515 # more) list the VIFs on which the packet should be received. INPORT and the
2516 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2517 for i in 1 2 3; do
2518 for j in 1 2 3; do
2519 for k in 1 2 3; do
2520 : > $i$j$k.expected
2521 done
2522 done
2523 done
2524 test_ip() {
2525 # This packet has bad checksums but logical L3 routing doesn't check.
2526 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2527 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2528 shift; shift; shift; shift; shift
2529 hv=hv`vif_to_hv $inport`
2530 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2531 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2532 in_ls=`vif_to_ls $inport`
2533 in_lrp=`vif_to_lrp $inport`
2534 for outport; do
2535 out_ls=`vif_to_ls $outport`
2536 if test $in_ls = $out_ls; then
2537 # Ports on the same logical switch receive exactly the same packet.
2538 echo $packet
2539 else
2540 # Routing decrements TTL and updates source and dest MAC
2541 # (and checksum).
2542 out_lrp=`vif_to_lrp $outport`
2543 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2544 fi >> $outport.expected
2545 done
2546 }
2547
2548 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2549 #
2550 # Causes a packet to be received on INPORT. The packet is an ARP
2551 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2552 # it should be the hardware address of the target to expect to receive in an
2553 # ARP reply; otherwise no reply is expected.
2554 #
2555 # INPORT is an logical switch port number, e.g. 11 for vif11.
2556 # SHA and REPLY_HA are each 12 hex digits.
2557 # SPA and TPA are each 8 hex digits.
2558 test_arp() {
2559 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2560 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2561 hv=hv`vif_to_hv $inport`
2562 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2563 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2564
2565 # Expect to receive the broadcast ARP on the other logical switch ports if
2566 # IP address is not configured to the switch patch port.
2567 local i=`vif_to_ls $inport`
2568 local j k
2569 for j in 1 2 3; do
2570 for k in 1 2 3; do
2571 # 192.168.33.254 is configured to the switch patch port for lrp33,
2572 # so no ARP flooding expected for it.
2573 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2574 echo $request >> $i$j$k.expected
2575 fi
2576 done
2577 done
2578
2579 # Expect to receive the reply, if any.
2580 if test X$reply_ha != X; then
2581 lrp=`vif_to_lrp $inport`
2582 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2583 echo $reply >> $inport.expected
2584 fi
2585 }
2586
2587 as hv1 ovs-vsctl --columns=name,ofport list interface
2588 as hv1 ovn-sbctl list port_binding
2589 as hv1 ovn-sbctl list datapath_binding
2590 as hv1 ovn-sbctl dump-flows
2591 as hv1 ovs-ofctl dump-flows br-int
2592
2593 # Send IP packets between all pairs of source and destination ports:
2594 #
2595 # 1. Unicast IP packets are delivered to exactly one logical switch port
2596 # (except that packets destined to their input ports are dropped).
2597 #
2598 # 2. Broadcast IP packets are delivered to all logical switch ports
2599 # except the input port.
2600 ip_to_hex() {
2601 printf "%02x%02x%02x%02x" "$@"
2602 }
2603 for is in 1 2 3; do
2604 for js in 1 2 3; do
2605 for ks in 1 2 3; do
2606 bcast=
2607 s=$is$js$ks
2608 smac=f00000000$s
2609 sip=`ip_to_hex 192 168 $is$js $ks`
2610 for id in 1 2 3; do
2611 for jd in 1 2 3; do
2612 for kd in 1 2 3; do
2613 d=$id$jd$kd
2614 dip=`ip_to_hex 192 168 $id$jd $kd`
2615 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2616 if test $d != $s; then unicast=$d; else unicast=; fi
2617
2618 test_ip $s $smac $dmac $sip $dip $unicast #1
2619
2620 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2621 done
2622 done
2623 done
2624 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2625 done
2626 done
2627 done
2628
2629 : > mac_bindings.expected
2630
2631 # 3. Send an IP packet from every logical port to every other subnet,
2632 # to an IP address that does not have a static IP-MAC binding.
2633 # This should generate a broadcast ARP request for the destination
2634 # IP address in the destination subnet.
2635 # Moreover generate an ARP reply for each of the IP addresses ARPed
2636 for is in 1 2 3; do
2637 for js in 1 2 3; do
2638 for ks in 1 2 3; do
2639 s=$is$js$ks
2640 smac=f00000000$s
2641 sip=`ip_to_hex 192 168 $is$js $ks`
2642 for id in 1 2 3; do
2643 for jd in 1 2 3; do
2644 if test $is$js = $id$jd; then
2645 continue
2646 fi
2647
2648 # Send the packet.
2649 dmac=00000000ff$is$js
2650 # Calculate a 4th octet for the destination that is
2651 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2652 # that have static MAC bindings, and fits in the range
2653 # 0-255.
2654 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2655 dip=`ip_to_hex 192 168 $id$jd $o4`
2656 test_ip $s $smac $dmac $sip $dip
2657
2658 # Every LP on the destination subnet's lswitch should
2659 # receive the ARP request.
2660 lrmac=00000000ff$id$jd
2661 lrip=`ip_to_hex 192 168 $id$jd 254`
2662 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2663 for jd2 in 1 2 3; do
2664 for kd in 1 2 3; do
2665 echo $arp >> $id$jd2$kd.expected
2666 done
2667 done
2668 if test $(vif_to_hv ${is}${js}${ks}) = $(vif_to_hv ${id}${jd}1); then
2669 hmac=8000000000$o4
2670 rmac=00000000ff$id$jd
2671 echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
2672 fi
2673
2674 host_mac=8000000000$o4
2675 lrmac=00000000ff$id$jd
2676
2677 arp_reply=${lrmac}${host_mac}08060001080006040002${host_mac}${dip}${lrmac}${lrip}
2678
2679 hv=hv`vif_to_hv ${id}${jd}1`
2680 as $hv ovs-appctl netdev-dummy/receive vif${id}${jd}1 $arp_reply
2681
2682 host_ip_pretty=192.168.$id$jd.$o4
2683 host_mac_pretty=80:00:00:00:00:$o4
2684 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2685 done
2686 done
2687 done
2688 done
2689 done
2690
2691 # Test router replies to ARP requests from all source ports:
2692 #
2693 # 4. Router replies to query for its MAC address from port's own IP address.
2694 #
2695 # 5. Router replies to query for its MAC address from any random IP address
2696 # in its subnet.
2697 #
2698 # 6. No reply to query for IP address other than router IP.
2699 #
2700 # 7. No reply to query from another subnet.
2701 for i in 1 2 3; do
2702 for j in 1 2 3; do
2703 for k in 1 2 3; do
2704 smac=f00000000$i$j$k # Source MAC
2705 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2706 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2707 rmac=00000000ff$i$j # Router MAC
2708 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2709 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2710
2711 test_arp $i$j$k $smac $sip $rip $rmac #4
2712 test_arp $i$j$k $smac $otherip $rip $rmac #5
2713 test_arp $i$j$k $smac $sip $otherip #6
2714
2715 # When rip is 192.168.33.254, ARP request from externalip won't be
2716 # filtered, because 192.168.33.254 is configured to switch peer port
2717 # for lrp33.
2718 lrp33_rsp=
2719 if test $i = 3 && test $j = 3; then
2720 lrp33_rsp=$rmac
2721 fi
2722 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2723
2724 # MAC binding should be learned from ARP request.
2725 host_mac_pretty=f0:00:00:00:0$i:$j$k
2726
2727 host_ip_pretty=192.168.$i$j.$k
2728 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2729
2730 # mac_binding is learned and overwritten so only the last one remains.
2731 if test $k = 3; then
2732 # lrp33 will not learn from ARP request, because 192.168.33.254 is
2733 # configured to switch peer port for lrp33.
2734 if test $i != 3 || test $j != 3; then
2735 host_ip_pretty=192.168.$i$j.55
2736 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2737 fi
2738 fi
2739
2740 done
2741 done
2742 done
2743
2744
2745 # Allow some time for packet forwarding.
2746 # XXX This can be improved.
2747 sleep 1
2748
2749 # 8. Send an IP packet from every logical port to every other subnet. These
2750 # are the same packets already sent as #3, but now the destinations' IP-MAC
2751 # bindings have been discovered via ARP, so instead of provoking an ARP
2752 # request, these packets now get routed to their destinations (which don't
2753 # have static MAC bindings, so they go to the port we've designated as
2754 # accepting "unknown" MACs.)
2755 for is in 1 2 3; do
2756 for js in 1 2 3; do
2757 for ks in 1 2 3; do
2758 s=$is$js$ks
2759 smac=f00000000$s
2760 sip=`ip_to_hex 192 168 $is$js $ks`
2761 for id in 1 2 3; do
2762 for jd in 1 2 3; do
2763 if test $is$js = $id$jd; then
2764 continue
2765 fi
2766
2767 # Send the packet.
2768 dmac=00000000ff$is$js
2769 # Calculate a 4th octet for the destination that is
2770 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2771 # that have static MAC bindings, and fits in the range
2772 # 0-255.
2773 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2774 dip=`ip_to_hex 192 168 $id$jd $o4`
2775 test_ip $s $smac $dmac $sip $dip
2776
2777 # Expect the packet egress.
2778 host_mac=8000000000$o4
2779 outport=${id}11
2780 out_lrp=$id$jd
2781 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2782 done
2783 done
2784 done
2785 done
2786 done
2787
2788 ovn-sbctl -f csv -d bare --no-heading \
2789 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2790
2791 # Now check the packets actually received against the ones expected.
2792 for i in 1 2 3; do
2793 for j in 1 2 3; do
2794 for k in 1 2 3; do
2795 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2796 [$i$j$k.expected])
2797 done
2798 done
2799 done
2800
2801 # Check the MAC bindings against those expected.
2802 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2803 ])
2804
2805 # Gracefully terminate daemons
2806 OVN_CLEANUP([hv1], [hv2], [hv3])
2807
2808 AT_CLEANUP
2809
2810 AT_SETUP([ovn -- IP relocation using GARP request])
2811 AT_SKIP_IF([test $HAVE_PYTHON = no])
2812 ovn_start
2813
2814 # Logical network:
2815 #
2816 # Two logical switches ls1, ls2.
2817 # One logical router lr0 connected to ls[12],
2818 # with 2 subnets, 1 per logical switch:
2819 #
2820 # lrp1 on ls1 for subnet 192.168.1.1/24
2821 # lrp2 on ls2 for subnet 192.168.2.1/24
2822 #
2823 # 4 VIFs, 2 per LS lp[12][12], first digit being LS.
2824 # VIFs' fixed IP addresses are 192.168.[12].1[12].
2825 #
2826 # There is a secondary IP 192.168.1.100 that is unknown in NB and learned
2827 # through ARP only, and it can move between lp11 and lp12.
2828 #
2829 ovn-nbctl lr-add lr0
2830 for i in 1 2 ; do
2831 ovn-nbctl ls-add ls$i
2832 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
2833 ovn-nbctl \
2834 -- lsp-add ls$i lrp$i-attachment \
2835 -- set Logical_Switch_Port lrp$i-attachment type=router \
2836 options:router-port=lrp$i \
2837 addresses=router
2838 for j in 1 2; do
2839 ovn-nbctl \
2840 -- lsp-add ls$i lp$i$j \
2841 -- lsp-set-addresses lp$i$j \
2842 "f0:00:00:00:00:$i$j 192.168.$i.1$j"
2843 done
2844 done
2845
2846 # Physical network:
2847 # 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
2848
2849 # Given the name of a logical port, prints the name of the hypervisor
2850 # on which it is located, e.g. "vif_to_hv 12" yields 2.
2851 vif_to_hv() {
2852 echo ${1#?}
2853 }
2854
2855 # Given the name of a logical port, prints the name of its logical router
2856 # port, e.g. "vif_to_lrp 12" yields 1.
2857 vif_to_lrp() {
2858 echo ${1%?}
2859 }
2860
2861 # Given the name of a logical port, prints the name of its logical
2862 # switch, e.g. "vif_to_ls 12" yields 1.
2863 vif_to_ls() {
2864 echo ${1%?}
2865 }
2866
2867 net_add n1
2868 for i in 1 2; do
2869 sim_add hv$i
2870 as hv$i
2871 ovs-vsctl add-br br-phys
2872 ovn_attach n1 br-phys 192.168.0.$i
2873 done
2874 for i in 1 2; do
2875 for j in 1 2; do
2876 hv=`vif_to_hv $i$j`
2877 as hv$hv ovs-vsctl \
2878 -- add-port br-int vif$i$j \
2879 -- set Interface vif$i$j \
2880 external-ids:iface-id=lp$i$j \
2881 options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
2882 options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
2883 ofport-request=$i$j
2884 done
2885 done
2886
2887 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2888 # packets for ARP resolution (native tunneling doesn't queue packets
2889 # for ARP resolution).
2890 OVN_POPULATE_ARP
2891
2892 # Allow some time for ovn-northd and ovn-controller to catch up.
2893 # XXX This should be more systematic.
2894 sleep 1
2895
2896 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2897 #
2898 # This shell function causes a packet to be received on INPORT. The packet's
2899 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2900 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2901 # more) list the VIFs on which the packet should be received. INPORT and the
2902 # OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
2903 for i in 1 2; do
2904 for j in 1 2; do
2905 : > $i$j.expected
2906 done
2907 done
2908 test_ip() {
2909 # This packet has bad checksums but logical L3 routing doesn't check.
2910 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2911 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2912 shift; shift; shift; shift; shift
2913 hv=hv`vif_to_hv $inport`
2914 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2915 in_ls=`vif_to_ls $inport`
2916 in_lrp=`vif_to_lrp $inport`
2917 for outport; do
2918 out_ls=`vif_to_ls $outport`
2919 if test $in_ls = $out_ls; then
2920 # Ports on the same logical switch receive exactly the same packet.
2921 echo $packet
2922 else
2923 # Routing decrements TTL and updates source and dest MAC
2924 # (and checksum).
2925 out_lrp=`vif_to_lrp $outport`
2926 echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2927 fi >> $outport.expected
2928 done
2929 }
2930
2931 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2932 #
2933 # Causes a packet to be received on INPORT. The packet is an ARP
2934 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2935 # it should be the hardware address of the target to expect to receive in an
2936 # ARP reply; otherwise no reply is expected.
2937 #
2938 # INPORT is an logical switch port number, e.g. 11 for vif11.
2939 # SHA and REPLY_HA are each 12 hex digits.
2940 # SPA and TPA are each 8 hex digits.
2941 test_arp() {
2942 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2943 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2944 hv=hv`vif_to_hv $inport`
2945 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2946
2947 # Expect to receive the broadcast ARP on the other logical switch ports if
2948 # IP address is not configured to the switch patch port.
2949 local i=`vif_to_ls $inport`
2950 local j
2951 for j in 1 2; do
2952 if test $i$j != $inport; then
2953 echo $request >> $i$j$k.expected
2954 fi
2955 done
2956
2957 # Expect to receive the reply, if any.
2958 if test X$reply_ha != X; then
2959 lrp=`vif_to_lrp $inport`
2960 local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2961 echo $reply >> $inport.expected
2962 fi
2963 }
2964
2965 ip_to_hex() {
2966 printf "%02x%02x%02x%02x" "$@"
2967 }
2968
2969 # lp11 send GARP request to announce ownership of 192.168.1.100.
2970
2971 sha=f00000000011
2972 spa=`ip_to_hex 192 168 1 100`
2973 tpa=$spa
2974 test_arp 11 $sha $spa $tpa
2975 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
2976 ovn-nbctl --wait=hv sync
2977
2978 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
2979
2980 smac=f00000000021
2981 dmac=00000000ff02
2982 sip=`ip_to_hex 192 168 2 11`
2983 dip=`ip_to_hex 192 168 1 100`
2984 test_ip 21 $smac $dmac $sip $dip 11
2985
2986 # lp12 send GARP request to announce ownership of 192.168.1.100.
2987
2988 sha=f00000000012
2989 test_arp 12 $sha $spa $tpa
2990 OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
2991 ovn-nbctl --wait=hv sync
2992
2993 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
2994
2995 test_ip 21 $smac $dmac $sip $dip 12
2996
2997 # Now check the packets actually received against the ones expected.
2998 for i in 1 2; do
2999 for j in 1 2; do
3000 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
3001 [$i$j.expected])
3002 done
3003 done
3004
3005 # Gracefully terminate daemons
3006 OVN_CLEANUP([hv1], [hv2])
3007
3008 AT_CLEANUP
3009
3010 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
3011 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
3012 AT_SKIP_IF([test $HAVE_PYTHON = no])
3013 ovn_start
3014
3015 # Create hypervisors hv[123].
3016 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
3017 # Add all of the vifs to a single logical switch lsw0.
3018 # Turn off port security on vifs vif[123]1
3019 # Turn on l2 port security on vifs vif[123]2
3020 # Turn of l2 and l3 port security on vifs vif[123]3
3021 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
3022 ovn-nbctl ls-add lsw0
3023 net_add n1
3024 for i in 1 2 3; do
3025 sim_add hv$i
3026 as hv$i
3027 ovs-vsctl add-br br-phys
3028 ovn_attach n1 br-phys 192.168.0.$i
3029
3030 for j in 1 2 3; do
3031 ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
3032 ovn-nbctl lsp-add lsw0 lp$i$j
3033 if test $j = 1; then
3034 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
3035 elif test $j = 2; then
3036 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
3037 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
3038 else
3039 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
3040 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3041 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3042 fi
3043 done
3044 done
3045
3046 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3047 # packets for ARP resolution (native tunneling doesn't queue packets
3048 # for ARP resolution).
3049 OVN_POPULATE_ARP
3050
3051 # Allow some time for ovn-northd and ovn-controller to catch up.
3052 # XXX This should be more systematic.
3053 sleep 1
3054
3055 # Given the name of a logical port, prints the name of the hypervisor
3056 # on which it is located.
3057 vif_to_hv() {
3058 echo hv${1%?}
3059 }
3060
3061 for i in 1 2 3; do
3062 for j in 1 2 3; do
3063 : > $i$j.expected
3064 done
3065 done
3066
3067 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3068 #
3069 # This shell function causes an ip packet to be received on INPORT.
3070 # The packet's content has Ethernet destination DST and source SRC
3071 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
3072 # The OUTPORTs (zero or more) list the VIFs on which the packet should
3073 # be received. INPORT and the OUTPORTs are specified as logical switch
3074 # port numbers, e.g. 11 for vif11.
3075 test_ip() {
3076 # This packet has bad checksums but logical L3 routing doesn't check.
3077 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3078 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3079 shift; shift; shift; shift; shift
3080 hv=`vif_to_hv $inport`
3081 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3082 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3083 for outport; do
3084 echo $packet >> $outport.expected
3085 done
3086 }
3087
3088 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
3089 #
3090 # Causes a packet to be received on INPORT. The packet is an ARP
3091 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3092 # it should be the hardware address of the target to expect to receive in an
3093 # ARP reply; otherwise no reply is expected.
3094 #
3095 # INPORT is an logical switch port number, e.g. 11 for vif11.
3096 # SHA and REPLY_HA are each 12 hex digits.
3097 # SPA and TPA are each 8 hex digits.
3098 test_arp() {
3099 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
3100 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3101 hv=`vif_to_hv $inport`
3102 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3103 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
3104 if test $drop != 1; then
3105 if test X$reply_ha = X; then
3106 # Expect to receive the broadcast ARP on the other logical switch ports
3107 # if no reply is expected.
3108 local i j
3109 for i in 1 2 3; do
3110 for j in 1 2 3; do
3111 if test $i$j != $inport; then
3112 echo $request >> $i$j.expected
3113 fi
3114 done
3115 done
3116 else
3117 # Expect to receive the reply, if any.
3118 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3119 echo $reply >> $inport.expected
3120 fi
3121 fi
3122 }
3123
3124 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3125 # This function is similar to test_ip() except that it sends
3126 # ipv6 packet
3127 test_ipv6() {
3128 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3129 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
3130 shift; shift; shift; shift; shift
3131 hv=`vif_to_hv $inport`
3132 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3133 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3134 for outport; do
3135 echo $packet >> $outport.expected
3136 done
3137 }
3138
3139 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
3140 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
3141 # of the test packet
3142 test_icmpv6() {
3143 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
3144 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
3145 shift; shift; shift; shift; shift; shift
3146 hv=`vif_to_hv $inport`
3147 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3148 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3149 for outport; do
3150 echo $packet >> $outport.expected
3151 done
3152 }
3153
3154 ip_to_hex() {
3155 printf "%02x%02x%02x%02x" "$@"
3156 }
3157
3158 # no port security
3159 sip=`ip_to_hex 192 168 0 12`
3160 tip=`ip_to_hex 192 168 0 13`
3161 # the arp packet should be allowed even if lp[123]1 is
3162 # not configured with mac f00000000023 and ip 192.168.0.12
3163 for i in 1 2 3; do
3164 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
3165 for j in 1 2 3; do
3166 if test $i != $j; then
3167 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
3168 fi
3169 done
3170 done
3171
3172 # l2 port security
3173 sip=`ip_to_hex 192 168 0 12`
3174 tip=`ip_to_hex 192 168 0 13`
3175
3176 # arp packet should be allowed since lp22 is configured with
3177 # mac f00000000022
3178 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
3179
3180 # arp packet should not be allowed since lp32 is not configured with
3181 # mac f00000000021
3182 test_arp 32 f00000000021 f00000000021 $sip $tip 1
3183
3184 # arp packet with sha set to f00000000021 should not be allowed
3185 # for lp12
3186 test_arp 12 f00000000012 f00000000021 $sip $tip 1
3187
3188 # ip packets should be allowed and received since lp[123]2 do not
3189 # have l3 port security
3190 sip=`ip_to_hex 192 168 0 55`
3191 tip=`ip_to_hex 192 168 0 66`
3192 for i in 1 2 3; do
3193 for j in 1 2 3; do
3194 if test $i != $j; then
3195 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3196 fi
3197 done
3198 done
3199
3200 # ipv6 packets should be received by lp[123]2
3201 # lp[123]1 can send ipv6 traffic as there is no port security
3202 sip=fe800000000000000000000000000000
3203 tip=ff020000000000000000000000000000
3204
3205 for i in 1 2 3; do
3206 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3207 done
3208
3209
3210 # l2 and l3 port security
3211 sip=`ip_to_hex 192 168 0 13`
3212 tip=`ip_to_hex 192 168 0 22`
3213 # arp packet should be allowed since lp13 is configured with
3214 # f00000000013 and 192.168.0.13
3215 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3216
3217 # the arp packet should be dropped because lp23 is not configured
3218 # with mac f00000000022
3219 sip=`ip_to_hex 192 168 0 13`
3220 tip=`ip_to_hex 192 168 0 22`
3221 test_arp 23 f00000000022 f00000000022 $sip $tip 1
3222
3223 # the arp packet should be dropped because lp33 is not configured
3224 # with ip 192.168.0.55
3225 spa=`ip_to_hex 192 168 0 55`
3226 tpa=`ip_to_hex 192 168 0 22`
3227 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3228
3229 # ip packets should not be received by lp[123]3 since
3230 # l3 port security is enabled
3231 sip=`ip_to_hex 192 168 0 55`
3232 tip=`ip_to_hex 192 168 0 66`
3233 for i in 1 2 3; do
3234 for j in 1 2 3; do
3235 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3236 done
3237 done
3238
3239 # ipv6 packets should be dropped for lp[123]3 since
3240 # it is configured with only ipv4 address
3241 sip=fe800000000000000000000000000000
3242 tip=ff020000000000000000000000000000
3243
3244 for i in 1 2 3; do
3245 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3246 done
3247
3248 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3249 # lp[123]1 can send ipv6 traffic as there is no port security
3250 for i in 1 2 3; do
3251 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3252 done
3253
3254 # lp13 has extra port security with mac f0000000113 and ipv6 addr
3255 # fe80::ea2a:eaff:fe28:0012
3256
3257 # ipv4 packet should be dropped for lp13 with mac f0000000113
3258 sip=`ip_to_hex 192 168 0 13`
3259 tip=`ip_to_hex 192 168 0 23`
3260 test_ip 13 f00000000113 f00000000023 $sip $tip
3261
3262 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3263 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
3264 # lp11 can send ipv6 traffic as there is no port security
3265 sip=ee800000000000000000000000000000
3266 for i in 1 2 3; do
3267 tip=fe80000000000000ea2aeafffe2800${i}3
3268 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
3269 done
3270
3271
3272 # ipv6 packet should not be received by lp33 with mac f0000000333
3273 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3274 # configured with fe80::ea2a:eaff:fe28:0033
3275 # lp11 can send ipv6 traffic as there is no port security
3276
3277 sip=ee800000000000000000000000000000
3278 tip=fe80000000000000ea2aeafffe280023
3279 test_ipv6 11 f00000000011 f00000000333 $sip $tip
3280
3281 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3282 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
3283 # and should be dropped for any other ip6.src
3284 # lp21 can receive ipv6 traffic as there is no port security
3285
3286 tip=ee800000000000000000000000000000
3287 for i in 1 2 3; do
3288 sip=fe80000000000000ea2aeafffe2800${i}3
3289 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3290
3291 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
3292 sip=00000000000000000000000000000000
3293 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3294 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3295 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3296 # Traffic to non-multicast traffic should be dropped
3297 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3298 # Traffic of other ICMPv6 types should be dropped
3299 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
3300
3301 # should be dropped
3302 sip=ae80000000000000ea2aeafffe2800aa
3303 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3304 done
3305
3306 # configure lsp13 to send and received IPv4 packets with an address range
3307 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"
3308
3309 sleep 2
3310
3311 sip=`ip_to_hex 10 0 0 13`
3312 tip=`ip_to_hex 192 168 0 22`
3313 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
3314 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3315
3316 sip=`ip_to_hex 10 0 0 14`
3317 tip=`ip_to_hex 192 168 0 23`
3318 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
3319 # with dst ip 192.168.0.23 should be allowed
3320 test_ip 13 f00000000013 f00000000023 $sip $tip 23
3321
3322 sip=`ip_to_hex 192 168 0 33`
3323 tip=`ip_to_hex 10 0 0 15`
3324 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3325 # with dst ip 10.0.0.15 should be received by lsp13
3326 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3327
3328 sip=`ip_to_hex 192 168 0 33`
3329 tip=`ip_to_hex 20 0 0 4`
3330 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3331 # with dst ip 20.0.0.4 should be received by lsp13
3332 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3333
3334 sip=`ip_to_hex 192 168 0 33`
3335 tip=`ip_to_hex 20 0 0 5`
3336 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3337 # with dst ip 20.0.0.5 should not be received by lsp13
3338 test_ip 33 f00000000033 f00000000013 $sip $tip
3339
3340 sip=`ip_to_hex 192 168 0 33`
3341 tip=`ip_to_hex 20 0 0 255`
3342 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3343 # with dst ip 20.0.0.255 should be received by lsp13
3344 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3345
3346 sip=`ip_to_hex 192 168 0 33`
3347 tip=`ip_to_hex 192 168 0 255`
3348 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3349 # with dst ip 192.168.0.255 should not be received by lsp13
3350 test_ip 33 f00000000033 f00000000013 $sip $tip
3351
3352 sip=`ip_to_hex 192 168 0 33`
3353 tip=`ip_to_hex 224 0 0 4`
3354 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3355 # with dst ip 224.0.0.4 should be received by lsp13
3356 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3357
3358 #dump information including flow counters
3359 ovn-nbctl show
3360 ovn-sbctl dump-flows -- list multicast_group
3361
3362 echo "------ hv1 dump ------"
3363 as hv1 ovs-vsctl show
3364 as hv1 ovs-ofctl -O OpenFlow13 show br-int
3365 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3366
3367 echo "------ hv2 dump ------"
3368 as hv2 ovs-vsctl show
3369 as hv2 ovs-ofctl -O OpenFlow13 show br-int
3370 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3371
3372 echo "------ hv3 dump ------"
3373 as hv3 ovs-vsctl show
3374 as hv3 ovs-ofctl -O OpenFlow13 show br-int
3375 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3376
3377 # Now check the packets actually received against the ones expected.
3378 for i in 1 2 3; do
3379 for j in 1 2 3; do
3380 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3381 done
3382 done
3383
3384 OVN_CLEANUP([hv1],[hv2],[hv3])
3385
3386 AT_CLEANUP
3387
3388 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3389 AT_SKIP_IF([test $HAVE_PYTHON = no])
3390 ovn_start
3391
3392 # Logical network:
3393 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3394 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3395 # R2 has ls2 (172.16.1.0/24) connected to it.
3396
3397 ls1_lp1_mac="f0:00:00:01:02:03"
3398 rp_ls1_mac="00:00:00:01:02:03"
3399 rp_ls2_mac="00:00:00:01:02:04"
3400 ls2_lp1_mac="f0:00:00:01:02:04"
3401
3402 ls1_lp1_ip="192.168.1.2"
3403 ls2_lp1_ip="172.16.1.2"
3404
3405 ovn-nbctl lr-add R1
3406 ovn-nbctl lr-add R2
3407
3408 ovn-nbctl ls-add ls1
3409 ovn-nbctl ls-add ls2
3410
3411 # Connect ls1 to R1
3412 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3413
3414 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3415 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3416
3417 # Connect ls2 to R2
3418 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3419
3420 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3421 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3422
3423 # Connect R1 to R2
3424 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3425 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3426
3427 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3428 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3429
3430 # Create logical port ls1-lp1 in ls1
3431 ovn-nbctl lsp-add ls1 ls1-lp1 \
3432 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3433
3434 # Create logical port ls2-lp1 in ls2
3435 ovn-nbctl lsp-add ls2 ls2-lp1 \
3436 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3437
3438 # Create two hypervisor and create OVS ports corresponding to logical ports.
3439 net_add n1
3440
3441 sim_add hv1
3442 as hv1
3443 ovs-vsctl add-br br-phys
3444 ovn_attach n1 br-phys 192.168.0.1
3445 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3446 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3447 options:tx_pcap=hv1/vif1-tx.pcap \
3448 options:rxq_pcap=hv1/vif1-rx.pcap \
3449 ofport-request=1
3450
3451 sim_add hv2
3452 as hv2
3453 ovs-vsctl add-br br-phys
3454 ovn_attach n1 br-phys 192.168.0.2
3455 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3456 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3457 options:tx_pcap=hv2/vif1-tx.pcap \
3458 options:rxq_pcap=hv2/vif1-rx.pcap \
3459 ofport-request=1
3460
3461
3462 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3463 # packets for ARP resolution (native tunneling doesn't queue packets
3464 # for ARP resolution).
3465 OVN_POPULATE_ARP
3466
3467 # Allow some time for ovn-northd and ovn-controller to catch up.
3468 # XXX This should be more systematic.
3469 sleep 1
3470
3471 # Packet to send.
3472 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3473 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3474 udp && udp.src==53 && udp.dst==4369"
3475 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3476
3477
3478 echo "---------NB dump-----"
3479 ovn-nbctl show
3480 echo "---------------------"
3481 ovn-nbctl list logical_router
3482 echo "---------------------"
3483 ovn-nbctl list logical_router_port
3484 echo "---------------------"
3485
3486 echo "---------SB dump-----"
3487 ovn-sbctl list datapath_binding
3488 echo "---------------------"
3489 ovn-sbctl list port_binding
3490 echo "---------------------"
3491
3492 echo "------ hv1 dump ----------"
3493 as hv1 ovs-ofctl show br-int
3494 as hv1 ovs-ofctl dump-flows br-int
3495 echo "------ hv2 dump ----------"
3496 as hv2 ovs-ofctl show br-int
3497 as hv2 ovs-ofctl dump-flows br-int
3498
3499 # Packet to Expect
3500 # The TTL should be decremented by 2.
3501 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3502 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3503 udp && udp.src==53 && udp.dst==4369"
3504 echo $packet | ovstest test-ovn expr-to-packets > expected
3505
3506 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3507
3508 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3509 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3510 ])
3511
3512 # Disable the ls2-lp1 port.
3513 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3514
3515 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3516 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3517 ])
3518
3519 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3520 # Packet to send.
3521 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3522 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3523 udp && udp.src==53 && udp.dst==4369"
3524
3525 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3526 # The 2nd packet sent shound not be received.
3527 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3528
3529 OVN_CLEANUP([hv1],[hv2])
3530
3531 AT_CLEANUP
3532
3533
3534 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3535 AT_KEYWORDS([router-admin-state])
3536 AT_SKIP_IF([test $HAVE_PYTHON = no])
3537 ovn_start
3538
3539 # Logical network:
3540 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3541 # and 172.16.1.0/24) connected to it.
3542
3543 ovn-nbctl lr-add R1
3544
3545 ovn-nbctl ls-add ls1
3546
3547 # Connect ls1 to R1
3548 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3549 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3550 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3551
3552 # Create logical port ls1-lp1 in ls1
3553 ovn-nbctl lsp-add ls1 ls1-lp1 \
3554 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3555
3556 # Create logical port ls1-lp2 in ls1
3557 ovn-nbctl lsp-add ls1 ls1-lp2 \
3558 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3559
3560 # Create one hypervisor and create OVS ports corresponding to logical ports.
3561 net_add n1
3562
3563 sim_add hv1
3564 as hv1
3565 ovs-vsctl add-br br-phys
3566 ovn_attach n1 br-phys 192.168.0.1
3567 ovs-vsctl -- add-port br-int vif1 -- \
3568 set interface vif1 external-ids:iface-id=ls1-lp1 \
3569 options:tx_pcap=hv1/vif1-tx.pcap \
3570 options:rxq_pcap=hv1/vif1-rx.pcap \
3571 ofport-request=1
3572
3573 ovs-vsctl -- add-port br-int vif2 -- \
3574 set interface vif2 external-ids:iface-id=ls1-lp2 \
3575 options:tx_pcap=hv1/vif2-tx.pcap \
3576 options:rxq_pcap=hv1/vif2-rx.pcap \
3577 ofport-request=1
3578
3579
3580 # Allow some time for ovn-northd and ovn-controller to catch up.
3581 # XXX This should be more systematic.
3582 sleep 1
3583
3584 # Send ip packets between the two ports.
3585 ip_to_hex() {
3586 printf "%02x%02x%02x%02x" "$@"
3587 }
3588
3589 # Packet to send.
3590 src_mac="f00000010203"
3591 dst_mac="000000010203"
3592 src_ip=`ip_to_hex 192 168 1 2`
3593 dst_ip=`ip_to_hex 172 16 1 2`
3594 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3595 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3596
3597
3598 echo "---------NB dump-----"
3599 ovn-nbctl show
3600 echo "---------------------"
3601 ovn-nbctl list logical_router
3602 echo "---------------------"
3603 ovn-nbctl list logical_router_port
3604 echo "---------------------"
3605
3606 echo "---------SB dump-----"
3607 ovn-sbctl list datapath_binding
3608 echo "---------------------"
3609 ovn-sbctl list logical_flow
3610 echo "---------------------"
3611
3612 echo "------ hv1 dump ----------"
3613 as hv1 ovs-ofctl dump-flows br-int
3614
3615
3616 #Disable router R1
3617 ovn-nbctl set Logical_Router R1 enabled=false
3618
3619 # Allow some time for ovn-northd and ovn-controller to catch up.
3620 # XXX This should be more systematic.
3621 sleep 1
3622
3623 echo "---------SB dump-----"
3624 ovn-sbctl list datapath_binding
3625 echo "---------------------"
3626 ovn-sbctl list logical_flow
3627 echo "---------------------"
3628
3629 echo "------ hv1 dump ----------"
3630 as hv1 ovs-ofctl dump-flows br-int
3631
3632 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3633
3634 # Packet to Expect
3635 expect_src_mac="000000010203"
3636 expect_dst_mac="f00000010204"
3637 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3638
3639 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3640
3641
3642 as hv1
3643 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3644 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3645 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3646
3647 as ovn-sb
3648 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3649
3650 as ovn-nb
3651 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3652
3653 as northd
3654 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3655
3656 as main
3657 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3658 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3659
3660 AT_CLEANUP
3661
3662
3663 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3664 AT_KEYWORDS([router-admin-state])
3665 AT_SKIP_IF([test $HAVE_PYTHON = no])
3666 ovn_start
3667
3668 # Logical network:
3669 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3670 # and has switch ls2 (172.16.1.0/24) connected to it.
3671
3672 ovn-nbctl lr-add R1
3673
3674 ovn-nbctl ls-add ls1
3675 ovn-nbctl ls-add ls2
3676
3677 # Connect ls1 to R1
3678 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3679 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3680 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3681
3682 # Connect ls2 to R1
3683 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3684 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3685 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3686
3687 # Create logical port ls1-lp1 in ls1
3688 ovn-nbctl lsp-add ls1 ls1-lp1 \
3689 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3690
3691 # Create logical port ls2-lp1 in ls2
3692 ovn-nbctl lsp-add ls2 ls2-lp1 \
3693 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3694
3695 # Create one hypervisor and create OVS ports corresponding to logical ports.
3696 net_add n1
3697
3698 sim_add hv1
3699 as hv1
3700 ovs-vsctl add-br br-phys
3701 ovn_attach n1 br-phys 192.168.0.1
3702 ovs-vsctl -- add-port br-int vif1 -- \
3703 set interface vif1 external-ids:iface-id=ls1-lp1 \
3704 options:tx_pcap=hv1/vif1-tx.pcap \
3705 options:rxq_pcap=hv1/vif1-rx.pcap \
3706 ofport-request=1
3707
3708 ovs-vsctl -- add-port br-int vif2 -- \
3709 set interface vif2 external-ids:iface-id=ls2-lp1 \
3710 options:tx_pcap=hv1/vif2-tx.pcap \
3711 options:rxq_pcap=hv1/vif2-rx.pcap \
3712 ofport-request=1
3713
3714
3715 # Allow some time for ovn-northd and ovn-controller to catch up.
3716 # XXX This should be more systematic.
3717 sleep 1
3718
3719 # Send ip packets between the two ports.
3720 ip_to_hex() {
3721 printf "%02x%02x%02x%02x" "$@"
3722 }
3723
3724 # Packet to send.
3725 src_mac="f00000010203"
3726 dst_mac="000000010203"
3727 src_ip=`ip_to_hex 192 168 1 2`
3728 dst_ip=`ip_to_hex 172 16 1 2`
3729 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3730 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3731
3732
3733 echo "---------NB dump-----"
3734 ovn-nbctl show
3735 echo "---------------------"
3736 ovn-nbctl list logical_router
3737 echo "---------------------"
3738 ovn-nbctl list logical_router_port
3739 echo "---------------------"
3740
3741 echo "---------SB dump-----"
3742 ovn-sbctl list datapath_binding
3743 echo "---------------------"
3744 ovn-sbctl list logical_flow
3745 echo "---------------------"
3746
3747 echo "------ hv1 dump ----------"
3748 as hv1 ovs-ofctl dump-flows br-int
3749
3750 #Disable router R1
3751 ovn-nbctl set Logical_Router R1 enabled=false
3752
3753 echo "---------SB dump-----"
3754 ovn-sbctl list datapath_binding
3755 echo "---------------------"
3756 ovn-sbctl list logical_flow
3757 echo "---------------------"
3758
3759 echo "------ hv1 dump ----------"
3760 as hv1 ovs-ofctl dump-flows br-int
3761
3762 # Allow some time for the disabling of logical router R1 to propagate.
3763 # XXX This should be more systematic.
3764 sleep 1
3765
3766 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3767
3768 # Packet to Expect
3769 expect_src_mac="000000010204"
3770 expect_dst_mac="f00000010204"
3771 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3772
3773 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3774
3775 OVN_CLEANUP([hv1])
3776
3777 AT_CLEANUP
3778
3779 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3780 AT_SKIP_IF([test $HAVE_PYTHON = no])
3781 ovn_start
3782
3783 # Logical network:
3784 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3785 # network. R1 has switchess foo (192.168.1.0/24)
3786 # connected to it.
3787 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3788
3789 ovn-nbctl lr-add R1
3790 ovn-nbctl lr-add R2
3791
3792 ovn-nbctl ls-add foo
3793 ovn-nbctl ls-add alice
3794 ovn-nbctl ls-add bob
3795
3796 # Connect foo to R1
3797 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3798 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3799 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3800
3801 # Connect alice to R2
3802 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3803 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3804 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3805
3806 # Connect bob to R2
3807 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3808 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3809 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3810
3811 # Connect R1 to R2
3812 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3813 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3814
3815 #install static routes
3816 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3817 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3818 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3819
3820 # Create logical port foo1 in foo
3821 ovn-nbctl lsp-add foo foo1 \
3822 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3823
3824 # Create logical port alice1 in alice
3825 ovn-nbctl lsp-add alice alice1 \
3826 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3827
3828 # Create logical port bob1 in bob
3829 ovn-nbctl lsp-add bob bob1 \
3830 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3831
3832 # Create two hypervisor and create OVS ports corresponding to logical ports.
3833 net_add n1
3834
3835 sim_add hv1
3836 as hv1
3837 ovs-vsctl add-br br-phys
3838 ovn_attach n1 br-phys 192.168.0.1
3839 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3840 set interface hv1-vif1 external-ids:iface-id=foo1 \
3841 options:tx_pcap=hv1/vif1-tx.pcap \
3842 options:rxq_pcap=hv1/vif1-rx.pcap \
3843 ofport-request=1
3844
3845 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3846 set interface hv1-vif2 external-ids:iface-id=alice1 \
3847 options:tx_pcap=hv1/vif2-tx.pcap \
3848 options:rxq_pcap=hv1/vif2-rx.pcap \
3849 ofport-request=2
3850
3851 sim_add hv2
3852 as hv2
3853 ovs-vsctl add-br br-phys
3854 ovn_attach n1 br-phys 192.168.0.2
3855 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3856 set interface hv2-vif1 external-ids:iface-id=bob1 \
3857 options:tx_pcap=hv2/vif1-tx.pcap \
3858 options:rxq_pcap=hv2/vif1-rx.pcap \
3859 ofport-request=1
3860
3861
3862 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3863 # packets for ARP resolution (native tunneling doesn't queue packets
3864 # for ARP resolution).
3865 OVN_POPULATE_ARP
3866
3867 # Allow some time for ovn-northd and ovn-controller to catch up.
3868 # XXX This should be more systematic.
3869 sleep 1
3870
3871 ip_to_hex() {
3872 printf "%02x%02x%02x%02x" "$@"
3873 }
3874
3875 # Send ip packets between foo1 and alice1
3876 src_mac="f00000010203"
3877 dst_mac="000000010203"
3878 src_ip=`ip_to_hex 192 168 1 2`
3879 dst_ip=`ip_to_hex 172 16 1 2`
3880 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3881 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3882
3883 # Send ip packets between foo1 and bob1
3884 src_mac="f00000010203"
3885 dst_mac="000000010203"
3886 src_ip=`ip_to_hex 192 168 1 2`
3887 dst_ip=`ip_to_hex 172 16 2 2`
3888 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3889 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3890
3891 echo "---------NB dump-----"
3892 ovn-nbctl show
3893 echo "---------------------"
3894 ovn-nbctl list logical_router
3895 echo "---------------------"
3896 ovn-nbctl list logical_router_port
3897 echo "---------------------"
3898
3899 echo "---------SB dump-----"
3900 ovn-sbctl list datapath_binding
3901 echo "---------------------"
3902 ovn-sbctl list port_binding
3903 echo "---------------------"
3904
3905 echo "------ hv1 dump ----------"
3906 as hv1 ovs-ofctl dump-flows br-int
3907 echo "------ hv2 dump ----------"
3908 as hv2 ovs-ofctl dump-flows br-int
3909
3910 # Packet to Expect at bob1
3911 src_mac="000000010205"
3912 dst_mac="f00000010205"
3913 src_ip=`ip_to_hex 192 168 1 2`
3914 dst_ip=`ip_to_hex 172 16 2 2`
3915 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3916
3917 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3918
3919 # Packet to Expect at alice1
3920 src_mac="000000010204"
3921 dst_mac="f00000010204"
3922 src_ip=`ip_to_hex 192 168 1 2`
3923 dst_ip=`ip_to_hex 172 16 1 2`
3924 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3925
3926 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3927
3928 OVN_CLEANUP([hv1],[hv2])
3929
3930 AT_CLEANUP
3931
3932 AT_SETUP([ovn -- send gratuitous arp on localnet])
3933 AT_SKIP_IF([test $HAVE_PYTHON = no])
3934 ovn_start
3935 ovn-nbctl ls-add lsw0
3936 net_add n1
3937 sim_add hv
3938 as hv
3939 ovs-vsctl \
3940 -- add-br br-phys \
3941 -- add-br br-eth0
3942
3943 ovn_attach n1 br-phys 192.168.0.1
3944
3945 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3946 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])
3947
3948 # Create a vif.
3949 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3950 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3951 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3952
3953 # Create a localnet port.
3954 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3955 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3956 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3957 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3958
3959 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3960
3961 # Wait for packet to be received.
3962 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3963 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3964
3965 # Check GARP packet when restart openflow connection.
3966 as hv
3967 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3968
3969 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3970
3971 as hv
3972 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3973
3974 # Wait for packet to be received.
3975 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3976 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3977
3978 # Delete the localnet ports.
3979 AT_CHECK([ovs-vsctl del-port localvif1])
3980 AT_CHECK([ovn-nbctl lsp-del ln_port])
3981
3982 OVN_CLEANUP([hv])
3983
3984 AT_CLEANUP
3985
3986 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3987 AT_SKIP_IF([test $HAVE_PYTHON = no])
3988 ovn_start
3989
3990 # Logical network:
3991 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3992 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3993 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3994 # connected to it.
3995
3996 ovn-nbctl lr-add R1
3997 ovn-nbctl lr-add R2
3998 ovn-nbctl lr-add R3
3999
4000 ovn-nbctl ls-add foo
4001 ovn-nbctl ls-add alice
4002 ovn-nbctl ls-add bob
4003 ovn-nbctl ls-add join
4004
4005 # Connect foo to R1
4006 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4007 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4008 options:router-port=foo addresses=\"00:00:01:01:02:03\"
4009
4010 # Connect alice to R2
4011 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4012 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4013 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4014
4015 # Connect bob to R3
4016 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
4017 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
4018 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
4019
4020 # Connect R1 to join
4021 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4022 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4023 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4024
4025 # Connect R2 to join
4026 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4027 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4028 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4029
4030 # Connect R3 to join
4031 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
4032 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
4033 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
4034
4035 #install static routes
4036 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4037 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
4038
4039 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4040 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
4041
4042 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
4043 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
4044
4045 # Create logical port foo1 in foo
4046 ovn-nbctl lsp-add foo foo1 \
4047 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4048
4049 # Create logical port alice1 in alice
4050 ovn-nbctl lsp-add alice alice1 \
4051 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4052
4053 # Create logical port bob1 in bob
4054 ovn-nbctl lsp-add bob bob1 \
4055 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
4056
4057 # Create two hypervisor and create OVS ports corresponding to logical ports.
4058 net_add n1
4059
4060 sim_add hv1
4061 as hv1
4062 ovs-vsctl add-br br-phys
4063 ovn_attach n1 br-phys 192.168.0.1
4064 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4065 set interface hv1-vif1 external-ids:iface-id=foo1 \
4066 options:tx_pcap=hv1/vif1-tx.pcap \
4067 options:rxq_pcap=hv1/vif1-rx.pcap \
4068 ofport-request=1
4069
4070 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4071 set interface hv1-vif2 external-ids:iface-id=alice1 \
4072 options:tx_pcap=hv1/vif2-tx.pcap \
4073 options:rxq_pcap=hv1/vif2-rx.pcap \
4074 ofport-request=2
4075
4076 sim_add hv2
4077 as hv2
4078 ovs-vsctl add-br br-phys
4079 ovn_attach n1 br-phys 192.168.0.2
4080 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4081 set interface hv2-vif1 external-ids:iface-id=bob1 \
4082 options:tx_pcap=hv2/vif1-tx.pcap \
4083 options:rxq_pcap=hv2/vif1-rx.pcap \
4084 ofport-request=1
4085
4086
4087 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4088 # packets for ARP resolution (native tunneling doesn't queue packets
4089 # for ARP resolution).
4090 OVN_POPULATE_ARP
4091
4092 # Allow some time for ovn-northd and ovn-controller to catch up.
4093 # XXX This should be more systematic.
4094 sleep 1
4095
4096 ip_to_hex() {
4097 printf "%02x%02x%02x%02x" "$@"
4098 }
4099
4100 # Send ip packets between foo1 and alice1
4101 src_mac="f00000010203"
4102 dst_mac="000001010203"
4103 src_ip=`ip_to_hex 192 168 1 2`
4104 dst_ip=`ip_to_hex 172 16 1 2`
4105 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4106 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4107 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4108
4109 # Send ip packets between foo1 and bob1
4110 src_mac="f00000010203"
4111 dst_mac="000001010203"
4112 src_ip=`ip_to_hex 192 168 1 2`
4113 dst_ip=`ip_to_hex 10 32 1 2`
4114 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4115 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4116
4117 echo "---------NB dump-----"
4118 ovn-nbctl show
4119 echo "---------------------"
4120 ovn-nbctl list logical_router
4121 echo "---------------------"
4122 ovn-nbctl list logical_router_port
4123 echo "---------------------"
4124
4125 echo "---------SB dump-----"
4126 ovn-sbctl list datapath_binding
4127 echo "---------------------"
4128 ovn-sbctl list port_binding
4129 echo "---------------------"
4130 ovn-sbctl dump-flows
4131 echo "---------------------"
4132
4133 echo "------ hv1 dump ----------"
4134 as hv1 ovs-ofctl show br-int
4135 as hv1 ovs-ofctl dump-flows br-int
4136 echo "------ hv2 dump ----------"
4137 as hv2 ovs-ofctl show br-int
4138 as hv2 ovs-ofctl dump-flows br-int
4139 echo "----------------------------"
4140
4141 # Packet to Expect at bob1
4142 src_mac="000003010203"
4143 dst_mac="f00000010205"
4144 src_ip=`ip_to_hex 192 168 1 2`
4145 dst_ip=`ip_to_hex 10 32 1 2`
4146 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4147
4148 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4149
4150 # Packet to Expect at alice1
4151 src_mac="000002010203"
4152 dst_mac="f00000010204"
4153 src_ip=`ip_to_hex 192 168 1 2`
4154 dst_ip=`ip_to_hex 172 16 1 2`
4155 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4156
4157 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4158
4159 OVN_CLEANUP([hv1],[hv2])
4160
4161 AT_CLEANUP
4162
4163 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
4164 AT_SKIP_IF([test $HAVE_PYTHON = no])
4165 ovn_start
4166
4167 ovn-nbctl ls-add ls1
4168
4169 ovn-nbctl lsp-add ls1 ls1-lp1 \
4170 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4171
4172 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4173
4174 ovn-nbctl lsp-add ls1 ls1-lp2 \
4175 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4176
4177 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4178
4179 ovn-nbctl ls-add ls2
4180 ovn-nbctl lsp-add ls2 ls2-lp1 \
4181 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4182 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4183 ovn-nbctl lsp-add ls2 ls2-lp2 \
4184 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4185 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4186
4187 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
4188 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
4189 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
4190
4191 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4192 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4193
4194 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
4195 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
4196 \"lease_time\"=\"3600\"")"
4197
4198 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
4199
4200 net_add n1
4201 sim_add hv1
4202
4203 as hv1
4204 ovs-vsctl add-br br-phys
4205 ovn_attach n1 br-phys 192.168.0.1
4206 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4207 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4208 options:tx_pcap=hv1/vif1-tx.pcap \
4209 options:rxq_pcap=hv1/vif1-rx.pcap \
4210 ofport-request=1
4211
4212 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4213 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4214 options:tx_pcap=hv1/vif2-tx.pcap \
4215 options:rxq_pcap=hv1/vif2-rx.pcap \
4216 ofport-request=2
4217
4218 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4219 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4220 options:tx_pcap=hv1/vif3-tx.pcap \
4221 options:rxq_pcap=hv1/vif3-rx.pcap \
4222 ofport-request=3
4223
4224 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4225 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4226 options:tx_pcap=hv1/vif4-tx.pcap \
4227 options:rxq_pcap=hv1/vif4-rx.pcap \
4228 ofport-request=4
4229
4230 OVN_POPULATE_ARP
4231
4232 sleep 2
4233
4234 as hv1 ovs-vsctl show
4235
4236 # This shell function sends a DHCP request packet
4237 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
4238 test_dhcp() {
4239 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
4240 shift; shift; shift; shift; shift;
4241 if test $use_ip != 0; then
4242 src_ip=$1
4243 dst_ip=$2
4244 shift; shift;
4245 else
4246 src_ip=`ip_to_hex 0 0 0 0`
4247 dst_ip=`ip_to_hex 255 255 255 255`
4248 fi
4249 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
4250 # udp header and dhcp header
4251 request=${request}0044004300fc0000
4252 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
4253 # client hardware padding
4254 request=${request}00000000000000000000
4255 # server hostname
4256 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4257 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4258 # boot file name
4259 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4260 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4261 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4262 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4263 # dhcp magic cookie
4264 request=${request}63825363
4265 # dhcp message type
4266 request=${request}3501${dhcp_type}ff
4267
4268 for port in $inport "$@"; do
4269 : >> $port.expected
4270 done
4271 if test $offer_ip != 0; then
4272 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
4273 # total IP length will be the IP length of the request packet
4274 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4275 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4276 udp_len=`expr $ip_len - 20`
4277 ip_len=$(printf "%x" $ip_len)
4278 udp_len=$(printf "%x" $udp_len)
4279 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4280 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4281 # udp header and dhcp header.
4282 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
4283 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
4284 # your ip address
4285 reply=${reply}${offer_ip}
4286 # next server ip address, relay agent ip address, client mac address
4287 reply=${reply}0000000000000000${src_mac}
4288 # client hardware padding
4289 reply=${reply}00000000000000000000
4290 # server hostname
4291 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4292 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4293 # boot file name
4294 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4295 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4296 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4297 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4298 # dhcp magic cookie
4299 reply=${reply}63825363
4300 # dhcp message type
4301 local dhcp_reply_type=02
4302 if test $dhcp_type = 03; then
4303 dhcp_reply_type=05
4304 fi
4305 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
4306 echo $reply >> $inport.expected
4307 else
4308 for outport; do
4309 echo $request >> $outport.expected
4310 done
4311 fi
4312 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4313 }
4314
4315 reset_pcap_file() {
4316 local iface=$1
4317 local pcap_file=$2
4318 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4319 options:rxq_pcap=dummy-rx.pcap
4320 rm -f ${pcap_file}*.pcap
4321 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4322 options:rxq_pcap=${pcap_file}-rx.pcap
4323 }
4324
4325 ip_to_hex() {
4326 printf "%02x%02x%02x%02x" "$@"
4327 }
4328
4329 AT_CAPTURE_FILE([ofctl_monitor0.log])
4330 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4331 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4332
4333 echo "---------NB dump-----"
4334 ovn-nbctl show
4335 echo "---------------------"
4336 echo "---------SB dump-----"
4337 ovn-sbctl list datapath_binding
4338 echo "---------------------"
4339 ovn-sbctl list logical_flow
4340 echo "---------------------"
4341
4342 echo "---------------------"
4343 ovn-sbctl dump-flows
4344 echo "---------------------"
4345
4346 echo "------ hv1 dump ----------"
4347 as hv1 ovs-ofctl dump-flows br-int
4348
4349 # Send DHCPDISCOVER.
4350 offer_ip=`ip_to_hex 10 0 0 4`
4351 server_ip=`ip_to_hex 10 0 0 1`
4352 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4353 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4354
4355 # NXT_RESUMEs should be 1.
4356 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4357
4358 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4359 cat 1.expected | cut -c -48 > expout
4360 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4361 # Skipping the IPv4 checksum.
4362 cat 1.expected | cut -c 53- > expout
4363 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4364
4365 # ovs-ofctl also resumes the packets and this causes other ports to receive
4366 # the DHCP request packet. So reset the pcap files so that its easier to test.
4367 reset_pcap_file hv1-vif1 hv1/vif1
4368 reset_pcap_file hv1-vif2 hv1/vif2
4369 rm -f 1.expected
4370 rm -f 2.expected
4371
4372 # Send DHCPREQUEST.
4373 offer_ip=`ip_to_hex 10 0 0 6`
4374 server_ip=`ip_to_hex 10 0 0 1`
4375 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4376 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4377
4378 # NXT_RESUMEs should be 2.
4379 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4380
4381 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4382 cat 2.expected | cut -c -48 > expout
4383 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4384 # Skipping the IPv4 checksum.
4385 cat 2.expected | cut -c 53- > expout
4386 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4387
4388 reset_pcap_file hv1-vif1 hv1/vif1
4389 reset_pcap_file hv1-vif2 hv1/vif2
4390 rm -f 1.expected
4391 rm -f 2.expected
4392
4393 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4394 # but should be resumed without the reply.
4395 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4396 # one from ovn-controller and the other from "ovs-ofctl resume."
4397 offer_ip=0
4398 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
4399
4400 # NXT_RESUMEs should be 3.
4401 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4402
4403 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4404 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4405
4406 reset_pcap_file hv1-vif1 hv1/vif1
4407 reset_pcap_file hv1-vif2 hv1/vif2
4408 rm -f 1.expected
4409 rm -f 2.expected
4410
4411 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4412 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4413
4414 test_dhcp 3 f00000000003 01 0 4 0
4415
4416 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4417 # this lport.
4418 test_dhcp 4 f00000000004 01 0 3 0
4419
4420 # NXT_RESUMEs should be 3.
4421 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4422
4423 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4424 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4425
4426 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4427 offer_ip=`ip_to_hex 10 0 0 6`
4428 server_ip=`ip_to_hex 10 0 0 1`
4429 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4430 src_ip=$offer_ip
4431 dst_ip=$server_ip
4432 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4433
4434 # NXT_RESUMEs should be 4.
4435 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4436
4437 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4438 cat 2.expected | cut -c -48 > expout
4439 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4440 # Skipping the IPv4 checksum.
4441 cat 2.expected | cut -c 53- > expout
4442 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4443
4444 reset_pcap_file hv1-vif1 hv1/vif1
4445 reset_pcap_file hv1-vif2 hv1/vif2
4446 rm -f 1.expected
4447 rm -f 2.expected
4448
4449 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4450 offer_ip=`ip_to_hex 10 0 0 6`
4451 server_ip=`ip_to_hex 10 0 0 1`
4452 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4453 src_ip=$offer_ip
4454 dst_ip=`ip_to_hex 255 255 255 255`
4455 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4456
4457 # NXT_RESUMEs should be 5.
4458 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4459
4460 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4461 cat 2.expected | cut -c -48 > expout
4462 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4463 # Skipping the IPv4 checksum.
4464 cat 2.expected | cut -c 53- > expout
4465 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4466
4467 reset_pcap_file hv1-vif1 hv1/vif1
4468 reset_pcap_file hv1-vif2 hv1/vif2
4469 rm -f 1.expected
4470 rm -f 2.expected
4471
4472 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4473 # The packet should not be received by ovn-controller.
4474 src_ip=`ip_to_hex 10 0 0 6`
4475 dst_ip=`ip_to_hex 10 0 0 4`
4476 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4477
4478 # NXT_RESUMEs should be 5.
4479 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4480
4481 # vif1-tx.pcap should have received the DHCPv4 request packet
4482 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4483
4484 as hv1
4485 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4486 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4487 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4488
4489 as ovn-sb
4490 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4491
4492 as ovn-nb
4493 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4494
4495 as northd
4496 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4497
4498 as main
4499 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4500 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4501
4502 AT_CLEANUP
4503
4504 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4505 AT_SKIP_IF([test $HAVE_PYTHON = no])
4506 ovn_start
4507
4508 ovn-nbctl ls-add ls1
4509 ovn-nbctl lsp-add ls1 ls1-lp1 \
4510 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4511
4512 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4513
4514 ovn-nbctl lsp-add ls1 ls1-lp2 \
4515 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4516
4517 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4518
4519 ovn-nbctl lsp-add ls1 ls1-lp3 \
4520 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4521
4522 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4523
4524 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4525 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4526
4527 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4528 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4529
4530 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4531 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4532
4533 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4534
4535 ovn-nbctl ls-add ls2
4536 ovn-nbctl lsp-add ls2 ls2-lp1 \
4537 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4538 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4539 ovn-nbctl lsp-add ls2 ls2-lp2 \
4540 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4541 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4542
4543 net_add n1
4544 sim_add hv1
4545
4546 as hv1
4547 ovs-vsctl add-br br-phys
4548 ovn_attach n1 br-phys 192.168.0.1
4549 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4550 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4551 options:tx_pcap=hv1/vif1-tx.pcap \
4552 options:rxq_pcap=hv1/vif1-rx.pcap \
4553 ofport-request=1
4554
4555 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4556 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4557 options:tx_pcap=hv1/vif2-tx.pcap \
4558 options:rxq_pcap=hv1/vif2-rx.pcap \
4559 ofport-request=2
4560
4561 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4562 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4563 options:tx_pcap=hv1/vif3-tx.pcap \
4564 options:rxq_pcap=hv1/vif3-rx.pcap \
4565 ofport-request=3
4566
4567 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4568 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4569 options:tx_pcap=hv1/vif4-tx.pcap \
4570 options:rxq_pcap=hv1/vif4-rx.pcap \
4571 ofport-request=4
4572
4573 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4574 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4575 options:tx_pcap=hv1/vif5-tx.pcap \
4576 options:rxq_pcap=hv1/vif5-rx.pcap \
4577 ofport-request=5
4578
4579 OVN_POPULATE_ARP
4580
4581 sleep 2
4582
4583 trim_zeros() {
4584 sed 's/\(00\)\{1,\}$//'
4585 }
4586
4587 # This shell function sends a DHCPv6 request packet
4588 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4589 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4590 # packet should be received twice (one from ovn-controller and the other
4591 # from the "ovs-ofctl monitor br-int resume"
4592 test_dhcpv6() {
4593 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4594 if test $msg_code != 0b; then
4595 req_len=2a
4596 else
4597 req_len=1a
4598 fi
4599 local request=ffffffffffff${src_mac}86dd0000000000${req_len}1101${src_lla}
4600 # dst ip ff02::1:2
4601 request=${request}ff020000000000000000000000010002
4602 # udp header and dhcpv6 header
4603 request=${request}0222022300${req_len}ffff${msg_code}010203
4604 # Client identifier
4605 request=${request}0001000a00030001${src_mac}
4606 # Add IA-NA (Identity Association for Non Temporary Address) if msg_code
4607 # is not 11 (information request packet)
4608 if test $msg_code != 0b; then
4609 request=${request}0003000c0102030400000e1000001518
4610 fi
4611 shift; shift; shift; shift; shift;
4612 if test $offer_ip != 0; then
4613 local server_mac=000000100001
4614 local server_lla=fe80000000000000020000fffe100001
4615 local reply_code=07
4616 if test $msg_code = 01; then
4617 reply_code=02
4618 fi
4619 local msg_len=54
4620 if test $offer_ip = 1; then
4621 msg_len=28
4622 fi
4623 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4624 # udp header and dhcpv6 header
4625 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4626 # Client identifier
4627 reply=${reply}0001000a00030001${src_mac}
4628 # IA-NA
4629 if test $offer_ip != 1; then
4630 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4631 fi
4632 # Server identifier
4633 reply=${reply}0002000a00030001${server_mac}
4634 echo $reply | trim_zeros >> $inport.expected
4635 else
4636 for outport; do
4637 echo $request | trim_zeros >> $outport.expected
4638 done
4639 fi
4640
4641 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4642 }
4643
4644 reset_pcap_file() {
4645 local iface=$1
4646 local pcap_file=$2
4647 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4648 options:rxq_pcap=dummy-rx.pcap
4649 rm -f ${pcap_file}*.pcap
4650 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4651 options:rxq_pcap=${pcap_file}-rx.pcap
4652 }
4653
4654 AT_CAPTURE_FILE([ofctl_monitor0.log])
4655 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4656 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4657
4658 echo "---------NB dump-----"
4659 ovn-nbctl show
4660 echo "---------------------"
4661 echo "---------SB dump-----"
4662 ovn-sbctl list datapath_binding
4663 echo "---------------------"
4664 ovn-sbctl list logical_flow
4665 echo "---------------------"
4666
4667 echo "---------------------"
4668 ovn-sbctl dump-flows
4669 echo "---------------------"
4670
4671 echo "------ hv1 dump ----------"
4672 as hv1 ovs-ofctl dump-flows br-int
4673
4674 src_mac=f00000000001
4675 src_lla=fe80000000000000f20000fffe000001
4676 offer_ip=ae700000000000000000000000000004
4677 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4678
4679 # NXT_RESUMEs should be 1.
4680 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4681
4682 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4683 # cat 1.expected | trim_zeros > expout
4684 cat 1.expected | cut -c -120 > expout
4685 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4686 # Skipping the UDP checksum
4687 cat 1.expected | cut -c 125- > expout
4688 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4689
4690 rm 1.expected
4691
4692 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4693 # without any modifications and the packet should be received by ls1-lp1.
4694 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4695 # resume and the other from ovs-ofctl monitor resume.
4696
4697 reset_pcap_file hv1-vif1 hv1/vif1
4698 reset_pcap_file hv1-vif2 hv1/vif2
4699
4700 src_mac=f00000000002
4701 src_lla=fe80000000000000f20000fffe000002
4702 offer_ip=ae700000000000000000000000000005
4703 # Set invalid msg_type
4704
4705 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4706
4707 # NXT_RESUMEs should be 2.
4708 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4709
4710 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4711 rm 2.packets
4712 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4713 AT_CHECK([cat 2.packets], [0], [])
4714
4715 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4716 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4717 cat 1.expected > expout
4718 AT_CHECK([cat 1.packets], [0], [expout])
4719
4720 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4721 # There should be no DHCPv6 reply from ovn-controller and the request packet
4722 # should be received by ls2-lp2.
4723
4724 src_mac=f00000000003
4725 src_lla=fe80000000000000f20000fffe000003
4726 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4727
4728 # NXT_RESUMEs should be 2 only.
4729 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4730
4731 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4732 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4733 AT_CHECK([cat 3.packets], [0], [])
4734
4735 # vif4-tx.pcap should have received the DHCPv6 request packet
4736 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4737 cat 4.expected > expout
4738 AT_CHECK([cat 4.packets], [0], [expout])
4739
4740 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4741 # The DHCPv6 reply shouldn't contain offer_ip.
4742 src_mac=f00000000022
4743 src_lla=fe80000000000000f20000fffe000022
4744 reset_pcap_file hv1-vif5 hv1/vif5
4745 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4746
4747 # NXT_RESUMEs should be 3.
4748 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4749
4750 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4751 # Skipping the UDP checksum
4752 cat 5.expected | cut -c 1-120,125- > expout
4753 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4754
4755 # Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
4756 # shouldn't contain offer_ip
4757 src_mac=f00000000022
4758 src_lla=fe80000000000000f20000fffe000022
4759 reset_pcap_file hv1-vif5 hv1/vif5
4760 rm -f 5.expected
4761 test_dhcpv6 5 $src_mac $src_lla 0b 1 5
4762
4763 # NXT_RESUMEs should be 4.
4764 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4765
4766 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap |
4767 trim_zeros > 5.packets
4768 # Skipping the UDP checksum
4769 cat 5.expected | cut -c 1-120,125- > expout
4770 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4771
4772 as hv1
4773 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4774 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4775 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4776
4777 as ovn-sb
4778 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4779
4780 as ovn-nb
4781 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4782
4783 as northd
4784 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4785
4786 as main
4787 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4788 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4789
4790 AT_CLEANUP
4791
4792 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4793 AT_SKIP_IF([test $HAVE_PYTHON = no])
4794 ovn_start
4795
4796 # Logical network:
4797 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4798 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4799 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4800 # R2 is a gateway router.
4801
4802
4803
4804 # Create two hypervisor and create OVS ports corresponding to logical ports.
4805 net_add n1
4806
4807 sim_add hv1
4808 as hv1
4809 ovs-vsctl add-br br-phys
4810 ovn_attach n1 br-phys 192.168.0.1
4811 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4812 set interface hv1-vif1 external-ids:iface-id=foo1 \
4813 options:tx_pcap=hv1/vif1-tx.pcap \
4814 options:rxq_pcap=hv1/vif1-rx.pcap \
4815 ofport-request=1
4816
4817
4818 sim_add hv2
4819 as hv2
4820 ovs-vsctl add-br br-phys
4821 ovn_attach n1 br-phys 192.168.0.2
4822 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4823 set interface hv2-vif1 external-ids:iface-id=alice1 \
4824 options:tx_pcap=hv2/vif1-tx.pcap \
4825 options:rxq_pcap=hv2/vif1-rx.pcap \
4826 ofport-request=1
4827
4828 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4829 # packets for ARP resolution (native tunneling doesn't queue packets
4830 # for ARP resolution).
4831 OVN_POPULATE_ARP
4832
4833 ovn-nbctl create Logical_Router name=R1
4834 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4835
4836 ovn-nbctl ls-add foo
4837 ovn-nbctl ls-add alice
4838 ovn-nbctl ls-add join
4839
4840 # Connect foo to R1
4841 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4842 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4843 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4844
4845 # Connect alice to R2
4846 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4847 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4848 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4849
4850 # Connect R1 to join
4851 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4852 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4853 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4854
4855 # Connect R2 to join
4856 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4857 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4858 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4859
4860
4861 #install static routes
4862 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4863 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4864 R1 static_routes @lrt
4865
4866 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4867 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4868 R2 static_routes @lrt
4869
4870 # Create logical port foo1 in foo
4871 ovn-nbctl lsp-add foo foo1 \
4872 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4873
4874 # Create logical port alice1 in alice
4875 ovn-nbctl lsp-add alice alice1 \
4876 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4877
4878
4879 # Allow some time for ovn-northd and ovn-controller to catch up.
4880 # XXX This should be more systematic.
4881 sleep 2
4882
4883 ip_to_hex() {
4884 printf "%02x%02x%02x%02x" "$@"
4885 }
4886
4887 # Send ip packets between foo1 and alice1
4888 src_mac="f00000010203"
4889 dst_mac="000001010203"
4890 src_ip=`ip_to_hex 192 168 1 2`
4891 dst_ip=`ip_to_hex 172 16 1 2`
4892 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4893
4894 echo "---------NB dump-----"
4895 ovn-nbctl show
4896 echo "---------------------"
4897 ovn-nbctl list logical_router
4898 echo "---------------------"
4899 ovn-nbctl list logical_router_port
4900 echo "---------------------"
4901
4902 echo "---------SB dump-----"
4903 ovn-sbctl list datapath_binding
4904 echo "---------------------"
4905 ovn-sbctl list port_binding
4906 echo "---------------------"
4907 ovn-sbctl dump-flows
4908 echo "---------------------"
4909 ovn-sbctl list chassis
4910 ovn-sbctl list encap
4911 echo "---------------------"
4912
4913 # Packet to Expect at alice1
4914 src_mac="000002010203"
4915 dst_mac="f00000010204"
4916 src_ip=`ip_to_hex 192 168 1 2`
4917 dst_ip=`ip_to_hex 172 16 1 2`
4918 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4919
4920
4921 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4922 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4923
4924 echo "------ hv1 dump after packet 1 ----------"
4925 as hv1 ovs-ofctl show br-int
4926 as hv1 ovs-ofctl dump-flows br-int
4927 echo "------ hv2 dump after packet 1 ----------"
4928 as hv2 ovs-ofctl show br-int
4929 as hv2 ovs-ofctl dump-flows br-int
4930 echo "----------------------------"
4931
4932 echo $expected > expected
4933 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4934
4935 # Delete the router and re-create it. Things should work as before.
4936 ovn-nbctl lr-del R2
4937 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4938 # Connect alice to R2
4939 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4940 # Connect R2 to join
4941 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4942
4943 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4944 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4945 R2 static_routes @lrt
4946
4947 # Wait for ovn-controller to catch up.
4948 sleep 1
4949
4950 # Send the packet again.
4951 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4952
4953 echo "------ hv1 dump after packet 2 ----------"
4954 as hv1 ovs-ofctl show br-int
4955 as hv1 ovs-ofctl dump-flows br-int
4956 echo "------ hv2 dump after packet 2 ----------"
4957 as hv2 ovs-ofctl show br-int
4958 as hv2 ovs-ofctl dump-flows br-int
4959 echo "----------------------------"
4960
4961 echo $expected >> expected
4962 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4963
4964 OVN_CLEANUP([hv1],[hv2])
4965
4966 AT_CLEANUP
4967
4968 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4969 AT_KEYWORDS([router-icmp-reply])
4970 AT_SKIP_IF([test $HAVE_PYTHON = no])
4971 ovn_start
4972
4973 # Logical network:
4974 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4975 # and has switch ls2 (172.16.1.0/24) connected to it.
4976
4977 ovn-nbctl lr-add R1
4978
4979 ovn-nbctl ls-add ls1
4980 ovn-nbctl ls-add ls2
4981
4982 # Connect ls1 to R1
4983 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4984 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4985 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4986
4987 # Connect ls2 to R1
4988 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4989 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4990 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4991
4992 # Create logical port ls1-lp1 in ls1
4993 ovn-nbctl lsp-add ls1 ls1-lp1 \
4994 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4995
4996 # Create logical port ls2-lp1 in ls2
4997 ovn-nbctl lsp-add ls2 ls2-lp1 \
4998 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4999
5000 # Create one hypervisor and create OVS ports corresponding to logical ports.
5001 net_add n1
5002
5003 sim_add hv1
5004 as hv1
5005 ovs-vsctl add-br br-phys
5006 ovn_attach n1 br-phys 192.168.0.1
5007 ovs-vsctl -- add-port br-int vif1 -- \
5008 set interface vif1 external-ids:iface-id=ls1-lp1 \
5009 options:tx_pcap=hv1/vif1-tx.pcap \
5010 options:rxq_pcap=hv1/vif1-rx.pcap \
5011 ofport-request=1
5012
5013 ovs-vsctl -- add-port br-int vif2 -- \
5014 set interface vif2 external-ids:iface-id=ls2-lp1 \
5015 options:tx_pcap=hv1/vif2-tx.pcap \
5016 options:rxq_pcap=hv1/vif2-rx.pcap \
5017 ofport-request=1
5018
5019
5020 # Allow some time for ovn-northd and ovn-controller to catch up.
5021 # XXX This should be more systematic.
5022 sleep 1
5023
5024
5025 ip_to_hex() {
5026 printf "%02x%02x%02x%02x" "$@"
5027 }
5028 for i in 1 2; do
5029 : > vif$i.expected
5030 done
5031 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
5032 #
5033 # Causes a packet to be received on INPORT. The packet is an ICMPv4
5034 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
5035 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
5036 # provided, then it should be the ip and icmp checksums of the packet
5037 # responded; otherwise, no reply is expected.
5038 # In the absence of an ip checksum calculation helpers, this relies
5039 # on the caller to provide the checksums for the ip and icmp headers.
5040 # XXX This should be more systematic.
5041 #
5042 # INPORT is an lport number, e.g. 11 for vif11.
5043 # ETH_SRC and ETH_DST are each 12 hex digits.
5044 # IPV4_SRC and IPV4_DST are each 8 hex digits.
5045 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
5046 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
5047 test_ipv4_icmp_request() {
5048 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
5049 local exp_ip_chksum=$8 exp_icmp_chksum=$9
5050 shift; shift; shift; shift; shift; shift; shift
5051 shift; shift
5052
5053 # Use ttl to exercise section 4.2.2.9 of RFC1812
5054 local ip_ttl=01
5055 local icmp_id=5fbf
5056 local icmp_seq=0001
5057 local icmp_data=$(seq 1 56 | xargs printf "%02x")
5058 local icmp_type_code_request=0800
5059 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5060 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
5061
5062 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
5063 if test X$exp_icmp_chksum != X; then
5064 # Expect to receive the reply, if any. In same port where packet was sent.
5065 # Note: src and dst fields are expected to be reversed.
5066 local icmp_type_code_response=0000
5067 local reply_icmp_ttl=fe
5068 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5069 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
5070 echo $reply >> vif$inport.expected
5071 fi
5072 }
5073
5074 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
5075 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
5076 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
5077 l1_ip=$(ip_to_hex 192 168 1 2)
5078 l2_ip=$(ip_to_hex 172 16 1 2)
5079
5080 # Ping router ip address that is on same subnet as the logical port
5081 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
5082 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
5083
5084 # Ping router ip address that is on the other side of the logical ports
5085 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
5086 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
5087
5088 echo "---------NB dump-----"
5089 ovn-nbctl show
5090 echo "---------------------"
5091 ovn-nbctl list logical_router
5092 echo "---------------------"
5093 ovn-nbctl list logical_router_port
5094 echo "---------------------"
5095
5096 echo "---------SB dump-----"
5097 ovn-sbctl list datapath_binding
5098 echo "---------------------"
5099 ovn-sbctl list logical_flow
5100 echo "---------------------"
5101
5102 echo "------ hv1 dump ----------"
5103 as hv1 ovs-ofctl dump-flows br-int
5104
5105 # Now check the packets actually received against the ones expected.
5106 for inport in 1 2; do
5107 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
5108 done
5109
5110 OVN_CLEANUP([hv1])
5111
5112 AT_CLEANUP
5113
5114 # 1 hypervisor, 1 port
5115 # make sure that the port state is properly set to up and back down
5116 # when created and deleted.
5117 AT_SETUP([ovn -- port state up and down])
5118 ovn_start
5119
5120 ovn-nbctl ls-add ls1
5121 ovn-nbctl lsp-add ls1 lp1
5122 ovn-nbctl lsp-set-addresses lp1 unknown
5123
5124 net_add n1
5125 sim_add hv1
5126 as hv1 ovs-vsctl add-br br-phys
5127 as hv1 ovn_attach n1 br-phys 192.168.0.1
5128
5129 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5130 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5131
5132 as hv1 ovs-vsctl del-port br-int vif1
5133 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5134
5135 OVN_CLEANUP([hv1])
5136
5137 AT_CLEANUP
5138
5139 # 1 hypervisor, 1 port
5140 # make sure that the OF rules created to support a datapath are added/cleared
5141 # when logical switch is created and removed.
5142 AT_SETUP([ovn -- datapath rules added/removed])
5143 AT_KEYWORDS([cleanup])
5144 ovn_start
5145
5146 net_add n1
5147 sim_add hv1
5148 as hv1 ovs-vsctl add-br br-phys
5149 as hv1 ovn_attach n1 br-phys 192.168.0.1
5150
5151 # This shell function checks if OF rules in br-int have clauses
5152 # related to OVN datapaths. The caller determines if it should find
5153 # a match in the output, or not.
5154 #
5155 # EXPECT_DATAPATH param determines whether flows that refer to
5156 # datapath to should be present or not. 0 means
5157 # they should not be.
5158 # STAGE_INFO param is a simple string to help identify the stage
5159 # in the test when this function was invoked.
5160 test_datapath_in_of_rules() {
5161 local expect_datapath=$1 stage_info=$2
5162 echo "------ ovn-nbctl show ${stage_info} ------"
5163 ovn-nbctl show
5164 echo "------ ovn-sbctl show ${stage_info} ------"
5165 ovn-sbctl show
5166 echo "------ OF rules ${stage_info} ------"
5167 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
5168 # if there is a datapath mentioned in the output, check for the
5169 # magic keyword that represents one, based on the exit status of
5170 # a quiet grep
5171 if test $expect_datapath != 0; then
5172 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
5173 else
5174 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
5175 fi
5176 }
5177
5178 test_datapath_in_of_rules 0 "before ls+port create"
5179
5180 ovn-nbctl ls-add ls1
5181 ovn-nbctl lsp-add ls1 lp1
5182 ovn-nbctl lsp-set-addresses lp1 unknown
5183
5184 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5185 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5186
5187 test_datapath_in_of_rules 1 "after port is bound"
5188
5189 as hv1 ovs-vsctl del-port br-int vif1
5190 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5191
5192 ovn-nbctl lsp-set-addresses lp1
5193 ovn-nbctl lsp-del lp1
5194 ovn-nbctl ls-del ls1
5195
5196 # wait for earlier changes to take effect
5197 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
5198
5199 # ensure OF rules are no longer present. There used to be a bug here.
5200 test_datapath_in_of_rules 0 "after lport+ls removal"
5201
5202 OVN_CLEANUP([hv1])
5203
5204 AT_CLEANUP
5205
5206 AT_SETUP([ovn -- nd_na ])
5207 AT_SKIP_IF([test $HAVE_PYTHON = no])
5208 ovn_start
5209
5210 #TODO: since patch port for IPv6 logical router port is not ready not,
5211 # so we are not going to test vifs on different lswitches cases. Try
5212 # to update for that once relevant stuff implemented.
5213
5214 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
5215 # with. NS packet we test, from one VIF for another VIF, will be replied
5216 # by local ovn-controller, but not by target VIF.
5217
5218 # Create hypervisors and logical switch lsw0.
5219 ovn-nbctl ls-add lsw0
5220 net_add n1
5221 sim_add hv1
5222 as hv1
5223 ovs-vsctl add-br br-phys
5224 ovn_attach n1 br-phys 192.168.0.2
5225
5226 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5227 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
5228 ovn-nbctl lsp-add lsw0 lp1
5229 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5230 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"
5231
5232 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5233 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
5234 ovn-nbctl lsp-add lsw0 lp2
5235 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5236 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"
5237
5238 # Add ACL rule for ICMPv6 on lsw0
5239 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5240 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5241 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5242
5243 # Allow some time for ovn-northd and ovn-controller to catch up.
5244 # XXX This should be more systematic.
5245 sleep 1
5246
5247 # Given the name of a logical port, prints the name of the hypervisor
5248 # on which it is located.
5249 vif_to_hv() {
5250 echo hv1${1%?}
5251 }
5252 for i in 1 2; do
5253 : > $i.expected
5254 done
5255
5256 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5257 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5258 # vif2 will not receive NS packet, since ovn-controller will reply for it.
5259 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5260 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5261
5262 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
5263 echo $na_packet >> 1.expected
5264
5265 echo "------ hv1 dump ------"
5266 as hv1 ovs-vsctl show
5267 as hv1 ovs-ofctl -O OpenFlow13 show br-int
5268 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5269
5270 for i in 1 2; do
5271 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
5272 done
5273
5274 OVN_CLEANUP([hv1])
5275
5276 AT_CLEANUP
5277
5278 AT_SETUP([ovn -- address sets modification/removal smoke test])
5279 ovn_start
5280
5281 net_add n1
5282
5283 sim_add hv1
5284 as hv1
5285 ovs-vsctl add-br br-phys
5286 ovn_attach n1 br-phys 192.168.0.1
5287
5288 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5289 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5290 ovn-nbctl destroy Address_Set $row
5291
5292 sleep 1
5293
5294 # A bug previously existed in the address set support code
5295 # that caused ovn-controller to crash after an address set
5296 # was updated and then removed. This test case ensures
5297 # that ovn-controller is at least still running after
5298 # creating, updating, and deleting an address set.
5299 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5300
5301 OVN_CLEANUP([hv1])
5302
5303 AT_CLEANUP
5304
5305 AT_SETUP([ovn -- ipam])
5306 AT_SKIP_IF([test $HAVE_PYTHON = no])
5307 ovn_start
5308
5309 # Add a port to a switch that does not have a subnet set, then set the
5310 # subnet which should result in an address being allocated for the port.
5311 ovn-nbctl ls-add sw0
5312 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
5313 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
5314 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5315 ["0a:00:00:00:00:01 192.168.1.2"
5316 ])
5317
5318 # Add 9 more ports to sw0, addresses should all be unique.
5319 for n in `seq 1 9`; do
5320 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
5321 done
5322 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5323 ["0a:00:00:00:00:02 192.168.1.3"
5324 ])
5325 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5326 ["0a:00:00:00:00:03 192.168.1.4"
5327 ])
5328 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5329 ["0a:00:00:00:00:04 192.168.1.5"
5330 ])
5331 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5332 ["0a:00:00:00:00:05 192.168.1.6"
5333 ])
5334 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5335 ["0a:00:00:00:00:06 192.168.1.7"
5336 ])
5337 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5338 ["0a:00:00:00:00:07 192.168.1.8"
5339 ])
5340 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5341 ["0a:00:00:00:00:08 192.168.1.9"
5342 ])
5343 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5344 ["0a:00:00:00:00:09 192.168.1.10"
5345 ])
5346 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5347 ["0a:00:00:00:00:0a 192.168.1.11"
5348 ])
5349
5350 # Trying similar tests with a second switch. MAC addresses should be unique
5351 # across both switches but IP's only need to be unique within the same switch.
5352 ovn-nbctl ls-add sw1
5353 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
5354 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
5355 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
5356 ["0a:00:00:00:00:0b 192.168.1.2"
5357 ])
5358
5359 for n in `seq 11 19`; do
5360 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
5361 done
5362 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5363 ["0a:00:00:00:00:0c 192.168.1.3"
5364 ])
5365 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5366 ["0a:00:00:00:00:0d 192.168.1.4"
5367 ])
5368 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5369 ["0a:00:00:00:00:0e 192.168.1.5"
5370 ])
5371 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5372 ["0a:00:00:00:00:0f 192.168.1.6"
5373 ])
5374 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5375 ["0a:00:00:00:00:10 192.168.1.7"
5376 ])
5377 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5378 ["0a:00:00:00:00:11 192.168.1.8"
5379 ])
5380 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5381 ["0a:00:00:00:00:12 192.168.1.9"
5382 ])
5383 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5384 ["0a:00:00:00:00:13 192.168.1.10"
5385 ])
5386 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5387 ["0a:00:00:00:00:14 192.168.1.11"
5388 ])
5389
5390 # Change a port's address to test for multiple ip's for a single address entry
5391 # and addresses set by the user.
5392 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.2 192.168.1.12 192.168.1.14"
5393 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
5394 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5395 ["0a:00:00:00:00:16 192.168.1.13"
5396 ])
5397
5398 # Test for logical router port address management.
5399 ovn-nbctl create Logical_Router name=R1
5400 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5401 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5402 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5403 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
5404 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
5405 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5406 ["0a:00:00:00:00:18 192.168.1.15"
5407 ])
5408
5409 # Test for address reuse after logical port is deleted.
5410 ovn-nbctl lsp-del p0
5411 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
5412 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5413 ["0a:00:00:00:00:19 192.168.1.2"
5414 ])
5415
5416 # Test for multiple addresses to one logical port.
5417 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5418 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
5419 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
5420 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5421 ["0a:00:00:00:00:1c 192.168.1.16"
5422 ])
5423
5424 # Test for exhausting subnet address space.
5425 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
5426 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
5427 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5428 ["0a:00:00:00:00:1d 172.16.1.2"
5429 ])
5430
5431 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
5432 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
5433 ["0a:00:00:00:00:1e"
5434 ])
5435
5436 # Test that address management does not add duplicate MAC for lsp/lrp peers.
5437 ovn-nbctl create Logical_Router name=R2
5438 ovn-nbctl ls-add sw3
5439 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
5440 "0a:00:00:00:00:1f"
5441 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5442 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5443 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5444 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
5445 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
5446 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5447 ["0a:00:00:00:00:20 192.168.1.17"
5448 ])
5449
5450 # Test static MAC address with dynamically allocated IP
5451 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5452 "fe:dc:ba:98:76:54 dynamic"
5453 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5454 ["fe:dc:ba:98:76:54 192.168.1.18"
5455 ])
5456
5457 # Update the static MAC address with dynamically allocated IP and check
5458 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5459 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5460
5461 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5462 ["fe:dc:ba:98:76:55 192.168.1.18"
5463 ])
5464
5465 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5466 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5467 ["0a:00:00:00:00:21 192.168.1.18"
5468 ])
5469
5470 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5471 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5472 ["fe:dc:ba:98:76:56 192.168.1.18"
5473 ])
5474
5475
5476 # Test the exclude_ips from the IPAM list
5477 ovn-nbctl --wait=sb set logical_switch sw0 \
5478 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5479
5480 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5481 "dynamic"
5482 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5483 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5484 ["0a:00:00:00:00:22 192.168.1.20"
5485 ])
5486
5487 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5488 "dynamic"
5489 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5490 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5491 ["0a:00:00:00:00:23 192.168.1.22"
5492 ])
5493
5494 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5495 "dynamic"
5496 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5497 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5498 ["0a:00:00:00:00:24 192.168.1.51"
5499 ])
5500
5501 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5502 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5503 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5504 "dynamic"
5505 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5506 ["0a:00:00:00:00:25 192.168.1.19"
5507 ])
5508
5509 # Set invalid data in exclude_ips list. It should be ignored.
5510 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5511 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5512 "dynamic"
5513 # 192.168.1.21 should be assigned as that's the next free one.
5514 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5515 ["0a:00:00:00:00:26 192.168.1.21"
5516 ])
5517
5518 # Clear the dynamic addresses assignment request.
5519 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5520 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5521 [[[]]
5522 ])
5523
5524 # Set IPv6 prefix
5525 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5526 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5527 "dynamic"
5528
5529 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5530 # - aef0::800:ff:fe00:26 (EUI64)
5531 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5532 ["0a:00:00:00:00:27 192.168.1.21 aef0::800:ff:fe00:27"
5533 ])
5534
5535 ovn-nbctl --wait=sb ls-add sw4
5536 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
5537 -- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
5538 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5539 "dynamic"
5540
5541 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5542 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5543 ])
5544
5545 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5546 "f0:00:00:00:10:12 dynamic"
5547
5548 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5549 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5550 ])
5551
5552 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5553 # p40 should not have an IPv4 address since the pool is exhausted
5554 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5555 "dynamic"
5556 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5557 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5558 ])
5559
5560 # Test dynamic changes on switch ports.
5561 #
5562 ovn-nbctl --wait=sb ls-add sw5
5563 ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
5564 "dynamic"
5565 # p41 will start with nothing
5566 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5567 [[[]]
5568 ])
5569
5570 # Set a subnet. Now p41 should have an ipv4 address, too
5571 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5572 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5573 ["0a:00:00:00:00:2a 192.168.1.2"
5574 ])
5575
5576 # Clear the other_config. The IPv4 address should be gone
5577 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5578 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5579 [[[]]
5580 ])
5581
5582 # Set an IPv6 prefix. Now p41 should have an IPv6 address.
5583 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
5584 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5585 ["0a:00:00:00:00:2b aef0::800:ff:fe00:2b"
5586 ])
5587
5588 # Change the MAC address to a static one. The IPv6 address should update.
5589 ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
5590 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5591 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
5592 ])
5593
5594 # Change the IPv6 prefix. The IPv6 address should update.
5595 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
5596 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5597 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
5598 ])
5599
5600 # Clear the other_config. The IPv6 address should be gone
5601 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5602 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5603 [[[]]
5604 ])
5605
5606 # Set the subnet again. Now p41 should get the IPv4 address again.
5607 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5608 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5609 ["f0:00:00:00:10:2b 192.168.1.2"
5610 ])
5611
5612 # Add an excluded IP address that conflicts with p41. p41 should update.
5613 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
5614 exclude_ips="192.168.1.2"
5615 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5616 ["f0:00:00:00:10:2b 192.168.1.3"
5617 ])
5618
5619 # define a mac address prefix
5620 ovn-nbctl ls-add sw6
5621 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22:33:44:55"
5622 ovn-nbctl --wait=sb set Logical-Switch sw6 other_config:subnet=192.168.100.0/24
5623 for n in $(seq 1 3); do
5624 ovn-nbctl --wait=sb lsp-add sw6 "p5$n" -- lsp-set-addresses "p5$n" dynamic
5625 done
5626 AT_CHECK([ovn-nbctl get Logical-Switch-Port p51 dynamic_addresses], [0],
5627 ["00:11:22:00:00:4d 192.168.100.2"
5628 ])
5629 AT_CHECK([ovn-nbctl get Logical-Switch-Port p52 dynamic_addresses], [0],
5630 ["00:11:22:00:00:4e 192.168.100.3"
5631 ])
5632 AT_CHECK([ovn-nbctl get Logical-Switch-Port p53 dynamic_addresses], [0],
5633 ["00:11:22:00:00:4f 192.168.100.4"
5634 ])
5635
5636 as ovn-sb
5637 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5638
5639 as ovn-nb
5640 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5641
5642 as northd
5643 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5644
5645 AT_CLEANUP
5646
5647 AT_SETUP([ovn -- ipam connectivity])
5648 AT_SKIP_IF([test $HAVE_PYTHON = no])
5649 ovn_start
5650
5651 ovn-nbctl lr-add R1
5652
5653 # Test for a ping using dynamically allocated addresses.
5654 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5655 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5656
5657 # Connect foo to R1
5658 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5659 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5660 options:router-port=foo \
5661 -- lsp-set-addresses rp-foo router
5662
5663 # Connect alice to R1
5664 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5665 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5666 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5667
5668 # Create logical port foo1 in foo
5669 ovn-nbctl --wait=sb lsp-add foo foo1 \
5670 -- lsp-set-addresses foo1 "dynamic"
5671 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])
5672
5673 # Create logical port alice1 in alice
5674 ovn-nbctl --wait=sb lsp-add alice alice1 \
5675 -- lsp-set-addresses alice1 "dynamic"
5676 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5677
5678 # Create logical port foo2 in foo
5679 ovn-nbctl --wait=sb lsp-add foo foo2 \
5680 -- lsp-set-addresses foo2 "dynamic"
5681 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5682
5683 # Create a hypervisor and create OVS ports corresponding to logical ports.
5684 net_add n1
5685
5686 sim_add hv1
5687 as hv1
5688 ovs-vsctl add-br br-phys
5689 ovn_attach n1 br-phys 192.168.0.1
5690 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5691 set interface hv1-vif1 external-ids:iface-id=foo1 \
5692 options:tx_pcap=hv1/vif1-tx.pcap \
5693 options:rxq_pcap=hv1/vif1-rx.pcap \
5694 ofport-request=1
5695
5696 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5697 set interface hv1-vif2 external-ids:iface-id=foo2 \
5698 options:tx_pcap=hv1/vif2-tx.pcap \
5699 options:rxq_pcap=hv1/vif2-rx.pcap \
5700 ofport-request=2
5701
5702 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5703 set interface hv1-vif3 external-ids:iface-id=alice1 \
5704 options:tx_pcap=hv1/vif3-tx.pcap \
5705 options:rxq_pcap=hv1/vif3-rx.pcap \
5706 ofport-request=3
5707
5708 # Allow some time for ovn-northd and ovn-controller to catch up.
5709 # XXX This should be more systematic.
5710 sleep 1
5711
5712 ip_to_hex() {
5713 printf "%02x%02x%02x%02x" "$@"
5714 }
5715
5716 # Send ip packets between foo1 and foo2
5717 src_mac="0a0000000001"
5718 dst_mac="0a0000000003"
5719 src_ip=`ip_to_hex 192 168 1 2`
5720 dst_ip=`ip_to_hex 192 168 1 3`
5721 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5722 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5723
5724 # Send ip packets between foo1 and alice1
5725 src_mac="0a0000000001"
5726 dst_mac="000000010203"
5727 src_ip=`ip_to_hex 192 168 1 2`
5728 dst_ip=`ip_to_hex 192 168 2 2`
5729 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5730 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5731
5732 echo "---------NB dump-----"
5733 ovn-nbctl show
5734 echo "---------------------"
5735 ovn-nbctl list logical_router
5736 echo "---------------------"
5737 ovn-nbctl list logical_router_port
5738 echo "---------------------"
5739
5740 echo "---------SB dump-----"
5741 ovn-sbctl list datapath_binding
5742 echo "---------------------"
5743 ovn-sbctl list port_binding
5744 echo "---------------------"
5745
5746 echo "------ hv1 dump ----------"
5747 as hv1 ovs-ofctl dump-flows br-int
5748
5749 # Packet to Expect at foo2
5750 src_mac="0a0000000001"
5751 dst_mac="0a0000000003"
5752 src_ip=`ip_to_hex 192 168 1 2`
5753 dst_ip=`ip_to_hex 192 168 1 3`
5754 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5755
5756 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5757 echo $expected > expout
5758 AT_CHECK([cat received1.packets], [0], [expout])
5759
5760 # Packet to Expect at alice1
5761 src_mac="000000010204"
5762 dst_mac="0a0000000002"
5763 src_ip=`ip_to_hex 192 168 1 2`
5764 dst_ip=`ip_to_hex 192 168 2 2`
5765 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5766
5767 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5768 echo $expected > expout
5769 AT_CHECK([cat received2.packets], [0], [expout])
5770
5771 OVN_CLEANUP([hv1])
5772
5773 AT_CLEANUP
5774
5775 AT_SETUP([ovn -- ovs-vswitchd restart])
5776 AT_KEYWORDS([vswitchd])
5777 AT_SKIP_IF([test $HAVE_PYTHON = no])
5778 ovn_start
5779
5780 ovn-nbctl ls-add ls1
5781
5782 ovn-nbctl lsp-add ls1 ls1-lp1 \
5783 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5784
5785 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5786
5787 net_add n1
5788 sim_add hv1
5789
5790 as hv1
5791 ovs-vsctl add-br br-phys
5792 ovn_attach n1 br-phys 192.168.0.1
5793 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5794 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5795 options:tx_pcap=hv1/vif1-tx.pcap \
5796 options:rxq_pcap=hv1/vif1-rx.pcap \
5797 ofport-request=1
5798
5799 OVN_POPULATE_ARP
5800 sleep 2
5801
5802 as hv1 ovs-vsctl show
5803
5804 echo "---------------------"
5805 ovn-sbctl dump-flows
5806 echo "---------------------"
5807
5808 echo "------ hv1 dump ----------"
5809 as hv1 ovs-ofctl dump-flows br-int
5810 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5811
5812 echo "Total flows before vswitchd restart = " $total_flows
5813
5814 # Code taken from ovs-save utility
5815 save_flows () {
5816 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5817 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5818 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5819 echo "EOF" >> restore_flows.sh
5820 }
5821
5822 restart_vswitchd () {
5823 restore_flows=$1
5824
5825 if test $restore_flows = true; then
5826 save_flows
5827 fi
5828
5829 as hv1
5830 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5831
5832 if test $restore_flows = true; then
5833 as hv1
5834 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5835 fi
5836
5837 as hv1
5838 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5839 ovs-ofctl dump-flows br-int
5840
5841 if test $restore_flows = true; then
5842 sh ./restore_flows.sh
5843 echo "Flows after restore"
5844 as hv1
5845 ovs-ofctl dump-flows br-int
5846 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5847 flow-restore-wait="true"
5848 fi
5849 }
5850
5851 # Save the flows, restart vswitchd and restore the flows
5852 restart_vswitchd true
5853 OVS_WAIT_UNTIL([
5854 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5855 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5856 test "${total_flows}" = "${total_flows_after_restart}"
5857 ])
5858
5859 # Restart vswitchd without restoring
5860 restart_vswitchd false
5861 OVS_WAIT_UNTIL([
5862 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5863 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5864 test "${total_flows}" = "${total_flows_after_restart}"
5865 ])
5866
5867 OVN_CLEANUP([hv1])
5868 AT_CLEANUP
5869
5870 AT_SETUP([ovn -- send arp for nexthop])
5871 AT_SKIP_IF([test $HAVE_PYTHON = no])
5872 ovn_start
5873
5874 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5875
5876 # Create logical switches
5877 ovn-nbctl ls-add ls1
5878 ovn-nbctl ls-add ls2
5879
5880 # Create router
5881 ovn-nbctl create Logical_Router name=lr0
5882
5883 # Add router ls1p1 port to gateway router
5884 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5885 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5886 type=router options:router-port=lrp-ls1lp1 \
5887 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5888
5889 # Add router ls2p2 port to gateway router
5890 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5891 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5892 type=router options:router-port=lrp-ls2lp1 \
5893 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5894
5895 # Set default gateway (nexthop) to 192.168.1.254
5896 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5897
5898 # Create logical port ls1lp2 in ls1
5899 ovn-nbctl lsp-add ls1 ls1lp2 \
5900 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5901
5902 # Create logical port ls2lp2 in ls2
5903 ovn-nbctl lsp-add ls2 ls2lp2 \
5904 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5905
5906 net_add n1
5907 sim_add hv1
5908 as hv1
5909 ovs-vsctl add-br br-phys
5910 ovn_attach n1 br-phys 192.168.0.1
5911 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5912 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5913 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5914 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5915 ofport-request=1
5916 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5917 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5918 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5919 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5920 ofport-request=2
5921
5922 # Allow some time for ovn-northd and ovn-controller to catch up.
5923 # XXX This should be more systematic.
5924 sleep 1
5925
5926 echo "---------NB dump-----"
5927 ovn-nbctl show
5928 echo "---------------------"
5929 ovn-nbctl list logical_router
5930 echo "---------------------"
5931 ovn-nbctl list logical_router_port
5932 echo "---------------------"
5933
5934 echo "---------SB dump-----"
5935 ovn-sbctl list datapath_binding
5936 echo "---------------------"
5937 ovn-sbctl list port_binding
5938 echo "---------------------"
5939 ovn-sbctl dump-flows
5940 echo "---------------------"
5941 ovn-sbctl list chassis
5942 ovn-sbctl list encap
5943 echo "---------------------"
5944
5945 echo "------Flows dump-----"
5946 as hv1
5947 ovs-ofctl dump-flows
5948 echo "---------------------"
5949
5950 ip_to_hex() {
5951 printf "%02x%02x%02x%02x" "$@"
5952 }
5953
5954 src_mac="f00000000003"
5955 dst_mac="f00000000001"
5956 src_ip=`ip_to_hex 192 168 0 2`
5957 dst_ip=`ip_to_hex 8 8 8 8`
5958 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5959
5960 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5961 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5962
5963 trim_zeros() {
5964 sed 's/\(00\)\{1,\}$//'
5965 }
5966
5967 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5968 # not 8.8.8.8
5969
5970 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5971 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5972 echo $expected > expout
5973 AT_CHECK([cat packets], [0], [expout])
5974 cat packets
5975
5976 OVN_CLEANUP([hv1])
5977
5978 AT_CLEANUP
5979
5980 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5981 AT_SKIP_IF([test $HAVE_PYTHON = no])
5982 ovn_start
5983 # Create logical switch
5984 ovn-nbctl ls-add ls0
5985 # Create gateway router
5986 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5987 # Add router port to gateway router
5988 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5989 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5990 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5991 # Add nat-address option
5992 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5993
5994 net_add n1
5995 sim_add hv1
5996 as hv1
5997 ovs-vsctl \
5998 -- add-br br-phys \
5999 -- add-br br-eth0
6000
6001 ovn_attach n1 br-phys 192.168.0.1
6002
6003 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6004 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])
6005
6006 # Create a localnet port.
6007 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6008 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6009 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6010 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6011
6012
6013 # Wait for packet to be received.
6014 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6015 trim_zeros() {
6016 sed 's/\(00\)\{1,\}$//'
6017 }
6018 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6019 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6020 echo $expected > expout
6021 AT_CHECK([sort packets], [0], [expout])
6022 cat packets
6023
6024 OVN_CLEANUP([hv1])
6025
6026 AT_CLEANUP
6027
6028 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6029 AT_SKIP_IF([test $HAVE_PYTHON = no])
6030 ovn_start
6031 # Create logical switch
6032 ovn-nbctl ls-add ls0
6033 # Create gateway router
6034 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6035 # Add router port to gateway router
6036 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6037 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
6038 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
6039 # Add nat-address option
6040 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6041 # Add NAT rules
6042 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6043 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6044 # Add load balancers
6045 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6046 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6047 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6048 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6049
6050 net_add n1
6051 sim_add hv1
6052 as hv1
6053 ovs-vsctl \
6054 -- add-br br-phys \
6055 -- add-br br-eth0
6056
6057 ovn_attach n1 br-phys 192.168.0.1
6058
6059 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6060 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])
6061
6062 # Create a localnet port.
6063 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6064 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6065 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6066 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6067
6068
6069 # Wait for packet to be received.
6070 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6071 trim_zeros() {
6072 sed 's/\(00\)\{1,\}$//'
6073 }
6074 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6075 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6076 echo $expected > expout
6077 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6078 echo $expected >> expout
6079 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6080 echo $expected >> expout
6081 AT_CHECK([sort packets], [0], [expout])
6082 cat packets
6083
6084 OVN_CLEANUP([hv1])
6085
6086 AT_CLEANUP
6087
6088 AT_SETUP([ovn -- delete mac bindings])
6089 ovn_start
6090 net_add n1
6091 sim_add hv1
6092 as hv1
6093 ovs-vsctl -- add-br br-phys
6094 ovn_attach n1 br-phys 192.168.0.1
6095 # Create logical switch ls0
6096 ovn-nbctl ls-add ls0
6097 # Create ports lp0, lp1 in ls0
6098 ovn-nbctl lsp-add ls0 lp0
6099 ovn-nbctl lsp-add ls0 lp1
6100 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6101 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6102 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6103 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6104 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6105 ovn-sbctl find MAC_Binding
6106 # Delete port lp0 and check that its MAC_Binding is deleted.
6107 ovn-nbctl lsp-del lp0
6108 ovn-sbctl find MAC_Binding
6109 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6110 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
6111 ovn-nbctl ls-del ls0
6112 ovn-sbctl find MAC_Binding
6113 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6114
6115 OVN_CLEANUP([hv1])
6116
6117 AT_CLEANUP
6118
6119 AT_SETUP([ovn -- conntrack zone allocation])
6120 AT_SKIP_IF([test $HAVE_PYTHON = no])
6121 ovn_start
6122
6123 # Logical network:
6124 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6125 # connected to a router R1.
6126 # foo has foo1 to act as a client.
6127 # bar has bar1, bar2, bar3 to act as servers.
6128
6129 net_add n1
6130
6131 sim_add hv1
6132 as hv1
6133 ovs-vsctl add-br br-phys
6134 ovn_attach n1 br-phys 192.168.0.1
6135 for i in foo1 bar1 bar2 bar3; do
6136 ovs-vsctl -- add-port br-int $i -- \
6137 set interface $i external-ids:iface-id=$i \
6138 options:tx_pcap=hv1/$i-tx.pcap \
6139 options:rxq_pcap=hv1/$i-rx.pcap
6140 done
6141
6142 ovn-nbctl create Logical_Router name=R1
6143 ovn-nbctl ls-add foo
6144 ovn-nbctl ls-add bar
6145
6146 # Connect foo to R1
6147 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6148 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6149 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6150
6151 # Connect bar to R1
6152 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6153 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6154 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6155
6156 # Create logical port foo1 in foo
6157 ovn-nbctl lsp-add foo foo1 \
6158 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6159
6160 # Create logical port bar1, bar2 and bar3 in bar
6161 for i in `seq 1 3`; do
6162 ip=`expr $i + 1`
6163 ovn-nbctl lsp-add bar bar$i \
6164 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6165 done
6166
6167 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6168
6169 OVN_CLEANUP([hv1])
6170
6171 AT_CLEANUP
6172
6173 AT_SETUP([ovn -- tag allocation])
6174 ovn_start
6175
6176 AT_CHECK([ovn-nbctl ls-add ls0])
6177 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6178 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6179 AT_CHECK([ovn-nbctl ls-add ls1])
6180
6181 dnl When a tag is provided, no allocation is done
6182 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6183 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6184 ])
6185 dnl The same 'tag' gets created in southbound database.
6186 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6187 logical_port="c0"], [0], [3
6188 ])
6189
6190 dnl Allocate tags and see it getting created in both NB and SB
6191 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6192 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6193 ])
6194 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6195 logical_port="c1"], [0], [1
6196 ])
6197
6198 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6199 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6200 ])
6201 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6202 logical_port="c2"], [0], [2
6203 ])
6204 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6205 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6206 ])
6207 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6208 logical_port="c3"], [0], [4
6209 ])
6210
6211 dnl A different parent.
6212 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6213 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6214 ])
6215 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6216 logical_port="c4"], [0], [1
6217 ])
6218
6219 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6220 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6221 ])
6222 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6223 logical_port="c5"], [0], [2
6224 ])
6225
6226 dnl Delete a logical port and create a new one.
6227 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6228 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6229 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6230 ])
6231 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6232 logical_port="c6"], [0], [1
6233 ])
6234
6235 dnl Restart northd to see that the same allocation remains.
6236 as northd
6237 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6238 start_daemon ovn-northd \
6239 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6240 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6241
6242 dnl Create a switch to make sure that ovn-northd has run through the main loop.
6243 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6244 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6245 ])
6246 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6247 ])
6248 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6249 ])
6250 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6251 ])
6252 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6253 ])
6254 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6255 ])
6256
6257 dnl Create a switch port with a tag that has already been allocated.
6258 dnl It should go through fine with a duplicate tag.
6259 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6260 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6261 ])
6262 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6263 logical_port="c7"], [0], [2
6264 ])
6265 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6266 ])
6267
6268 AT_CHECK([ovn-nbctl ls-add ls2])
6269 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
6270 dnl gets copied to 'tag'
6271 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
6272 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
6273 ])
6274 dnl The same 'tag' gets created in southbound database.
6275 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6276 logical_port="local0"], [0], [25
6277 ])
6278 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
6279 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
6280 AT_CHECK([ovn-nbctl lsp-get-tag local1])
6281 dnl change the tag_request.
6282 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
6283 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
6284 ])
6285
6286 AT_CLEANUP
6287
6288 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
6289 ovn_start
6290 ovn-nbctl ls-add lsw0
6291 net_add n1
6292 for i in 1 2; do
6293 sim_add hv$i
6294 as hv$i
6295 ovs-vsctl add-br br-phys
6296 ovn_attach n1 br-phys 192.168.0.$i
6297 ovs-vsctl add-br br-eth0
6298 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6299 done
6300
6301 # Create a localnet port.
6302 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
6303 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6304 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6305 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6306
6307
6308 # Create 3 vifs.
6309 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6310 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6311 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6312 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
6313 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
6314 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6315 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6316 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6317 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6318
6319 # Bind the localvif1 to hv1.
6320 as hv1
6321 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6322
6323 # On hv1, check that there are no flows outputting bcast to tunnel
6324 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6325
6326 # On hv2, check that no flow outputs bcast to tunnel to hv1.
6327 as hv2
6328 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6329
6330 # Now bind vif2 on hv2.
6331 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6332
6333 # At this point, the broadcast flow on vif2 should be deleted.
6334 # because, there is now a localnet vif bound (table=32 programming logic)
6335 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6336
6337 # Verify that the local net patch port exists on hv2.
6338 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6339
6340 # Now bind vif3 on hv2.
6341 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6342
6343 # Verify that the local net patch port still exists on hv2
6344 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6345
6346 # Delete localvif2
6347 AT_CHECK([ovn-nbctl lsp-del localvif2])
6348
6349 # Verify that the local net patch port still exists on hv2,
6350 # because, localvif3 is still bound.
6351 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6352
6353 OVN_CLEANUP([hv1],[hv2])
6354
6355 AT_CLEANUP
6356
6357
6358 AT_SETUP([ovn -- ACL logging])
6359 AT_KEYWORDS([ovn])
6360 ovn_start
6361
6362 net_add n1
6363
6364 sim_add hv
6365 as hv
6366 ovs-vsctl add-br br-phys
6367 ovn_attach n1 br-phys 192.168.0.1
6368 for i in lp1 lp2; do
6369 ovs-vsctl -- add-port br-int $i -- \
6370 set interface $i external-ids:iface-id=$i \
6371 options:tx_pcap=hv/$i-tx.pcap \
6372 options:rxq_pcap=hv/$i-rx.pcap
6373 done
6374
6375 lp1_mac="f0:00:00:00:00:01"
6376 lp1_ip="192.168.1.2"
6377
6378 lp2_mac="f0:00:00:00:00:02"
6379 lp2_ip="192.168.1.3"
6380
6381 ovn-nbctl ls-add lsw0
6382 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6383 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6384 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6385 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6386 ovn-nbctl --wait=sb sync
6387
6388 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6389 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6390
6391 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6392 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6393
6394 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6395 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6396
6397 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6398 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6399
6400 ovn-sbctl dump-flows
6401
6402
6403 # Send packet that should be dropped without logging.
6404 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6405 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6406 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6407 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6408
6409 # Send packet that should be dropped with logging.
6410 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6411 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6412 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6413 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6414
6415 # Send packet that should be allowed without logging.
6416 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6417 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6418 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6419 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6420
6421 # Send packet that should be allowed with logging.
6422 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6423 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6424 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6425 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6426
6427 # Send packet that should allow related flows without logging.
6428 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6429 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6430 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6431 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6432
6433 # Send packet that should allow related flows with logging.
6434 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6435 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6436 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6437 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6438
6439 # Send packet that should be rejected without logging.
6440 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6441 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6442 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6443 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6444
6445 # Send packet that should be rejected with logging.
6446 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6447 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6448 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6449 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6450
6451 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6452
6453 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6454 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
6455 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
6456 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
6457 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
6458 ])
6459
6460 OVN_CLEANUP([hv])
6461 AT_CLEANUP
6462
6463
6464 AT_SETUP([ovn -- ACL rate-limited logging])
6465 AT_KEYWORDS([ovn])
6466 ovn_start
6467
6468 net_add n1
6469
6470 sim_add hv
6471 as hv
6472 ovs-vsctl add-br br-phys
6473 ovn_attach n1 br-phys 192.168.0.1
6474 for i in lp1 lp2; do
6475 ovs-vsctl -- add-port br-int $i -- \
6476 set interface $i external-ids:iface-id=$i \
6477 options:tx_pcap=hv/$i-tx.pcap \
6478 options:rxq_pcap=hv/$i-rx.pcap
6479 done
6480
6481 lp1_mac="f0:00:00:00:00:01"
6482 lp1_ip="192.168.1.2"
6483
6484 lp2_mac="f0:00:00:00:00:02"
6485 lp2_ip="192.168.1.3"
6486
6487 ovn-nbctl ls-add lsw0
6488 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6489 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6490 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6491 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6492 ovn-nbctl --wait=sb sync
6493
6494
6495 # Add an ACL that rate-limits logs at 10 per second.
6496 ovn-nbctl meter-add http-rl1 drop 10 pktps
6497 ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6498
6499 # Add an ACL that rate-limits logs at 5 per second.
6500 ovn-nbctl meter-add http-rl2 drop 5 pktps
6501 ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
6502
6503 # Add an ACL that doesn't rate-limit logs.
6504 ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
6505
6506
6507 # For each ACL, send 100 packets.
6508 for i in `seq 1 100`; do
6509 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=80)'
6510
6511 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=81)'
6512
6513 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=82)'
6514 done
6515
6516 # The rate at which packets are sent is highly system-dependent, so we
6517 # can't count on precise drop counts. To work around that, we just
6518 # check that exactly 100 "http-acl3" actions were logged and that there
6519 # were more "http-acl1" actions than "http-acl2" ones.
6520 OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
6521
6522 # On particularly slow or overloaded systems, the transmission rate may
6523 # be lower than the configured meter rate. To prevent false test
6524 # failures, we check the duration count of the meter, and if it's
6525 # greater than nine seconds, just skip the test.
6526 d_secs=$(as hv ovs-ofctl -O OpenFlow13 meter-stats br-int | grep "meter:1" | sed 's/.* duration:\([[0-9]]\{1,\}\)\.[[0-9]]\+s .*/\1/')
6527
6528 echo "Meter duration: $d_secs"
6529 AT_SKIP_IF([test $d_secs -gt 9])
6530
6531 # Print some information that may help debugging.
6532 as hv ovs-appctl -t ovn-controller meter-table-list
6533 as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
6534
6535 n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
6536 n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
6537 n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
6538
6539 AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
6540 AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
6541
6542 OVN_CLEANUP([hv])
6543 AT_CLEANUP
6544
6545
6546 AT_SETUP([ovn -- DSCP marking and meter check])
6547 AT_KEYWORDS([ovn])
6548 ovn_start
6549
6550 ovn-nbctl ls-add lsw0
6551 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6552 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6553 ovn-nbctl --wait=sb lsp-add lsw0 lp3
6554 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6555 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
6556 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
6557 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6558 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6559 ovn-nbctl --wait=sb sync
6560 net_add n1
6561 sim_add hv
6562 as hv
6563 ovs-vsctl add-br br-phys
6564 ovn_attach n1 br-phys 192.168.0.1
6565 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
6566 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
6567
6568 AT_CAPTURE_FILE([trace])
6569 ovn_trace () {
6570 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6571 }
6572
6573 # Extracts nw_tos from the final flow from ofproto/trace output and prints
6574 # it on stdout. Prints "none" if no nw_tos was included.
6575 get_final_nw_tos() {
6576 if flow=$(grep '^Final flow:' stdout); then :; else
6577 # The output didn't have a final flow.
6578 return 99
6579 fi
6580
6581 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6582 case $tos in
6583 '') echo none ;;
6584 *) echo $tos ;;
6585 esac
6586 }
6587
6588 # check_tos TOS
6589 #
6590 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6591 check_tos() {
6592 # First check with ovn-trace for logical flows.
6593 echo "checking for tos $1"
6594 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6595 echo 'output("lp2");') > expout
6596 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])
6597
6598 # Then re-check with ofproto/trace for a physical packet.
6599 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])
6600 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6601 ])
6602 }
6603
6604 # check at L2
6605 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");
6606 ])
6607 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])
6608 AT_CHECK([get_final_nw_tos], [0], [none
6609 ])
6610
6611 # check at L3 without dscp marking
6612 check_tos 0
6613
6614 # Mark DSCP with a valid value
6615 qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"\ &&\ is_chassis_resident(\"lp1\")" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
6616 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6617 ])
6618 check_tos 48
6619
6620 # check at hv without qos meter
6621 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6622 ])
6623
6624 # Update the meter rate
6625 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6626
6627 # check at hv with a qos meter table
6628 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6629 ])
6630 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6631 ])
6632
6633 # Update the DSCP marking
6634 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6635 check_tos 63
6636
6637 # Update the meter rate
6638 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6639
6640 # check at hv with a qos meter table
6641 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6642 ])
6643 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6644 ])
6645
6646 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6647 check_tos 63
6648
6649 # Disable DSCP marking
6650 ovn-nbctl --wait=hv qos-del lsw0
6651 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6652 ])
6653 check_tos 0
6654
6655 # check at hv without qos meter
6656 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6657 ])
6658
6659 # check meter with chassis not resident
6660 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6661 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6662 ])
6663
6664 # check no meter table
6665 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6666 ])
6667 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6668 ])
6669
6670 OVN_CLEANUP([hv])
6671 AT_CLEANUP
6672
6673 AT_SETUP([ovn -- read-only sb db:ptcp access])
6674 AT_SKIP_IF([test $HAVE_PYTHON = no])
6675
6676 : > .$1.db.~lock~
6677 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6678
6679 # Add read-only remote to sb ovsdb-server
6680 AT_CHECK(
6681 [ovsdb-tool transact ovn-sb.db \
6682 ['["OVN_Southbound",
6683 {"op": "insert",
6684 "table": "SB_Global",
6685 "row": {
6686 "connections": ["set", [["named-uuid", "xyz"]]]}},
6687 {"op": "insert",
6688 "table": "Connection",
6689 "uuid-name": "xyz",
6690 "row": {"target": "ptcp:0:127.0.0.1",
6691 "read_only": true}}]']], [0], [ignore], [ignore])
6692
6693 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6694
6695 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6696
6697 # read-only accesses should succeed
6698 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6699 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6700
6701 # write access should fail
6702 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6703 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6704 ])
6705
6706 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6707 AT_CLEANUP
6708
6709 AT_SETUP([ovn -- read-only sb db:pssl access])
6710 AT_SKIP_IF([test $HAVE_PYTHON = no])
6711 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6712 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6713 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6714 \\]"])
6715
6716 : > .$1.db.~lock~
6717 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6718
6719 # Add read-only remote to sb ovsdb-server
6720 AT_CHECK(
6721 [ovsdb-tool transact ovn-sb.db \
6722 ['["OVN_Southbound",
6723 {"op": "insert",
6724 "table": "SB_Global",
6725 "row": {
6726 "connections": ["set", [["named-uuid", "xyz"]]]}},
6727 {"op": "insert",
6728 "table": "Connection",
6729 "uuid-name": "xyz",
6730 "row": {"target": "pssl:0:127.0.0.1",
6731 "read_only": true}}]']], [0], [ignore], [ignore])
6732
6733 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6734 --remote=db:OVN_Southbound,SB_Global,connections \
6735 --private-key="$PKIDIR/testpki-privkey2.pem" \
6736 --certificate="$PKIDIR/testpki-cert2.pem" \
6737 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6738 ovn-sb.db
6739
6740 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6741
6742 # read-only accesses should succeed
6743 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6744 --private-key=$PKIDIR/testpki-privkey.pem \
6745 --certificate=$PKIDIR/testpki-cert.pem \
6746 --ca-cert=$PKIDIR/testpki-cacert.pem \
6747 list SB_Global], [0], [stdout], [ignore])
6748 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6749 --private-key=$PKIDIR/testpki-privkey.pem \
6750 --certificate=$PKIDIR/testpki-cert.pem \
6751 --ca-cert=$PKIDIR/testpki-cacert.pem \
6752 list Connection], [0], [stdout], [ignore])
6753
6754 # write access should fail
6755 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6756 --private-key=$PKIDIR/testpki-privkey.pem \
6757 --certificate=$PKIDIR/testpki-cert.pem \
6758 --ca-cert=$PKIDIR/testpki-cacert.pem \
6759 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6760 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6761 ])
6762
6763 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6764 AT_CLEANUP
6765
6766 AT_SETUP([ovn -- nb connection/ssl commands])
6767 AT_SKIP_IF([test $HAVE_PYTHON = no])
6768 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6769 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6770 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6771 \\]"])
6772
6773 : > .$1.db.~lock~
6774 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6775
6776 # Start nb db server using db connection/ssl entries (unpopulated initially)
6777 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6778 --remote=db:OVN_Northbound,NB_Global,connections \
6779 --private-key=db:OVN_Northbound,SSL,private_key \
6780 --certificate=db:OVN_Northbound,SSL,certificate \
6781 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6782 ovn-nb.db
6783
6784 # Populate SSL configuration entries in nb db
6785 AT_CHECK(
6786 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6787 $PKIDIR/testpki-cert.pem \
6788 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6789
6790 # Populate a passive SSL connection in nb db
6791 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6792
6793 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6794
6795 # Verify SSL connetivity to nb db server
6796 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6797 --private-key=$PKIDIR/testpki-privkey.pem \
6798 --certificate=$PKIDIR/testpki-cert.pem \
6799 --ca-cert=$PKIDIR/testpki-cacert.pem \
6800 list NB_Global],
6801 [0], [stdout], [ignore])
6802 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6803 --private-key=$PKIDIR/testpki-privkey.pem \
6804 --certificate=$PKIDIR/testpki-cert.pem \
6805 --ca-cert=$PKIDIR/testpki-cacert.pem \
6806 list Connection],
6807 [0], [stdout], [ignore])
6808 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6809 --private-key=$PKIDIR/testpki-privkey.pem \
6810 --certificate=$PKIDIR/testpki-cert.pem \
6811 --ca-cert=$PKIDIR/testpki-cacert.pem \
6812 get-connection],
6813 [0], [stdout], [ignore])
6814
6815 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6816 AT_CLEANUP
6817
6818 AT_SETUP([ovn -- sb connection/ssl commands])
6819 AT_SKIP_IF([test $HAVE_PYTHON = no])
6820 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6821 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6822 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6823 \\]"])
6824
6825 : > .$1.db.~lock~
6826 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6827
6828 # Start sb db server using db connection/ssl entries (unpopulated initially)
6829 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6830 --remote=db:OVN_Southbound,SB_Global,connections \
6831 --private-key=db:OVN_Southbound,SSL,private_key \
6832 --certificate=db:OVN_Southbound,SSL,certificate \
6833 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6834 ovn-sb.db
6835
6836 # Populate SSL configuration entries in sb db
6837 AT_CHECK(
6838 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6839 $PKIDIR/testpki-cert.pem \
6840 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6841
6842 # Populate a passive SSL connection in sb db
6843 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6844
6845 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6846
6847 # Verify SSL connetivity to sb db server
6848 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6849 --private-key=$PKIDIR/testpki-privkey.pem \
6850 --certificate=$PKIDIR/testpki-cert.pem \
6851 --ca-cert=$PKIDIR/testpki-cacert.pem \
6852 list SB_Global],
6853 [0], [stdout], [ignore])
6854 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6855 --private-key=$PKIDIR/testpki-privkey.pem \
6856 --certificate=$PKIDIR/testpki-cert.pem \
6857 --ca-cert=$PKIDIR/testpki-cacert.pem \
6858 list Connection],
6859 [0], [stdout], [ignore])
6860 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6861 --private-key=$PKIDIR/testpki-privkey.pem \
6862 --certificate=$PKIDIR/testpki-cert.pem \
6863 --ca-cert=$PKIDIR/testpki-cacert.pem \
6864 get-connection],
6865 [0], [stdout], [ignore])
6866
6867 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6868 AT_CLEANUP
6869
6870 AT_SETUP([ovn -- nested containers])
6871 ovn_start
6872
6873 # Physical network:
6874 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6875
6876 # Logical network:
6877 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6878 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6879
6880 ovn-nbctl lr-add R1
6881 ovn-nbctl ls-add mgmt
6882 ovn-nbctl ls-add foo
6883 ovn-nbctl ls-add bar
6884
6885 # Connect mgmt to R1
6886 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6887 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6888 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6889
6890 # Connect foo to R1
6891 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6892 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6893 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6894
6895 # Connect bar to R1
6896 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6897 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6898 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6899
6900 # "mgmt" has VM1 and VM2 connected
6901 ovn-nbctl lsp-add mgmt vm1 \
6902 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6903
6904 ovn-nbctl lsp-add mgmt vm2 \
6905 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6906
6907 # "foo1" and "foo2" are containers belonging to switch "foo"
6908 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6909 ovn-nbctl lsp-add foo foo1 vm1 1 \
6910 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6911
6912 ovn-nbctl lsp-add foo foo2 vm2 2 \
6913 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6914
6915 # "bar1" and "bar2" are containers belonging to switch "bar"
6916 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6917 ovn-nbctl lsp-add bar bar1 vm1 2 \
6918 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6919
6920 ovn-nbctl lsp-add bar bar2 vm2 1 \
6921 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6922
6923 # bar3 is a standalone VM belonging to switch "bar"
6924 ovn-nbctl lsp-add bar bar3 \
6925 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6926
6927 # Create two hypervisor and create OVS ports corresponding to logical ports.
6928 net_add n1
6929
6930 sim_add hv1
6931 as hv1
6932 ovs-vsctl add-br br-phys
6933 ovn_attach n1 br-phys 192.168.0.1
6934 ovs-vsctl -- add-port br-int vm1 -- \
6935 set interface vm1 external-ids:iface-id=vm1 \
6936 options:tx_pcap=hv1/vm1-tx.pcap \
6937 options:rxq_pcap=hv1/vm1-rx.pcap \
6938 ofport-request=1
6939
6940 ovs-vsctl -- add-port br-int bar3 -- \
6941 set interface bar3 external-ids:iface-id=bar3 \
6942 options:tx_pcap=hv1/bar3-tx.pcap \
6943 options:rxq_pcap=hv1/bar3-rx.pcap \
6944 ofport-request=2
6945
6946 sim_add hv2
6947 as hv2
6948 ovs-vsctl add-br br-phys
6949 ovn_attach n1 br-phys 192.168.0.2
6950 ovs-vsctl -- add-port br-int vm2 -- \
6951 set interface vm2 external-ids:iface-id=vm2 \
6952 options:tx_pcap=hv2/vm2-tx.pcap \
6953 options:rxq_pcap=hv2/vm2-rx.pcap \
6954 ofport-request=1
6955
6956 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6957 # packets for ARP resolution (native tunneling doesn't queue packets
6958 # for ARP resolution).
6959 OVN_POPULATE_ARP
6960
6961 # Allow some time for ovn-northd and ovn-controller to catch up.
6962 # XXX This should be more systematic.
6963 sleep 1
6964
6965 ip_to_hex() {
6966 printf "%02x%02x%02x%02x" "$@"
6967 }
6968
6969 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6970 # different VLAN tags).
6971 src_mac="f00000010205"
6972 dst_mac="f00000010206"
6973 src_ip=`ip_to_hex 192 168 1 2`
6974 dst_ip=`ip_to_hex 192 168 1 3`
6975 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6976 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6977
6978 # expected packet at foo2
6979 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6980 echo $packet > expected
6981 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6982
6983 # Send ip packets between foo1 and bar2 (different switch, different HV)
6984 src_mac="f00000010205"
6985 dst_mac="000000010203"
6986 src_ip=`ip_to_hex 192 168 1 2`
6987 dst_ip=`ip_to_hex 192 168 2 3`
6988 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6989 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6990
6991 # expected packet at bar2
6992 src_mac="000000010204"
6993 dst_mac="f00000010208"
6994 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6995 echo $packet >> expected
6996 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6997
6998 # Send ip packets between foo1 and bar1
6999 # (different switch, loopback to same vm but different tag)
7000 src_mac="f00000010205"
7001 dst_mac="000000010203"
7002 src_ip=`ip_to_hex 192 168 1 2`
7003 dst_ip=`ip_to_hex 192 168 2 2`
7004 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7005 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7006
7007 # expected packet at bar1
7008 src_mac="000000010204"
7009 dst_mac="f00000010207"
7010 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7011 echo $packet > expected1
7012 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7013
7014 # Send ip packets between bar1 and bar3
7015 # (same switch. But one is container and another is a standalone VM)
7016 src_mac="f00000010207"
7017 dst_mac="f00000010209"
7018 src_ip=`ip_to_hex 192 168 2 2`
7019 dst_ip=`ip_to_hex 192 168 2 3`
7020 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7021 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7022
7023 # expected packet at bar3
7024 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7025 echo $packet > expected
7026 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7027
7028 # Send ip packets between foo1 and vm1.
7029 (different switch, container to the VM hosting it.)
7030 src_mac="f00000010205"
7031 dst_mac="000000010203"
7032 src_ip=`ip_to_hex 192 168 1 2`
7033 dst_ip=`ip_to_hex 172 16 1 2`
7034 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7035 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7036
7037 # expected packet at vm1
7038 src_mac="000000010202"
7039 dst_mac="f00000010203"
7040 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7041 echo $packet >> expected1
7042 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7043
7044 # Send packets from vm1 to bar1.
7045 (different switch, A hosting VM to a container inside it)
7046 src_mac="f00000010203"
7047 dst_mac="000000010202"
7048 src_ip=`ip_to_hex 172 16 1 2`
7049 dst_ip=`ip_to_hex 192 168 2 2`
7050 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7051 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7052
7053 # expected packet at vm1
7054 src_mac="000000010204"
7055 dst_mac="f00000010207"
7056 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7057 echo $packet >> expected1
7058 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7059
7060 # Send broadcast packet from foo1. foo1 should not receive the same packet.
7061 src_mac="f00000010205"
7062 dst_mac="ffffffffffff"
7063 src_ip=`ip_to_hex 192 168 1 2`
7064 dst_ip=`ip_to_hex 255 255 255 255`
7065 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7066 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7067
7068 # expected packet at VM1
7069 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7070
7071 OVN_CLEANUP([hv1],[hv2])
7072
7073 AT_CLEANUP
7074
7075 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7076 AT_SKIP_IF([test $HAVE_PYTHON = no])
7077 ovn_start
7078
7079 # Logical network:
7080 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7081 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7082 # (192.168.2.0/24) connected to it.
7083 #
7084 # R2 and R3 are gateway routers.
7085 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7086 # connected to it. Note how both alice and bob have the same subnet behind it.
7087 # We are trying to simulate external network via those 2 switches. In real
7088 # world the switch ports of these switches will have addresses set as "unknown"
7089 # to make them learning switches. Or those switches will be "localnet" ones.
7090
7091 # Create three hypervisors and create OVS ports corresponding to logical ports.
7092 net_add n1
7093
7094 sim_add hv1
7095 as hv1
7096 ovs-vsctl add-br br-phys
7097 ovn_attach n1 br-phys 192.168.0.1
7098 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7099 set interface hv1-vif1 external-ids:iface-id=foo1 \
7100 options:tx_pcap=hv1/vif1-tx.pcap \
7101 options:rxq_pcap=hv1/vif1-rx.pcap \
7102 ofport-request=1
7103
7104 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7105 set interface hv1-vif2 external-ids:iface-id=bar1 \
7106 options:tx_pcap=hv1/vif2-tx.pcap \
7107 options:rxq_pcap=hv1/vif2-rx.pcap \
7108 ofport-request=2
7109
7110 sim_add hv2
7111 as hv2
7112 ovs-vsctl add-br br-phys
7113 ovn_attach n1 br-phys 192.168.0.2
7114 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7115 set interface hv2-vif1 external-ids:iface-id=alice1 \
7116 options:tx_pcap=hv2/vif1-tx.pcap \
7117 options:rxq_pcap=hv2/vif1-rx.pcap \
7118 ofport-request=1
7119
7120 sim_add hv3
7121 as hv3
7122 ovs-vsctl add-br br-phys
7123 ovn_attach n1 br-phys 192.168.0.3
7124 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7125 set interface hv3-vif1 external-ids:iface-id=bob1 \
7126 options:tx_pcap=hv3/vif1-tx.pcap \
7127 options:rxq_pcap=hv3/vif1-rx.pcap \
7128 ofport-request=1
7129
7130
7131 ovn-nbctl create Logical_Router name=R1
7132 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7133 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7134
7135 ovn-nbctl ls-add foo
7136 ovn-nbctl ls-add bar
7137 ovn-nbctl ls-add alice
7138 ovn-nbctl ls-add bob
7139 ovn-nbctl ls-add join
7140
7141 # Connect foo to R1
7142 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7143 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7144 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7145
7146 # Connect bar to R1
7147 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7148 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7149 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7150
7151 # Connect alice to R2
7152 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7153 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7154 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7155
7156 # Connect bob to R3
7157 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7158 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7159 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7160
7161 # Connect R1 to join
7162 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7163 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7164 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7165
7166 # Connect R2 to join
7167 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7168 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7169 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7170
7171 # Connect R3 to join
7172 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7173 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7174 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7175
7176 # Install static routes with source ip address as the policy for routing.
7177 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7178 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7179 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7180
7181 # Install static routes with destination ip address as the policy for routing.
7182 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7183
7184 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7185
7186 # Create logical port foo1 in foo
7187 ovn-nbctl lsp-add foo foo1 \
7188 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7189
7190 # Create logical port bar1 in bar
7191 ovn-nbctl lsp-add bar bar1 \
7192 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7193
7194 # Create logical port alice1 in alice
7195 ovn-nbctl lsp-add alice alice1 \
7196 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7197
7198 # Create logical port bob1 in bob
7199 ovn-nbctl lsp-add bob bob1 \
7200 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7201
7202 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7203 # packets for ARP resolution (native tunneling doesn't queue packets
7204 # for ARP resolution).
7205 OVN_POPULATE_ARP
7206
7207 # Allow some time for ovn-northd and ovn-controller to catch up.
7208 # XXX This should be more systematic.
7209 sleep 1
7210
7211 ip_to_hex() {
7212 printf "%02x%02x%02x%02x" "$@"
7213 }
7214 trim_zeros() {
7215 sed 's/\(00\)\{1,\}$//'
7216 }
7217
7218 # Send ip packets between foo1 and bar1
7219 # (East-west traffic should flow normally)
7220 src_mac="f00000010203"
7221 dst_mac="000001010203"
7222 src_ip=`ip_to_hex 192 168 1 2`
7223 dst_ip=`ip_to_hex 192 168 2 2`
7224 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7225 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7226
7227 # Send ip packets between foo1 and alice1
7228 src_mac="f00000010203"
7229 dst_mac="000001010203"
7230 src_ip=`ip_to_hex 192 168 1 2`
7231 dst_ip=`ip_to_hex 172 16 1 3`
7232 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7233 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7234 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
7235
7236 # Send ip packets between bar1 and bob1
7237 src_mac="f00000010204"
7238 dst_mac="000001010204"
7239 src_ip=`ip_to_hex 192 168 2 2`
7240 dst_ip=`ip_to_hex 172 16 1 4`
7241 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7242 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7243 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7244
7245 # Packet to expect at bar1
7246 src_mac="000001010204"
7247 dst_mac="f00000010204"
7248 src_ip=`ip_to_hex 192 168 1 2`
7249 dst_ip=`ip_to_hex 192 168 2 2`
7250 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7251 echo $expected > expected
7252 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7253
7254 # Packet to Expect at alice1
7255 src_mac="000002010203"
7256 dst_mac="f00000010205"
7257 src_ip=`ip_to_hex 192 168 1 2`
7258 dst_ip=`ip_to_hex 172 16 1 3`
7259 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7260 echo $expected > expected
7261 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7262
7263 # Packet to Expect at bob1
7264 src_mac="000003010203"
7265 dst_mac="f00000010206"
7266 src_ip=`ip_to_hex 192 168 2 2`
7267 dst_ip=`ip_to_hex 172 16 1 4`
7268 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7269 echo $expected > expected
7270 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
7271
7272 for sim in hv1 hv2 hv3; do
7273 as $sim
7274 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7275 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7276 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7277 done
7278
7279 as ovn-sb
7280 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7281
7282 as ovn-nb
7283 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7284
7285 as northd
7286 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7287
7288 as main
7289 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7290 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7291
7292 AT_CLEANUP
7293
7294 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
7295 AT_SKIP_IF([test $HAVE_PYTHON = no])
7296 ovn_start
7297
7298 ovn-nbctl ls-add ls1
7299
7300 ovn-nbctl lsp-add ls1 ls1-lp1 \
7301 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7302
7303 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7304
7305 ovn-nbctl lsp-add ls1 ls1-lp2 \
7306 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7307
7308 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7309
7310 DNS1=`ovn-nbctl create DNS records={}`
7311 DNS2=`ovn-nbctl create DNS records={}`
7312
7313 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7314 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
7315 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
7316
7317 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
7318
7319 net_add n1
7320 sim_add hv1
7321
7322 as hv1
7323 ovs-vsctl add-br br-phys
7324 ovn_attach n1 br-phys 192.168.0.1
7325 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7326 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
7327 options:tx_pcap=hv1/vif1-tx.pcap \
7328 options:rxq_pcap=hv1/vif1-rx.pcap \
7329 ofport-request=1
7330
7331 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7332 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
7333 options:tx_pcap=hv1/vif2-tx.pcap \
7334 options:rxq_pcap=hv1/vif2-rx.pcap \
7335 ofport-request=2
7336
7337 OVN_POPULATE_ARP
7338 sleep 2
7339 as hv1 ovs-vsctl show
7340
7341 echo "*************************"
7342 ovn-sbctl list DNS
7343 echo "*************************"
7344
7345 ip_to_hex() {
7346 printf "%02x%02x%02x%02x" "$@"
7347 }
7348
7349 reset_pcap_file() {
7350 local iface=$1
7351 local pcap_file=$2
7352 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7353 options:rxq_pcap=dummy-rx.pcap
7354 rm -f ${pcap_file}*.pcap
7355 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7356 options:rxq_pcap=${pcap_file}-rx.pcap
7357 }
7358
7359 # set_dns_params host_name
7360 # Sets the dns_req_data and dns_resp_data
7361 set_dns_params() {
7362 local hname=$1
7363 local ttl=00000e10
7364 an_count=0001
7365 type=0001
7366 case $hname in
7367 vm1)
7368 # vm1.ovn.org
7369 query_name=03766d31036f766e036f726700
7370 # IPv4 address - 10.0.0.4
7371 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7372 ;;
7373 vm2)
7374 # vm2.ovn.org
7375 query_name=03766d32036f766e036f726700
7376 # IPv4 address - 10.0.0.6
7377 expected_dns_answer=${query_name}00010001${ttl}00040a000006
7378 # IPv4 address - 20.0.0.4
7379 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
7380 an_count=0002
7381 ;;
7382 vm3)
7383 # vm3.ovn.org
7384 query_name=03766d33036f766e036f726700
7385 # IPv4 address - 40.0.0.4
7386 expected_dns_answer=${query_name}00010001${ttl}000428000004
7387 ;;
7388 vm1_ipv6_only)
7389 # vm1.ovn.org
7390 query_name=03766d31036f766e036f726700
7391 # IPv6 address - aef0::4
7392 type=001c
7393 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
7394 ;;
7395 vm1_ipv4_v6)
7396 # vm1.ovn.org
7397 query_name=03766d31036f766e036f726700
7398 type=00ff
7399 an_count=0002
7400 # IPv4 address - 10.0.0.4
7401 # IPv6 address - aef0::4
7402 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7403 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7404 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7405 ;;
7406 vm1_invalid_type)
7407 # vm1.ovn.org
7408 query_name=03766d31036f766e036f726700
7409 # IPv6 address - aef0::4
7410 type=0002
7411 ;;
7412 vm1_incomplete)
7413 # set type to none
7414 type=''
7415 esac
7416 # TTL - 3600
7417 local dns_req_header=010201200001000000000000
7418 local dns_resp_header=010281200001${an_count}00000000
7419 dns_req_data=${dns_req_header}${query_name}${type}0001
7420 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7421 }
7422
7423 # This shell function sends a DNS request packet
7424 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7425 test_dns() {
7426 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7427 local dns_query_data=$7
7428 shift; shift; shift; shift; shift; shift; shift;
7429 # Packet size => IPv4 header (20) + UDP header (8) +
7430 # DNS data (header + query)
7431 ip_len=`expr 28 + ${#dns_query_data} / 2`
7432 udp_len=`expr $ip_len - 20`
7433 ip_len=$(printf "%x" $ip_len)
7434 udp_len=$(printf "%x" $udp_len)
7435 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7436 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7437 # dns data
7438 request=${request}${dns_query_data}
7439
7440 if test $dns_reply != 0; then
7441 local dns_reply=$1
7442 ip_len=`expr 28 + ${#dns_reply} / 2`
7443 udp_len=`expr $ip_len - 20`
7444 ip_len=$(printf "%x" $ip_len)
7445 udp_len=$(printf "%x" $udp_len)
7446 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7447 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7448 echo $reply >> $inport.expected
7449 else
7450 for outport; do
7451 echo $request >> $outport.expected
7452 done
7453 fi
7454 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7455 }
7456
7457 test_dns6() {
7458 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7459 local dns_query_data=$7
7460 shift; shift; shift; shift; shift; shift; shift;
7461 # Packet size => UDP header (8) +
7462 # DNS data (header + query)
7463 ip_len=`expr 8 + ${#dns_query_data} / 2`
7464 udp_len=$ip_len
7465 ip_len=$(printf "%x" $ip_len)
7466 udp_len=$(printf "%x" $udp_len)
7467 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7468 request=${request}9234003500${udp_len}0000
7469 #dns data
7470 request=${request}${dns_query_data}
7471
7472 if test $dns_reply != 0; then
7473 local dns_reply=$1
7474 ip_len=`expr 8 + ${#dns_reply} / 2`
7475 udp_len=$ip_len
7476 ip_len=$(printf "%x" $ip_len)
7477 udp_len=$(printf "%x" $udp_len)
7478 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7479 reply=${reply}0035923400${udp_len}0000${dns_reply}
7480 echo $reply >> $inport.expected
7481 else
7482 for outport; do
7483 echo $request >> $outport.expected
7484 done
7485 fi
7486 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7487 }
7488
7489 AT_CAPTURE_FILE([ofctl_monitor0.log])
7490 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7491 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7492
7493 set_dns_params vm2
7494 src_ip=`ip_to_hex 10 0 0 4`
7495 dst_ip=`ip_to_hex 10 0 0 1`
7496 dns_reply=1
7497 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7498
7499 # NXT_RESUMEs should be 1.
7500 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7501
7502 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7503 cat 1.expected | cut -c -48 > expout
7504 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7505 # Skipping the IPv4 checksum.
7506 cat 1.expected | cut -c 53- > expout
7507 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7508
7509 reset_pcap_file hv1-vif1 hv1/vif1
7510 reset_pcap_file hv1-vif2 hv1/vif2
7511 rm -f 1.expected
7512 rm -f 2.expected
7513
7514 set_dns_params vm1
7515 src_ip=`ip_to_hex 10 0 0 6`
7516 dst_ip=`ip_to_hex 10 0 0 1`
7517 dns_reply=1
7518 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7519
7520 # NXT_RESUMEs should be 2.
7521 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7522
7523 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7524 cat 2.expected | cut -c -48 > expout
7525 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7526 # Skipping the IPv4 checksum.
7527 cat 2.expected | cut -c 53- > expout
7528 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7529
7530 reset_pcap_file hv1-vif1 hv1/vif1
7531 reset_pcap_file hv1-vif2 hv1/vif2
7532 rm -f 1.expected
7533 rm -f 2.expected
7534
7535 # Clear the query name options for ls1-lp2
7536 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7537
7538 set_dns_params vm2
7539 src_ip=`ip_to_hex 10 0 0 4`
7540 dst_ip=`ip_to_hex 10 0 0 1`
7541 dns_reply=0
7542 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7543
7544 # NXT_RESUMEs should be 3.
7545 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7546
7547 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7548 AT_CHECK([cat 1.packets], [0], [])
7549
7550 reset_pcap_file hv1-vif1 hv1/vif1
7551 reset_pcap_file hv1-vif2 hv1/vif2
7552 rm -f 1.expected
7553 rm -f 2.expected
7554
7555 # Clear the query name for ls1-lp1
7556 # Since ls1 has no query names configued,
7557 # ovn-northd should not add the DNS flows.
7558 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7559
7560 set_dns_params vm1
7561 src_ip=`ip_to_hex 10 0 0 6`
7562 dst_ip=`ip_to_hex 10 0 0 1`
7563 dns_reply=0
7564 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7565
7566 # NXT_RESUMEs should be 3 only.
7567 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7568
7569 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7570 AT_CHECK([cat 2.packets], [0], [])
7571
7572 reset_pcap_file hv1-vif1 hv1/vif1
7573 reset_pcap_file hv1-vif2 hv1/vif2
7574 rm -f 1.expected
7575 rm -f 2.expected
7576
7577 # Test IPv6 (AAAA records) using IPv4 packet.
7578 # Add back the DNS options for ls1-lp1.
7579 ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7580
7581 set_dns_params vm1_ipv6_only
7582 src_ip=`ip_to_hex 10 0 0 6`
7583 dst_ip=`ip_to_hex 10 0 0 1`
7584 dns_reply=1
7585 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7586
7587 # NXT_RESUMEs should be 4.
7588 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7589
7590 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7591 cat 2.expected | cut -c -48 > expout
7592 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7593 # Skipping the IPv4 checksum.
7594 cat 2.expected | cut -c 53- > expout
7595 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7596
7597 reset_pcap_file hv1-vif1 hv1/vif1
7598 reset_pcap_file hv1-vif2 hv1/vif2
7599 rm -f 1.expected
7600 rm -f 2.expected
7601
7602 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7603 set_dns_params vm1_ipv4_v6
7604 src_ip=`ip_to_hex 10 0 0 6`
7605 dst_ip=`ip_to_hex 10 0 0 1`
7606 dns_reply=1
7607 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7608
7609 # NXT_RESUMEs should be 5.
7610 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7611
7612 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7613 cat 2.expected | cut -c -48 > expout
7614 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7615 # Skipping the IPv4 checksum.
7616 cat 2.expected | cut -c 53- > expout
7617 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7618
7619 reset_pcap_file hv1-vif1 hv1/vif1
7620 reset_pcap_file hv1-vif2 hv1/vif2
7621 rm -f 1.expected
7622 rm -f 2.expected
7623
7624 # Invalid type.
7625 set_dns_params vm1_invalid_type
7626 src_ip=`ip_to_hex 10 0 0 6`
7627 dst_ip=`ip_to_hex 10 0 0 1`
7628 dns_reply=0
7629 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7630
7631 # NXT_RESUMEs should be 6.
7632 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7633
7634 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7635 AT_CHECK([cat 2.packets], [0], [])
7636
7637 reset_pcap_file hv1-vif1 hv1/vif1
7638 reset_pcap_file hv1-vif2 hv1/vif2
7639 rm -f 1.expected
7640 rm -f 2.expected
7641
7642 # Incomplete DNS packet.
7643 set_dns_params vm1_incomplete
7644 src_ip=`ip_to_hex 10 0 0 6`
7645 dst_ip=`ip_to_hex 10 0 0 1`
7646 dns_reply=0
7647 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7648
7649 # NXT_RESUMEs should be 7.
7650 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7651
7652 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7653 AT_CHECK([cat 2.packets], [0], [])
7654
7655 reset_pcap_file hv1-vif1 hv1/vif1
7656 reset_pcap_file hv1-vif2 hv1/vif2
7657 rm -f 1.expected
7658 rm -f 2.expected
7659
7660 # Add one more DNS record to the ls1.
7661 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7662
7663 set_dns_params vm3
7664 src_ip=`ip_to_hex 10 0 0 4`
7665 dst_ip=`ip_to_hex 10 0 0 1`
7666 dns_reply=1
7667 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7668
7669 # NXT_RESUMEs should be 8.
7670 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7671
7672 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7673 cat 1.expected | cut -c -48 > expout
7674 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7675 # Skipping the IPv4 checksum.
7676 cat 1.expected | cut -c 53- > expout
7677 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7678
7679 reset_pcap_file hv1-vif1 hv1/vif1
7680 reset_pcap_file hv1-vif2 hv1/vif2
7681 rm -f 1.expected
7682 rm -f 2.expected
7683
7684 # Try DNS query over IPv6
7685 set_dns_params vm1
7686 src_ip=aef00000000000000000000000000004
7687 dst_ip=aef00000000000000000000000000001
7688 dns_reply=1
7689 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7690
7691 # NXT_RESUMEs should be 9.
7692 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7693
7694 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7695 # Skipping the UDP checksum.
7696 cat 1.expected | cut -c 1-120,125- > expout
7697 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
7698
7699 reset_pcap_file hv1-vif1 hv1/vif1
7700 reset_pcap_file hv1-vif2 hv1/vif2
7701 rm -f 1.expected
7702 rm -f 2.expected
7703
7704 as hv1
7705 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7706 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7707 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7708
7709 as ovn-sb
7710 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7711
7712 as ovn-nb
7713 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7714
7715 as northd
7716 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7717
7718 as main
7719 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7720 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7721 AT_CLEANUP
7722
7723 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
7724 AT_SKIP_IF([test $HAVE_PYTHON = no])
7725 ovn_start
7726
7727 net_add n1
7728
7729 sim_add hv1
7730 as hv1
7731 ovs-vsctl add-br br-phys
7732 ovn_attach n1 br-phys 192.168.0.1
7733 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7734 set interface hv1-vif1 external-ids:iface-id=foo1 \
7735 options:tx_pcap=hv1/vif1-tx.pcap \
7736 options:rxq_pcap=hv1/vif1-rx.pcap \
7737 ofport-request=1
7738
7739 sim_add gw1
7740 as gw1
7741 ovs-vsctl add-br br-phys
7742 ovn_attach n1 br-phys 192.168.0.2
7743
7744 sim_add gw2
7745 as gw2
7746 ovs-vsctl add-br br-phys
7747 ovn_attach n1 br-phys 192.168.0.4
7748
7749 sim_add ext1
7750 as ext1
7751 ovs-vsctl add-br br-phys
7752 ovn_attach n1 br-phys 192.168.0.3
7753 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7754 set interface ext1-vif1 external-ids:iface-id=outside1 \
7755 options:tx_pcap=ext1/vif1-tx.pcap \
7756 options:rxq_pcap=ext1/vif1-rx.pcap \
7757 ofport-request=1
7758
7759 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7760 # packets for ARP resolution (native tunneling doesn't queue packets
7761 # for ARP resolution).
7762 OVN_POPULATE_ARP
7763
7764 ovn-nbctl create Logical_Router name=R1
7765
7766 ovn-nbctl ls-add foo
7767 ovn-nbctl ls-add alice
7768 ovn-nbctl ls-add outside
7769
7770 # Connect foo to R1
7771 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7772 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7773 type=router options:router-port=foo \
7774 -- lsp-set-addresses rp-foo router
7775
7776 # Connect alice to R1 as distributed router gateway port on gw1
7777 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7778
7779 ovn-nbctl \
7780 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7781 chassis_name=gw1 \
7782 priority=20 -- \
7783 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7784 chassis_name=gw2 \
7785 priority=10 -- \
7786 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7787
7788 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7789 type=router options:router-port=alice \
7790 -- lsp-set-addresses rp-alice router
7791
7792 # Create logical port foo1 in foo
7793 ovn-nbctl lsp-add foo foo1 \
7794 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7795
7796 # Create logical port outside1 in outside
7797 ovn-nbctl lsp-add outside outside1 \
7798 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7799
7800 # Create localnet port in alice
7801 ovn-nbctl lsp-add alice ln-alice
7802 ovn-nbctl lsp-set-addresses ln-alice unknown
7803 ovn-nbctl lsp-set-type ln-alice localnet
7804 ovn-nbctl lsp-set-options ln-alice network_name=phys
7805
7806 # Create localnet port in outside
7807 ovn-nbctl lsp-add outside ln-outside
7808 ovn-nbctl lsp-set-addresses ln-outside unknown
7809 ovn-nbctl lsp-set-type ln-outside localnet
7810 ovn-nbctl lsp-set-options ln-outside network_name=phys
7811
7812 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7813 # mapping to the external network, is the one generating packets
7814 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7815 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7816 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7817
7818 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7819
7820 # Allow some time for ovn-northd and ovn-controller to catch up.
7821 # XXX This should be more systematic.
7822 sleep 2
7823
7824 ip_to_hex() {
7825 printf "%02x%02x%02x%02x" "$@"
7826 }
7827
7828 reset_pcap_file() {
7829 local iface=$1
7830 local pcap_file=$2
7831 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7832 options:rxq_pcap=dummy-rx.pcap
7833 rm -f ${pcap_file}*.pcap
7834 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7835 options:rxq_pcap=${pcap_file}-rx.pcap
7836 }
7837
7838 test_ip_packet()
7839 {
7840 local active_gw=$1
7841 local backup_gw=$2
7842
7843 # Send ip packet between foo1 and outside1
7844 src_mac="f00000010203" # foo1 mac
7845 dst_mac="000001010203" # rp-foo mac (internal router leg)
7846 src_ip=`ip_to_hex 192 168 1 2`
7847 dst_ip=`ip_to_hex 172 16 1 3`
7848 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7849
7850 # ARP request packet to expect at outside1
7851 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7852
7853 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7854
7855 # Send ARP reply from outside1 back to the router
7856 # XXX: note, we could avoid this if we plug this port into a netns
7857 # and setup the IP address into the port, so the kernel would simply reply
7858 src_mac="000002010203"
7859 reply_mac="f00000010204"
7860 dst_ip=`ip_to_hex 172 16 1 3`
7861 src_ip=`ip_to_hex 172 16 1 1`
7862 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7863
7864 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7865
7866 OVS_WAIT_UNTIL([
7867 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7868 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7869 ])
7870
7871 # Packet to Expect at ext1 chassis, outside1 port
7872 src_mac="000002010203"
7873 dst_mac="f00000010204"
7874 src_ip=`ip_to_hex 192 168 1 2`
7875 dst_ip=`ip_to_hex 172 16 1 3`
7876 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7877 echo $expected > ext1-vif1.expected
7878
7879 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7880 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7881 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7882
7883 # Resend packet from foo1 to outside1
7884 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7885
7886 sleep 1
7887
7888 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7889 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7890 AT_CHECK([grep $expected packets | sort], [0], [expout])
7891 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7892 AT_CHECK([grep $expected packets | sort], [0], [])
7893 }
7894
7895 test_ip_packet gw1 gw2
7896
7897 ovn-nbctl --timeout=3 --wait=hv \
7898 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7899 chassis_name=gw1 \
7900 priority=10 -- \
7901 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7902 chassis_name=gw2 \
7903 priority=20 -- \
7904 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7905
7906 test_ip_packet gw2 gw1
7907
7908 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7909 AT_CLEANUP
7910
7911 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7912 AT_SKIP_IF([test $HAVE_PYTHON = no])
7913 ovn_start
7914
7915 net_add n1
7916
7917 sim_add hv1
7918 as hv1
7919 ovs-vsctl add-br br-phys
7920 ovn_attach n1 br-phys 192.168.0.1
7921 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7922 set interface hv1-vif1 external-ids:iface-id=foo1 \
7923 options:tx_pcap=hv1/vif1-tx.pcap \
7924 options:rxq_pcap=hv1/vif1-rx.pcap \
7925 ofport-request=1
7926
7927 sim_add gw1
7928 as gw1
7929 ovs-vsctl add-br br-phys
7930 ovn_attach n1 br-phys 192.168.0.2
7931
7932 sim_add gw2
7933 as gw2
7934 ovs-vsctl add-br br-phys
7935 ovn_attach n1 br-phys 192.168.0.4
7936
7937 sim_add ext1
7938 as ext1
7939 ovs-vsctl add-br br-phys
7940 ovn_attach n1 br-phys 192.168.0.3
7941 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7942 set interface ext1-vif1 external-ids:iface-id=outside1 \
7943 options:tx_pcap=ext1/vif1-tx.pcap \
7944 options:rxq_pcap=ext1/vif1-rx.pcap \
7945 ofport-request=1
7946
7947 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7948 # packets for ARP resolution (native tunneling doesn't queue packets
7949 # for ARP resolution).
7950 OVN_POPULATE_ARP
7951
7952 ovn-nbctl create Logical_Router name=R0
7953 ovn-nbctl create Logical_Router name=R1
7954
7955 ovn-nbctl ls-add foo
7956 ovn-nbctl ls-add join
7957 ovn-nbctl ls-add alice
7958 ovn-nbctl ls-add outside
7959
7960 #Connect foo to R0
7961 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7962 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7963 type=router options:router-port=R0-foo \
7964 -- lsp-set-addresses foo-R0 router
7965
7966 #Connect R0 to join
7967 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7968 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7969 type=router options:router-port=R0-join \
7970 -- lsp-set-addresses join-R0 router
7971
7972 #Connect join to R1
7973 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7974 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7975 type=router options:router-port=R1-join \
7976 -- lsp-set-addresses join-R1 router
7977
7978 #add route rules
7979 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7980 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7981
7982 # Connect alice to R1 as distributed router gateway port on gw1
7983 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7984
7985 ovn-nbctl \
7986 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7987 chassis_name=gw1 \
7988 priority=20 -- \
7989 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7990 chassis_name=gw2 \
7991 priority=10 -- \
7992 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7993
7994 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7995 type=router options:router-port=alice \
7996 -- lsp-set-addresses rp-alice router
7997
7998 # Create logical port foo1 in foo
7999 ovn-nbctl lsp-add foo foo1 \
8000 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8001
8002 # Create logical port outside1 in outside
8003 ovn-nbctl lsp-add outside outside1 \
8004 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8005
8006 # Create localnet port in alice
8007 ovn-nbctl lsp-add alice ln-alice
8008 ovn-nbctl lsp-set-addresses ln-alice unknown
8009 ovn-nbctl lsp-set-type ln-alice localnet
8010 ovn-nbctl lsp-set-options ln-alice network_name=phys
8011
8012 # Create localnet port in outside
8013 ovn-nbctl lsp-add outside ln-outside
8014 ovn-nbctl lsp-set-addresses ln-outside unknown
8015 ovn-nbctl lsp-set-type ln-outside localnet
8016 ovn-nbctl lsp-set-options ln-outside network_name=phys
8017
8018 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8019 # mapping to the external network, is the one generating packets
8020 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8021 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8022 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8023
8024 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8025
8026 # Allow some time for ovn-northd and ovn-controller to catch up.
8027 # XXX This should be more systematic.
8028 sleep 2
8029
8030 ip_to_hex() {
8031 printf "%02x%02x%02x%02x" "$@"
8032 }
8033
8034 reset_pcap_file() {
8035 local iface=$1
8036 local pcap_file=$2
8037 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8038 options:rxq_pcap=dummy-rx.pcap
8039 rm -f ${pcap_file}*.pcap
8040 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8041 options:rxq_pcap=${pcap_file}-rx.pcap
8042 }
8043
8044 test_ip_packet()
8045 {
8046 local active_gw=$1
8047 local backup_gw=$2
8048
8049 # Send ip packet between foo1 and outside1
8050 src_mac="f00000010203" # foo1 mac
8051 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8052 src_ip=`ip_to_hex 192 168 1 2`
8053 dst_ip=`ip_to_hex 172 16 1 3`
8054 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8055
8056 # ARP request packet to expect at outside1
8057 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8058
8059 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8060
8061 # Send ARP reply from outside1 back to the router
8062 # XXX: note, we could avoid this if we plug this port into a netns
8063 # and setup the IP address into the port, so the kernel would simply reply
8064 src_mac="000002010203"
8065 reply_mac="f00000010204"
8066 dst_ip=`ip_to_hex 172 16 1 3`
8067 src_ip=`ip_to_hex 172 16 1 1`
8068 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8069
8070 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8071
8072 OVS_WAIT_UNTIL([
8073 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8074 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8075 ])
8076
8077 # Packet to Expect at ext1 chassis, outside1 port
8078 src_mac="000002010203"
8079 dst_mac="f00000010204"
8080 src_ip=`ip_to_hex 192 168 1 2`
8081 dst_ip=`ip_to_hex 172 16 1 3`
8082 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8083 echo $expected > ext1-vif1.expected
8084
8085 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8086 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8087 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8088
8089 # Resend packet from foo1 to outside1
8090 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8091
8092 sleep 1
8093
8094 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8095 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8096 AT_CHECK([grep $expected packets | sort], [0], [expout])
8097 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8098 AT_CHECK([grep $expected packets | sort], [0], [])
8099 }
8100
8101 test_ip_packet gw1 gw2
8102
8103 ovn-nbctl --timeout=3 --wait=hv \
8104 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8105 chassis_name=gw1 \
8106 priority=10 -- \
8107 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8108 chassis_name=gw2 \
8109 priority=20 -- \
8110 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8111
8112 test_ip_packet gw2 gw1
8113
8114 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8115 AT_CLEANUP
8116
8117 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8118 AT_SKIP_IF([test $HAVE_PYTHON = no])
8119 ovn_start
8120
8121 # Logical network:
8122 # One LR R1 that has switches foo (192.168.1.0/24) and
8123 # alice (172.16.1.0/24) connected to it. The logical port
8124 # between R1 and alice has a "redirect-chassis" specified,
8125 # i.e. it is the distributed router gateway port.
8126 # Switch alice also has a localnet port defined.
8127 # An additional switch outside has a localnet port and the
8128 # same subnet as alice (172.16.1.0/24).
8129
8130 # Physical network:
8131 # Three hypervisors hv[123].
8132 # hv1 hosts vif foo1.
8133 # hv2 is the "redirect-chassis" that hosts the distributed
8134 # router gateway port.
8135 # hv3 hosts vif outside1.
8136 # In order to show that connectivity works only through hv2,
8137 # an initial round of tests is run without any bridge-mapping
8138 # defined for the localnet on hv2. These tests are expected
8139 # to fail.
8140 # Subsequent tests are run after defining the bridge-mapping
8141 # for the localnet on hv2. These tests are expected to succeed.
8142
8143 # Create three hypervisors and create OVS ports corresponding
8144 # to logical ports.
8145 net_add n1
8146
8147 sim_add hv1
8148 as hv1
8149 ovs-vsctl add-br br-phys
8150 ovn_attach n1 br-phys 192.168.0.1
8151 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8152 set interface hv1-vif1 external-ids:iface-id=foo1 \
8153 options:tx_pcap=hv1/vif1-tx.pcap \
8154 options:rxq_pcap=hv1/vif1-rx.pcap \
8155 ofport-request=1
8156
8157 sim_add hv2
8158 as hv2
8159 ovs-vsctl add-br br-phys
8160 ovn_attach n1 br-phys 192.168.0.2
8161
8162 sim_add hv3
8163 as hv3
8164 ovs-vsctl add-br br-phys
8165 ovn_attach n1 br-phys 192.168.0.3
8166 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8167 set interface hv3-vif1 external-ids:iface-id=outside1 \
8168 options:tx_pcap=hv3/vif1-tx.pcap \
8169 options:rxq_pcap=hv3/vif1-rx.pcap \
8170 ofport-request=1
8171
8172 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8173 # packets for ARP resolution (native tunneling doesn't queue packets
8174 # for ARP resolution).
8175 OVN_POPULATE_ARP
8176
8177 ovn-nbctl create Logical_Router name=R1
8178
8179 ovn-nbctl ls-add foo
8180 ovn-nbctl ls-add alice
8181 ovn-nbctl ls-add outside
8182
8183 # Connect foo to R1
8184 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8185 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8186 type=router options:router-port=foo \
8187 -- lsp-set-addresses rp-foo router
8188
8189 # Connect alice to R1 as distributed router gateway port on hv2
8190 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8191 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8192 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8193 type=router options:router-port=alice \
8194 -- lsp-set-addresses rp-alice router
8195
8196 # Create logical port foo1 in foo
8197 ovn-nbctl lsp-add foo foo1 \
8198 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8199
8200 # Create logical port outside1 in outside
8201 ovn-nbctl lsp-add outside outside1 \
8202 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8203
8204 # Create localnet port in alice
8205 ovn-nbctl lsp-add alice ln-alice
8206 ovn-nbctl lsp-set-addresses ln-alice unknown
8207 ovn-nbctl lsp-set-type ln-alice localnet
8208 ovn-nbctl lsp-set-options ln-alice network_name=phys
8209
8210 # Create localnet port in outside
8211 ovn-nbctl lsp-add outside ln-outside
8212 ovn-nbctl lsp-set-addresses ln-outside unknown
8213 ovn-nbctl lsp-set-type ln-outside localnet
8214 ovn-nbctl lsp-set-options ln-outside network_name=phys
8215
8216 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8217 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8218 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8219
8220
8221 # Allow some time for ovn-northd and ovn-controller to catch up.
8222 # XXX This should be more systematic.
8223 sleep 2
8224
8225 echo "---------NB dump-----"
8226 ovn-nbctl show
8227 echo "---------------------"
8228 ovn-nbctl list logical_router
8229 echo "---------------------"
8230 ovn-nbctl list logical_router_port
8231 echo "---------------------"
8232
8233 echo "---------SB dump-----"
8234 ovn-sbctl list datapath_binding
8235 echo "---------------------"
8236 ovn-sbctl list port_binding
8237 echo "---------------------"
8238 ovn-sbctl dump-flows
8239 echo "---------------------"
8240 ovn-sbctl list chassis
8241 ovn-sbctl list encap
8242 echo "------ Gateway_Chassis dump (SBDB) -------"
8243 ovn-sbctl list Gateway_Chassis
8244 echo "------ Port_Binding chassisredirect -------"
8245 ovn-sbctl find Port_Binding type=chassisredirect
8246 echo "-------------------------------------------"
8247
8248 echo "------ hv1 dump ----------"
8249 as hv1 ovs-ofctl show br-int
8250 as hv1 ovs-ofctl dump-flows br-int
8251 echo "------ hv2 dump ----------"
8252 as hv2 ovs-ofctl show br-int
8253 as hv2 ovs-ofctl dump-flows br-int
8254 echo "------ hv3 dump ----------"
8255 as hv3 ovs-ofctl show br-int
8256 as hv3 ovs-ofctl dump-flows br-int
8257 echo "--------------------------"
8258
8259
8260 # Check that redirect mapping is programmed only on hv2
8261 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8262 ])
8263 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
8264 ])
8265 # Check that hv1 sends chassisredirect port traffic to hv2
8266 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
8267 ])
8268 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8269 ])
8270 # Check that arp reply on distributed gateway port is only programmed on hv2
8271 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
8272 ])
8273 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
8274 ])
8275
8276
8277 ip_to_hex() {
8278 printf "%02x%02x%02x%02x" "$@"
8279 }
8280
8281
8282 : > hv2-vif1.expected
8283 : > hv3-vif1.expected
8284
8285 # test_arp INPORT SHA SPA TPA [REPLY_HA]
8286 #
8287 # Causes a packet to be received on INPORT. The packet is an ARP
8288 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
8289 # it should be the hardware address of the target to expect to receive in an
8290 # ARP reply; otherwise no reply is expected.
8291 #
8292 # INPORT is an logical switch port number, e.g. 11 for vif11.
8293 # SHA and REPLY_HA are each 12 hex digits.
8294 # SPA and TPA are each 8 hex digits.
8295 test_arp() {
8296 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
8297 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
8298 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
8299
8300 if test X$reply_ha != X; then
8301 # Expect to receive the reply, if any.
8302 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
8303 echo $reply >> hv${hv}-vif$inport.expected
8304 fi
8305 }
8306
8307 rtr_ip=$(ip_to_hex 172 16 1 1)
8308 foo_ip=$(ip_to_hex 192 168 1 2)
8309 outside_ip=$(ip_to_hex 172 16 1 3)
8310
8311 echo $rtr_ip
8312 echo $foo_ip
8313 echo $outside_ip
8314
8315 # ARP for router IP address from outside1, no response expected
8316 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
8317
8318 # Now check the packets actually received against the ones expected.
8319 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8320
8321 # Send ip packet between foo1 and outside1
8322 src_mac="f00000010203"
8323 dst_mac="000001010203"
8324 src_ip=`ip_to_hex 192 168 1 2`
8325 dst_ip=`ip_to_hex 172 16 1 3`
8326 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8327
8328 # Now check the packets actually received against the ones expected.
8329 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8330
8331 # Now add bridge-mappings on hv2, which should make everything work
8332 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8333
8334 # Allow some time for ovn-northd and ovn-controller to catch up.
8335 # XXX This should be more systematic.
8336 sleep 2
8337
8338 # ARP for router IP address from outside1
8339 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
8340
8341 # Now check the packets actually received against the ones expected.
8342 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8343
8344 # Send ip packet between foo1 and outside1
8345 src_mac="f00000010203"
8346 dst_mac="000001010203"
8347 src_ip=`ip_to_hex 192 168 1 2`
8348 dst_ip=`ip_to_hex 172 16 1 3`
8349 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8350
8351 # Packet to Expect at outside1
8352 src_mac="000002010203"
8353 dst_mac="f00000010204"
8354 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8355
8356 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8357
8358 echo "------ hv1 dump ----------"
8359 as hv1 ovs-ofctl show br-int
8360 as hv1 ovs-ofctl dump-flows br-int
8361 echo "------ hv2 dump ----------"
8362 as hv2 ovs-ofctl show br-int
8363 as hv2 ovs-ofctl dump-flows br-int
8364 echo "------ hv3 dump ----------"
8365 as hv3 ovs-ofctl show br-int
8366 as hv3 ovs-ofctl dump-flows br-int
8367 echo "----------------------------"
8368
8369 echo $expected >> hv3-vif1.expected
8370 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8371
8372 #Check ovn-trace over "chassisredirect" port
8373 AT_CAPTURE_FILE([trace])
8374 ovn_trace () {
8375 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
8376 }
8377
8378 echo 'ip.ttl--;' > expout
8379 echo 'eth.src = 00:00:02:01:02:03;' >> expout
8380 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8381 echo 'output("ln-alice");' >> expout
8382 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])
8383
8384 # Create logical port alice1 in alice on hv1
8385 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8386 set interface hv1-vif2 external-ids:iface-id=alice1 \
8387 options:tx_pcap=hv1/vif2-tx.pcap \
8388 options:rxq_pcap=hv1/vif2-rx.pcap \
8389 ofport-request=1
8390
8391 ovn-nbctl lsp-add alice alice1 \
8392 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8393
8394 # Create logical port foo2 in foo on hv2
8395 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8396 set interface hv2-vif1 external-ids:iface-id=foo2 \
8397 options:tx_pcap=hv2/vif1-tx.pcap \
8398 options:rxq_pcap=hv2/vif1-rx.pcap \
8399 ofport-request=1
8400
8401 ovn-nbctl lsp-add foo foo2 \
8402 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8403
8404 # Allow some time for ovn-northd and ovn-controller to catch up.
8405 # XXX This should be more systematic.
8406 sleep 1
8407
8408 : > hv1-vif2.expected
8409
8410 # Send ip packet between alice1 and foo2
8411 src_mac="f00000010205"
8412 dst_mac="000002010203"
8413 src_ip=`ip_to_hex 172 16 1 4`
8414 dst_ip=`ip_to_hex 192 168 1 3`
8415 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8416
8417 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8418
8419 # Packet to Expect at foo2
8420 src_mac="000001010203"
8421 dst_mac="f00000010206"
8422 src_ip=`ip_to_hex 172 16 1 4`
8423 dst_ip=`ip_to_hex 192 168 1 3`
8424 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8425
8426 echo $expected >> hv2-vif1.expected
8427 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
8428
8429 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
8430 ])
8431
8432 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
8433
8434 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
8435 ])
8436
8437 OVN_CLEANUP([hv1],[hv2],[hv3])
8438
8439 AT_CLEANUP
8440
8441 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8442 AT_SKIP_IF([test $HAVE_PYTHON = no])
8443 ovn_start
8444 # Create logical switches
8445 ovn-nbctl ls-add ls0
8446 ovn-nbctl ls-add ls1
8447 # Create distributed router
8448 ovn-nbctl create Logical_Router name=lr0
8449 # Add distributed gateway port to distributed router
8450 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8451 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8452 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8453 type=router options:router-port=lrp0 addresses="router"
8454 # Add router port to ls1
8455 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8456 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8457 type=router options:router-port=lrp1 addresses="router"
8458 # Add logical ports for NAT rules
8459 ovn-nbctl lsp-add ls1 foo1 \
8460 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8461 ovn-nbctl lsp-add ls1 foo2 \
8462 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
8463 # Add nat-addresses option
8464 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8465 # Add NAT rules
8466 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8467 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8468 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])
8469 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])
8470
8471 net_add n1
8472 sim_add hv1
8473 as hv1
8474 ovs-vsctl add-br br-phys
8475 ovn_attach n1 br-phys 192.168.0.1
8476
8477 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8478 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])
8479
8480 sim_add hv2
8481 as hv2
8482 ovs-vsctl add-br br-phys
8483 ovn_attach n1 br-phys 192.168.0.2
8484 # Initially test with no bridge-mapping on hv2, expect to receive no packets
8485
8486 sim_add hv3
8487 as hv3
8488 ovs-vsctl add-br br-phys
8489 ovn_attach n1 br-phys 192.168.0.3
8490 # Initially test with no bridge-mapping on hv3
8491
8492 # Create a localnet port.
8493 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8494 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8495 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8496 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8497
8498 # Allow some time for ovn-northd and ovn-controller to catch up.
8499 # XXX This should be more systematic.
8500 sleep 2
8501
8502 # Expect no packets when hv2 bridge-mapping is not present
8503 : > packets
8504 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8505
8506 # Add bridge-mapping on hv2
8507 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8508
8509 # Wait for packets to be received.
8510 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8511 trim_zeros() {
8512 sed 's/\(00\)\{1,\}$//'
8513 }
8514 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8515 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8516 echo $expected > expout
8517 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8518 echo $expected >> expout
8519 AT_CHECK([sort packets], [0], [expout])
8520 sort packets | cat
8521
8522 # Temporarily remove nat-addresses option to avoid race conditions
8523 # due to GARP backoff
8524 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8525
8526 reset_pcap_file() {
8527 local iface=$1
8528 local pcap_file=$2
8529 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8530 options:rxq_pcap=dummy-rx.pcap
8531 rm -f ${pcap_file}*.pcap
8532 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8533 options:rxq_pcap=${pcap_file}-rx.pcap
8534 }
8535
8536 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8537
8538 # Add OVS ports for foo1 and foo2 on hv3
8539 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8540 set interface hv3-vif1 external-ids:iface-id=foo1 \
8541 ofport-request=1
8542 ovs-vsctl -- add-port br-int hv3-vif2 -- \
8543 set interface hv3-vif2 external-ids:iface-id=foo2 \
8544 ofport-request=2
8545
8546 # Add bridge-mapping on hv3
8547 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8548
8549 # Re-add nat-addresses option
8550 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8551
8552 # Wait for packets to be received.
8553 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8554 trim_zeros() {
8555 sed 's/\(00\)\{1,\}$//'
8556 }
8557
8558 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8559 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8560 echo $expected >> expout
8561 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8562 echo $expected >> expout
8563 AT_CHECK([sort packets], [0], [expout])
8564 sort packets | cat
8565
8566 OVN_CLEANUP([hv1],[hv2],[hv3])
8567
8568 AT_CLEANUP
8569
8570 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8571 AT_KEYWORDS([ovn-nd_ra])
8572 AT_SKIP_IF([test $HAVE_PYTHON = no])
8573 ovn_start
8574
8575 # In this test case we create 1 lswitch with 3 VIF ports attached,
8576 # and a lrouter connected to the lswitch.
8577 # We generate the Router solicitation packet and verify the Router Advertisement
8578 # reply packet from the ovn-controller.
8579
8580 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8581 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8582 # 'slaac' to allow lrp0 send RA for SLAAC mode.
8583 ovn-nbctl ls-add lsw0
8584 ovn-nbctl lr-add lr0
8585 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8586 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8587 ovn-nbctl \
8588 -- lsp-add lsw0 lsp0 \
8589 -- set Logical_Switch_Port lsp0 type=router \
8590 options:router-port=lrp0 \
8591 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8592 net_add n1
8593 sim_add hv1
8594 as hv1
8595 ovs-vsctl add-br br-phys
8596 ovn_attach n1 br-phys 192.168.0.2
8597
8598 ovn-nbctl lsp-add lsw0 lp1
8599 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8600 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"
8601
8602 ovn-nbctl lsp-add lsw0 lp2
8603 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8604 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"
8605
8606 ovn-nbctl lsp-add lsw0 lp3
8607 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8608 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"
8609
8610 # Add ACL rule for ICMPv6 on lsw0
8611 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8612 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8613 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8614 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8615
8616 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8617 set interface hv1-vif1 external-ids:iface-id=lp1 \
8618 options:tx_pcap=hv1/vif1-tx.pcap \
8619 options:rxq_pcap=hv1/vif1-rx.pcap \
8620 ofport-request=1
8621
8622 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8623 set interface hv1-vif2 external-ids:iface-id=lp2 \
8624 options:tx_pcap=hv1/vif2-tx.pcap \
8625 options:rxq_pcap=hv1/vif2-rx.pcap \
8626 ofport-request=2
8627
8628 ovs-vsctl -- add-port br-int hv1-vif3 -- \
8629 set interface hv1-vif3 external-ids:iface-id=lp3 \
8630 options:tx_pcap=hv1/vif3-tx.pcap \
8631 options:rxq_pcap=hv1/vif3-rx.pcap \
8632 ofport-request=3
8633
8634 # Allow some time for ovn-northd and ovn-controller to catch up.
8635 # XXX This should be more systematic.
8636 sleep 1
8637
8638 reset_pcap_file() {
8639 local iface=$1
8640 local pcap_file=$2
8641 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8642 options:rxq_pcap=dummy-rx.pcap
8643 rm -f ${pcap_file}*.pcap
8644 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8645 options:rxq_pcap=${pcap_file}-rx.pcap
8646 }
8647
8648 # Make sure that ovn-controller has installed the corresponding OF Flow.
8649 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"`])
8650
8651 # This shell function sends a Router Solicitation packet.
8652 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8653 test_ipv6_ra() {
8654 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8655 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8656
8657 local len=24
8658 local mtu_opt=""
8659 if test $mtu != 0; then
8660 len=`expr $len + 8`
8661 mtu_opt=05010000${mtu}
8662 fi
8663
8664 if test ${#prefix_opt} != 0; then
8665 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8666 len=`expr $len + ${#prefix_opt} / 2`
8667 fi
8668
8669 len=$(printf "%x" $len)
8670 local lrp_mac=fa163e000001
8671 local lrp_lla=fe80000000000000f8163efffe000001
8672 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8673 echo $reply >> $inport.expected
8674
8675 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8676 }
8677
8678 AT_CAPTURE_FILE([ofctl_monitor0.log])
8679 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8680 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8681
8682 # MTU is not set and the address mode is set to slaac
8683 addr_mode=00
8684 default_prefix_option_config=030440c0ffffffffffffffff00000000
8685 src_mac=fa163e000002
8686 src_lla=fe80000000000000f8163efffe000002
8687 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8688
8689 # NXT_RESUME should be 1.
8690 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8691
8692 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8693
8694 cat 1.expected | cut -c -112 > expout
8695 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8696
8697 # Skipping the ICMPv6 checksum.
8698 cat 1.expected | cut -c 117- > expout
8699 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8700
8701 rm -f *.expected
8702 reset_pcap_file hv1-vif1 hv1/vif1
8703 reset_pcap_file hv1-vif2 hv1/vif2
8704 reset_pcap_file hv1-vif3 hv1/vif3
8705
8706 # Set the MTU to 1500
8707 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8708
8709 # Make sure that ovn-controller has installed the corresponding OF Flow.
8710 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"`])
8711
8712 addr_mode=00
8713 default_prefix_option_config=030440c0ffffffffffffffff00000000
8714 src_mac=fa163e000003
8715 src_lla=fe80000000000000f8163efffe000003
8716 mtu=000005dc
8717
8718 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8719
8720 # NXT_RESUME should be 2.
8721 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8722
8723 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8724
8725 cat 2.expected | cut -c -112 > expout
8726 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8727
8728 # Skipping the ICMPv6 checksum.
8729 cat 2.expected | cut -c 117- > expout
8730 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8731
8732 rm -f *.expected
8733 reset_pcap_file hv1-vif1 hv1/vif1
8734 reset_pcap_file hv1-vif2 hv1/vif2
8735 reset_pcap_file hv1-vif3 hv1/vif3
8736
8737 # Set the address mode to dhcpv6_stateful
8738 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8739 # Make sure that ovn-controller has installed the corresponding OF Flow.
8740 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"`])
8741
8742 addr_mode=80
8743 default_prefix_option_config=""
8744 src_mac=fa163e000004
8745 src_lla=fe80000000000000f8163efffe000004
8746 mtu=000005dc
8747
8748 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8749
8750 # NXT_RESUME should be 3.
8751 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8752
8753 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8754
8755 cat 3.expected | cut -c -112 > expout
8756 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8757
8758 # Skipping the ICMPv6 checksum.
8759 cat 3.expected | cut -c 117- > expout
8760 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8761
8762 rm -f *.expected
8763 reset_pcap_file hv1-vif1 hv1/vif1
8764 reset_pcap_file hv1-vif2 hv1/vif2
8765 reset_pcap_file hv1-vif3 hv1/vif3
8766
8767 # Set the address mode to dhcpv6_stateless
8768 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8769 # Make sure that ovn-controller has installed the corresponding OF Flow.
8770 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"`])
8771
8772 addr_mode=40
8773 default_prefix_option_config=030440c0ffffffffffffffff00000000
8774 src_mac=fa163e000002
8775 src_lla=fe80000000000000f8163efffe000002
8776 mtu=000005dc
8777
8778 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8779
8780 # NXT_RESUME should be 4.
8781 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8782
8783 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8784
8785 cat 1.expected | cut -c -112 > expout
8786 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8787
8788 # Skipping the ICMPv6 checksum.
8789 cat 1.expected | cut -c 117- > expout
8790 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8791
8792 rm -f *.expected
8793 reset_pcap_file hv1-vif1 hv1/vif1
8794 reset_pcap_file hv1-vif2 hv1/vif2
8795 reset_pcap_file hv1-vif3 hv1/vif3
8796
8797 # Set the address mode to invalid.
8798 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8799 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8800 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"`])
8801
8802 addr_mode=40
8803 default_prefix_option_config=""
8804 src_mac=fa163e000002
8805 src_lla=fe80000000000000f8163efffe000002
8806 mtu=000005dc
8807
8808 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8809
8810 # NXT_RESUME should be 4 only.
8811 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8812
8813 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8814 AT_CHECK([cat 1.packets], [0], [])
8815
8816 OVN_CLEANUP([hv1])
8817 AT_CLEANUP
8818
8819 AT_SETUP([ovn -- /32 router IP address])
8820 AT_SKIP_IF([test $HAVE_PYTHON = no])
8821 ovn_start
8822
8823 # Logical network:
8824 # 2 LS 'foo' and 'alice' connected via router R1.
8825 # R1 connects to 'alice' with a /32 IP address. We use static routes and
8826 # nexthop to push traffic to a logical port in switch 'alice'
8827
8828 ovn-nbctl lr-add R1
8829
8830 ovn-nbctl ls-add foo
8831 ovn-nbctl ls-add alice
8832
8833 # Connect foo to R1
8834 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8835 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8836 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8837
8838 # Connect alice to R1.
8839 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8840 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8841 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8842
8843 # Create logical port foo1 in foo
8844 ovn-nbctl lsp-add foo foo1 \
8845 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8846
8847 # Create logical port alice1 in alice
8848 ovn-nbctl lsp-add alice alice1 \
8849 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8850
8851 #install default route in R1 to use alice1's IP address as nexthop
8852 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8853
8854 # Create two hypervisor and create OVS ports corresponding to logical ports.
8855 net_add n1
8856
8857 sim_add hv1
8858 as hv1
8859 ovs-vsctl add-br br-phys
8860 ovn_attach n1 br-phys 192.168.0.1
8861 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8862 set interface hv1-vif1 external-ids:iface-id=foo1 \
8863 options:tx_pcap=hv1/vif1-tx.pcap \
8864 options:rxq_pcap=hv1/vif1-rx.pcap \
8865 ofport-request=1
8866
8867 sim_add hv2
8868 as hv2
8869 ovs-vsctl add-br br-phys
8870 ovn_attach n1 br-phys 192.168.0.2
8871 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8872 set interface hv2-vif1 external-ids:iface-id=alice1 \
8873 options:tx_pcap=hv2/vif1-tx.pcap \
8874 options:rxq_pcap=hv2/vif1-rx.pcap \
8875 ofport-request=1
8876
8877
8878 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8879 # packets for ARP resolution (native tunneling doesn't queue packets
8880 # for ARP resolution).
8881 OVN_POPULATE_ARP
8882
8883 # Allow some time for ovn-northd and ovn-controller to catch up.
8884 # XXX This should be more systematic.
8885 sleep 1
8886
8887 ip_to_hex() {
8888 printf "%02x%02x%02x%02x" "$@"
8889 }
8890
8891 # Send ip packets between foo1 and alice1
8892 src_mac="f00000010203"
8893 dst_mac="000000010203"
8894 src_ip=`ip_to_hex 192 168 1 2`
8895 dst_ip=`ip_to_hex 10 0 0 2`
8896 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8897
8898 # Send the first packet to trigger a ARP response and population of
8899 # mac_bindings table.
8900 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8901 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8902 ovn-nbctl --wait=hv sync
8903
8904 # Packet to Expect at 'alice1'
8905 src_mac="000000010204"
8906 dst_mac="f00000010204"
8907 src_ip=`ip_to_hex 192 168 1 2`
8908 dst_ip=`ip_to_hex 10 0 0 2`
8909 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8910
8911 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8912
8913 OVN_CLEANUP([hv1],[hv2])
8914
8915 AT_CLEANUP
8916
8917 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8918 AT_SKIP_IF([test $HAVE_PYTHON = no])
8919 ovn_start
8920
8921 ovn-nbctl ls-add ls1
8922
8923 # Add localport to the switch
8924 ovn-nbctl lsp-add ls1 lp01
8925 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8926 ovn-nbctl lsp-set-type lp01 localport
8927
8928 net_add n1
8929
8930 for i in 1 2; do
8931 sim_add hv$i
8932 as hv$i
8933 ovs-vsctl add-br br-phys
8934 ovn_attach n1 br-phys 192.168.0.$i
8935 ovs-vsctl add-port br-int vif01 -- \
8936 set Interface vif01 external-ids:iface-id=lp01 \
8937 options:tx_pcap=hv${i}/vif01-tx.pcap \
8938 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8939 ofport-request=${i}0
8940
8941 ovs-vsctl add-port br-int vif${i}1 -- \
8942 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8943 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8944 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8945 ofport-request=${i}1
8946
8947 ovn-nbctl lsp-add ls1 lp${i}1
8948 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8949 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8950
8951 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8952 done
8953
8954 ovn-nbctl --wait=sb sync
8955 ovn-sbctl dump-flows
8956
8957 OVN_POPULATE_ARP
8958
8959 # Given the name of a logical port, prints the name of the hypervisor
8960 # on which it is located.
8961 vif_to_hv() {
8962 echo hv${1%?}
8963 }
8964 #
8965 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8966 #
8967 # This shell function causes a packet to be received on INPORT. The packet's
8968 # content has Ethernet destination DST and source SRC (each exactly 12 hex
8969 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8970 # logical switch port numbers, e.g. 11 for vif11.
8971 #
8972 # EOUT is the end-to-end output port, that is, where the packet will end up
8973 # after possibly bouncing through one or more localnet ports. LOUT is the
8974 # logical output port, which might be a localnet port, as seen by ovn-trace
8975 # (which doesn't know what localnet ports are connected to and therefore can't
8976 # figure out the end-to-end answer).
8977 #
8978 # DEFHV is the default hypervisor from where the packet is going to be sent
8979 # if the source port is a localport.
8980 for i in 1 2; do
8981 for j in 0 1; do
8982 : > $i$j.expected
8983 done
8984 done
8985 test_packet() {
8986 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8987 echo "$@"
8988
8989 # First try tracing the packet.
8990 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8991 if test $lout != drop; then
8992 echo "output(\"$lout\");"
8993 fi > expout
8994 AT_CAPTURE_FILE([trace])
8995 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8996
8997 # Then actually send a packet, for an end-to-end test.
8998 local packet=$(echo $dst$src | sed 's/://g')${eth}
8999 hv=`vif_to_hv $inport`
9000 # If hypervisor 0 (localport) use the defhv parameter
9001 if test $hv = hv0; then
9002 hv=$defhv
9003 fi
9004 vif=vif$inport
9005 as $hv ovs-appctl netdev-dummy/receive $vif $packet
9006 if test $eout != drop; then
9007 echo $packet >> ${eout#lp}.expected
9008 fi
9009 }
9010
9011
9012 # lp11 and lp21 are on different hypervisors
9013 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
9014 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
9015
9016 # Both VIFs should be able to reach the localport on their own HV
9017 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
9018 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
9019
9020 # Packet sent from localport on same hv should reach the vif
9021 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
9022 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
9023
9024 # Packet sent from localport on different hv should be dropped
9025 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
9026 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
9027
9028 # Now check the packets actually received against the ones expected.
9029 for i in 1 2; do
9030 for j in 0 1; do
9031 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
9032 done
9033 done
9034
9035 OVN_CLEANUP([hv1],[hv2])
9036
9037 AT_CLEANUP
9038
9039 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
9040 AT_SKIP_IF([test $HAVE_PYTHON = no])
9041 ovn_start
9042
9043 net_add n1
9044
9045 # create gateways with external network connectivity
9046
9047 for i in 1 2; do
9048 sim_add gw$i
9049 as gw$i
9050 ovs-vsctl add-br br-phys
9051 ovn_attach n1 br-phys 192.168.0.$i
9052 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9053 done
9054
9055 ovn-nbctl ls-add inside
9056 ovn-nbctl ls-add outside
9057
9058 # create hypervisors with a vif port each to an internal network
9059
9060 for i in 1 2; do
9061 sim_add hv$i
9062 as hv$i
9063 ovs-vsctl add-br br-phys
9064 ovn_attach n1 br-phys 192.168.0.1$i
9065 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9066 set interface hv$i-vif1 external-ids:iface-id=inside$i \
9067 options:tx_pcap=hv$i/vif1-tx.pcap \
9068 options:rxq_pcap=hv$i/vif1-rx.pcap \
9069 ofport-request=1
9070
9071 ovn-nbctl lsp-add inside inside$i \
9072 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
9073
9074 done
9075
9076 OVN_POPULATE_ARP
9077
9078 ovn-nbctl create Logical_Router name=R1
9079
9080 # Connect inside to R1
9081 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9082 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9083 type=router options:router-port=inside \
9084 -- lsp-set-addresses rp-inside router
9085
9086 # Connect outside to R1 as distributed router gateway port on gw1+gw2
9087 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9088
9089 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9090 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9091 --id=@gc1 create Gateway_Chassis \
9092 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9093 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9094
9095 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9096 type=router options:router-port=outside \
9097 -- lsp-set-addresses rp-outside router
9098
9099 # Create localnet port in outside
9100 ovn-nbctl lsp-add outside ln-outside
9101 ovn-nbctl lsp-set-addresses ln-outside unknown
9102 ovn-nbctl lsp-set-type ln-outside localnet
9103 ovn-nbctl lsp-set-options ln-outside network_name=phys
9104
9105 # Allow some time for ovn-northd and ovn-controller to catch up.
9106 # XXX This should be more systematic.
9107 ovn-nbctl --wait=hv --timeout=3 sync
9108
9109 echo "---------NB dump-----"
9110 ovn-nbctl show
9111 echo "---------------------"
9112 ovn-nbctl list logical_router
9113 echo "---------------------"
9114 ovn-nbctl list logical_router_port
9115 echo "---------------------"
9116
9117 echo "---------SB dump-----"
9118 ovn-sbctl list datapath_binding
9119 echo "---------------------"
9120 ovn-sbctl list port_binding
9121 echo "---------------------"
9122 ovn-sbctl dump-flows
9123 echo "---------------------"
9124 ovn-sbctl list chassis
9125 ovn-sbctl list encap
9126 echo "---------------------"
9127 echo "------ Gateway_Chassis dump (SBDB) -------"
9128 ovn-sbctl list Gateway_Chassis
9129 echo "------ Port_Binding chassisredirect -------"
9130 ovn-sbctl find Port_Binding type=chassisredirect
9131 echo "-------------------------------------------"
9132
9133 for chassis in gw1 gw2 hv1 hv2; do
9134 as $chassis
9135 echo "------ $chassis dump ----------"
9136 ovs-ofctl show br-int
9137 ovs-ofctl dump-flows br-int
9138 echo "--------------------------"
9139 done
9140 function bfd_dump() {
9141 for chassis in gw1 gw2 hv1 hv2; do
9142 as $chassis
9143 echo "------ $chassis dump (BFD)----"
9144 echo "BFD (from $chassis):"
9145 # dump BFD config and status to the other chassis
9146 for chassis2 in gw1 gw2 hv1 hv2; do
9147 if [[ "$chassis" != "$chassis2" ]]; then
9148 echo " -> $chassis2:"
9149 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
9150 fi
9151 done
9152 echo "--------------------------"
9153 done
9154 }
9155
9156 bfd_dump
9157
9158 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9159 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9160 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9161 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9162
9163 echo $hv1_gw1_ofport
9164 echo $hv1_gw2_ofport
9165 echo $hv2_gw1_ofport
9166 echo $hv2_gw2_ofport
9167
9168 echo "--- hv1 ---"
9169 as hv1 ovs-ofctl dump-flows br-int table=32
9170
9171 echo "--- hv2 ---"
9172 as hv2 ovs-ofctl dump-flows br-int table=32
9173
9174 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
9175 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9176
9177 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
9178 ])
9179
9180 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
9181 ])
9182
9183 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9184
9185 # make sure that flows for handling the outside router port reside on gw1
9186 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
9187 ]])
9188 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
9189 ]])
9190
9191 # make sure ARP responder flows for outside router port reside on gw1 too
9192 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
9193 ]])
9194 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
9195 ]])
9196
9197
9198
9199 # check that the chassis redirect port has been claimed by the gw1 chassis
9200 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9201 [0],[[1
9202 ]])
9203
9204
9205 # at this point, we invert the priority of the gw chassis between gw1 and gw2
9206
9207 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9208 name=outside_gw1 chassis_name=gw1 priority=10 -- \
9209 --id=@gc1 create Gateway_Chassis \
9210 name=outside_gw2 chassis_name=gw2 priority=20 -- \
9211 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9212
9213
9214 # XXX: Let the change propagate down to the ovn-controllers
9215 ovn-nbctl --wait=hv --timeout=3 sync
9216
9217 # we make sure that the hypervisors noticed, and inverted the slave ports
9218 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
9219 ])
9220
9221 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
9222 ])
9223
9224 # check that the chassis redirect port has been reclaimed by the gw2 chassis
9225 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
9226 [0],[[1
9227 ]])
9228
9229 # check BFD enablement on tunnel ports from gw1 #########
9230 as gw1
9231 for chassis in gw2 hv1 hv2; do
9232 echo "checking gw1 -> $chassis"
9233 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9234 [[enable=true
9235 ]])
9236 done
9237
9238
9239 # check BFD enablement on tunnel ports from gw2 ##########
9240 as gw2
9241 for chassis in gw1 hv1 hv2; do
9242 echo "checking gw2 -> $chassis"
9243 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9244 [[enable=true
9245 ]])
9246 done
9247
9248 # check BFD enablement on tunnel ports from hv1 ###########
9249 as hv1
9250 for chassis in gw1 gw2; do
9251 echo "checking hv1 -> $chassis"
9252 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9253 [[enable=true
9254 ]])
9255 done
9256 # make sure BFD is not enabled to hv2, we don't need it
9257 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
9258 [[
9259 ]])
9260
9261
9262 # check BFD enablement on tunnel ports from hv2 ##########
9263 as hv2
9264 for chassis in gw1 gw2; do
9265 echo "checking hv2 -> $chassis"
9266 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9267 [[enable=true
9268 ]])
9269 done
9270 # make sure BFD is not enabled to hv1, we don't need it
9271 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
9272 [[
9273 ]])
9274
9275 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9276
9277 # make sure that flows for handling the outside router port reside on gw2 now
9278 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
9279 ]])
9280 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
9281 ]])
9282
9283 # disconnect GW2 from the network, GW1 should take over
9284 as gw2
9285 port=${sandbox}_br-phys
9286 as main ovs-vsctl del-port n1 $port
9287 sleep 4
9288
9289 bfd_dump
9290
9291 # make sure that flows for handling the outside router port reside on gw2 now
9292 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
9293 ]])
9294 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
9295 ]])
9296
9297 # check that the chassis redirect port has been reclaimed by the gw1 chassis
9298 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9299 [0],[[1
9300 ]])
9301
9302 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
9303 as gw2
9304 for chassis in gw1 hv1 hv2; do
9305 echo "checking gw2 -> $chassis"
9306 OVS_WAIT_UNTIL([
9307 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9308 test "$bfd_cfg" = "enable=true min_rx=2000"
9309 ])
9310 done
9311 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
9312 for chassis in gw1 hv1 hv2; do
9313 echo "checking gw2 -> $chassis"
9314 OVS_WAIT_UNTIL([
9315 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9316 test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
9317 ])
9318 done
9319 ovn-nbctl remove NB_Global . options "bfd-min-rx"
9320 ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
9321 for chassis in gw1 hv1 hv2; do
9322 echo "checking gw2 -> $chassis"
9323 OVS_WAIT_UNTIL([
9324 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9325 test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
9326 ])
9327 done
9328
9329 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
9330
9331 AT_CLEANUP
9332
9333 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
9334 AT_SKIP_IF([test $HAVE_PYTHON = no])
9335 ovn_start
9336 ovn-nbctl ls-add ls0
9337 ovn-nbctl ls-add ls1
9338 ovn-nbctl create Logical_Router name=lr0
9339 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
9340
9341 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9342 name=outside_gw1 chassis_name=hv2 priority=10 -- \
9343 --id=@gc1 create Gateway_Chassis \
9344 name=outside_gw2 chassis_name=hv3 priority=1 -- \
9345 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9346
9347 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9348 type=router options:router-port=lrp0 addresses="router"
9349 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9350 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9351 type=router options:router-port=lrp1 addresses="router"
9352
9353 # Add NAT rules
9354 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
9355
9356 net_add n1
9357 sim_add hv1
9358 as hv1
9359 ovs-vsctl add-br br-phys
9360 ovn_attach n1 br-phys 192.168.0.1
9361 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9362 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])
9363
9364 sim_add hv2
9365 as hv2
9366 ovs-vsctl add-br br-phys
9367 ovn_attach n1 br-phys 192.168.0.2
9368 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9369
9370 sim_add hv3
9371 as hv3
9372 ovs-vsctl add-br br-phys
9373 ovn_attach n1 br-phys 192.168.0.3
9374 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9375
9376 # Create a localnet port.
9377 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9378 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9379 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9380 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
9381
9382 # wait for earlier changes to take effect
9383 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
9384
9385 reset_pcap_file() {
9386 local iface=$1
9387 local pcap_file=$2
9388 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9389 options:rxq_pcap=dummy-rx.pcap
9390 rm -f ${pcap_file}*.pcap
9391 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9392 options:rxq_pcap=${pcap_file}-rx.pcap
9393 }
9394
9395 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9396 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9397 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9398 # add nat-addresses option
9399 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9400
9401 # Wait for packets to be received through hv2.
9402 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9403 trim_zeros() {
9404 sed 's/\(00\)\{1,\}$//'
9405 }
9406
9407 only_broadcast_from_lrp1() {
9408 grep "fffffffffffff00000000001"
9409 }
9410
9411 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
9412 echo $garp > expout
9413
9414 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
9415 echo "packets on hv1-snoopvif:"
9416 cat hv1_snoop_tx
9417 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
9418 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9419 echo "packets on hv2 br-phys tx"
9420 cat hv2_br_phys_tx
9421 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
9422 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9423 echo "packets on hv3 br-phys tx"
9424 cat hv3_br_phys_tx
9425 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9426
9427
9428 # at this point, we invert the priority of the gw chassis between hv2 and hv3
9429
9430 ovn-nbctl --wait=hv \
9431 --id=@gc0 create Gateway_Chassis \
9432 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9433 --id=@gc1 create Gateway_Chassis \
9434 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9435 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9436
9437
9438 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9439 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9440 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9441
9442 # Wait for packets to be received.
9443 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9444 trim_zeros() {
9445 sed 's/\(00\)\{1,\}$//'
9446 }
9447
9448 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9449 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9450 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9451 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9452 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9453 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9454
9455 # change localnet port tag.
9456 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9457
9458 # wait for earlier changes to take effect
9459 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
9460
9461 # update nat-addresses option
9462 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9463 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9464
9465 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9466 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9467 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9468
9469 # Wait for packets to be received.
9470 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9471 trim_zeros() {
9472 sed 's/\(00\)\{1,\}$//'
9473 }
9474
9475 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9476 echo $garp > expout
9477
9478 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9479 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9480 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9481 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9482 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9483 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9484
9485 OVN_CLEANUP([hv1],[hv2],[hv3])
9486
9487 AT_CLEANUP
9488
9489 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9490 AT_SKIP_IF([test $HAVE_PYTHON = no])
9491 ovn_start
9492
9493 net_add n1
9494
9495 # create two gateways with external network connectivity
9496 for i in 1 2; do
9497 sim_add gw$i
9498 as gw$i
9499 ovs-vsctl add-br br-phys
9500 ovn_attach n1 br-phys 192.168.0.$i
9501 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9502 done
9503
9504 ovn-nbctl ls-add inside
9505 ovn-nbctl ls-add outside
9506
9507 # create one hypervisors with a vif port the internal network
9508 sim_add hv1
9509 as hv1
9510 ovs-vsctl add-br br-phys
9511 ovn_attach n1 br-phys 192.168.0.11
9512 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9513 set interface hv1-vif1 external-ids:iface-id=inside1 \
9514 options:tx_pcap=hv1/vif1-tx.pcap \
9515 options:rxq_pcap=hv1/vif1-rx.pcap \
9516 ofport-request=1
9517
9518 ovn-nbctl lsp-add inside inside1 \
9519 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9520
9521
9522 OVN_POPULATE_ARP
9523
9524 ovn-nbctl create Logical_Router name=R1
9525
9526 # Connect inside to R1
9527 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9528 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9529 type=router options:router-port=inside \
9530 -- lsp-set-addresses rp-inside router
9531
9532 # Connect outside to R1 as distributed router gateway port on gw1+gw2
9533 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9534
9535 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9536 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9537 --id=@gc1 create Gateway_Chassis \
9538 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9539 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9540
9541 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9542 type=router options:router-port=outside \
9543 -- lsp-set-addresses rp-outside router
9544
9545 # Create localnet port in outside
9546 ovn-nbctl lsp-add outside ln-outside
9547 ovn-nbctl lsp-set-addresses ln-outside unknown
9548 ovn-nbctl lsp-set-type ln-outside localnet
9549 ovn-nbctl lsp-set-options ln-outside network_name=phys
9550
9551 # Allow some time for ovn-northd and ovn-controller to catch up.
9552 ovn-nbctl --wait=hv --timeout=3 sync
9553
9554 # currently when ovn-controller is restarted, the old entry is deleted
9555 # and a new one is created, which leaves the Gateway_Chassis with
9556 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
9557 # doesn't have the same effect because "name" is conserved, and the
9558 # Chassis entry is not replaced.
9559
9560 > gw1/ovn-controller.log
9561
9562 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9563 ovn-sbctl destroy Chassis $gw2_chassis
9564
9565 # Ensure ovn-controller has processed latest sbdb update
9566 # ovn-nbctl --wait=hv sync
9567
9568 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9569
9570 OVN_CLEANUP([gw1],[gw2],[hv1])
9571
9572 AT_CLEANUP
9573
9574 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9575 AT_KEYWORDS([ovn-nd_ns for unknown mac])
9576 AT_SKIP_IF([test $HAVE_PYTHON = no])
9577 ovn_start
9578
9579 ovn-nbctl ls-add sw0_ip6
9580 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9581 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9582 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9583
9584 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9585 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9586
9587 ovn-nbctl lr-add lr0_ip6
9588 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
9589 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9590 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9591 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
9592 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9593 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9594
9595 ovn-nbctl ls-add public
9596 ovn-nbctl lsp-add public ln-public
9597 ovn-nbctl lsp-set-addresses ln-public unknown
9598 ovn-nbctl lsp-set-type ln-public localnet
9599 ovn-nbctl lsp-set-options ln-public network_name=phys
9600
9601 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
9602 2001:db8:1:0:200:02ff:fe01:0204/64 \
9603 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9604
9605
9606 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9607 rp-ip6_public type=router options:router-port=ip6_public \
9608 -- lsp-set-addresses rp-ip6_public router
9609
9610 net_add n1
9611 sim_add hv1
9612 as hv1
9613 ovs-vsctl add-br br-phys
9614 ovn_attach n1 br-phys 192.168.0.2
9615
9616 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9617 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9618 options:tx_pcap=hv1/vif1-tx.pcap \
9619 options:rxq_pcap=hv1/vif1-rx.pcap \
9620 ofport-request=1
9621 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9622
9623 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9624
9625 # There should be 2 Neighbor Advertisement flows for the router port
9626 # aef0:: ip address in logical switch pipeline with action nd_na_router.
9627 AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
9628 grep "nd_na_router" | wc -l], [0], [2
9629 ])
9630
9631 # There should be 4 Neighbor Advertisement flows with action nd_na_router
9632 # in the router pipeline for the router lr0_ip6.
9633 AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
9634 wc -l], [0], [4
9635 ])
9636
9637 cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9638
9639 # There is only one chassis.
9640 chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9641 OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
9642
9643 trim_zeros() {
9644 sed 's/\(00\)\{1,\}$//'
9645 }
9646
9647 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9648 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
9649 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9650 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9651 # This function sends ipv6 packet
9652 test_ipv6() {
9653 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9654 dst_ip=20010db800010000020002fffe010205
9655
9656 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9657 packet=${packet}8000000000000000
9658 shift; shift; shift; shift
9659
9660 dst_mac=3333ff010205
9661 src_mac=000002010204
9662 mcast_node_ip=ff0200000000000000000001ff010205
9663 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9664 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9665 expected_packet=${expected_packet}0101${src_mac}
9666
9667 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9668 echo $expected_packet >> ipv6_ns.expected
9669 }
9670
9671 src_mac=506400000002
9672 dst_mac=00000000af01
9673 src_ip=aef0000000000000526400fffe000002
9674 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9675 # should be received by the ports attached to br-phys.
9676 test_ipv6 1 $src_mac $dst_mac $src_ip 2
9677
9678 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9679 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9680
9681 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9682 trim_zeros > 1.packets
9683 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9684 trim_zeros > 2.packets
9685
9686 cat ipv6_ns.expected | cut -c -112 > expout
9687 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9688 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9689
9690 # Skipping the ICMPv6 checksum
9691 cat ipv6_ns.expected | cut -c 117- > expout
9692 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9693 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9694
9695 OVN_CLEANUP([hv1])
9696
9697 AT_CLEANUP
9698
9699 AT_SETUP([ovn -- options:requested-chassis for logical port])
9700 ovn_start
9701
9702 net_add n1
9703
9704 ovn-nbctl ls-add ls0
9705 ovn-nbctl lsp-add ls0 lsp0
9706
9707 # create two hypervisors, each with one vif port
9708 sim_add hv1
9709 as hv1
9710 ovs-vsctl add-br br-phys
9711 ovn_attach n1 br-phys 192.168.0.11
9712 ovs-vsctl -- add-port br-int hv1-vif0 -- \
9713 set Interface hv1-vif0 ofport-request=1
9714
9715 sim_add hv2
9716 as hv2
9717 ovs-vsctl add-br br-phys
9718 ovn_attach n1 br-phys 192.168.0.12
9719 ovs-vsctl -- add-port br-int hv2-vif0 -- \
9720 set Interface hv2-vif0 ofport-request=1
9721
9722 # Allow only chassis hv1 to bind logical port lsp0.
9723 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9724
9725 # Allow some time for ovn-northd and ovn-controller to catch up.
9726 ovn-nbctl --wait=hv --timeout=3 sync
9727
9728 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
9729 ovn-sbctl wait-until chassis hv1
9730 ovn-sbctl wait-until chassis hv2
9731 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9732 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9733
9734 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9735 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9736 as hv2
9737 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9738
9739 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9740 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9741
9742 # (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9743 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9744 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9745
9746 # (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9747 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9748 as hv1
9749 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9750
9751 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9752 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9753
9754 # (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9755 as hv1 ovs-ofctl dump-flows br-int
9756 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9757 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9758
9759 # (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9760 # the requested chassis for lsp0 is changed from hv1 to hv2.
9761 echo "verifying that lsp0 binding moves when requested-chassis is changed"
9762
9763 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9764 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9765 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
9766
9767 # (6) Chassis hv2 should add flows and hv1 should not.
9768 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9769 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9770
9771 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9772 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9773
9774 OVN_CLEANUP([hv1],[hv2])
9775
9776 AT_CLEANUP
9777
9778 AT_SETUP([ovn -- options:requested-chassis with hostname])
9779
9780 ovn_start
9781
9782 ovn-nbctl ls-add ls0
9783 ovn-nbctl lsp-add ls0 lsp0
9784
9785 net_add n1
9786 sim_add hv1
9787 as hv1
9788 ovs-vsctl add-br br-phys
9789 ovn_attach n1 br-phys 192.168.0.11
9790 ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
9791
9792 ovn-sbctl wait-until chassis hv1
9793 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9794 echo "hv1_hostname=${hv1_hostname}"
9795 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9796 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9797
9798 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9799 echo "hv1_uuid=${hv1_uuid}"
9800 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9801 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9802 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9803 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9804
9805 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9806 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9807 ovn-nbctl --wait=hv --timeout=3 sync
9808 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9809 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9810 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9811
9812 OVN_CLEANUP([hv1])
9813
9814 AT_CLEANUP
9815
9816 AT_SETUP([ovn -- IPv6 periodic RA])
9817 ovn_start
9818
9819 # This test sets up two hypervisors.
9820 # hv1 and hv2 run ovn-controllers, and
9821 # each has a VIF connected to the same
9822 # logical switch in OVN. The logical
9823 # switch is connected to a logical
9824 # router port that is configured to send
9825 # periodic router advertisements.
9826 #
9827 # The reason for having two ovn-controller
9828 # hypervisors is to ensure that the
9829 # periodic RAs being sent by each ovn-controller
9830 # are kept to their local hypervisors. If the
9831 # packets are not kept local, then each port
9832 # will receive too many RAs.
9833
9834 net_add n1
9835 sim_add hv1
9836 sim_add hv2
9837 as hv1
9838 ovs-vsctl add-br br-phys
9839 ovn_attach n1 br-phys 192.168.0.2
9840 as hv2
9841 ovs-vsctl add-br br-phys
9842 ovn_attach n1 br-phys 192.168.0.3
9843
9844 ovn-nbctl lr-add ro
9845 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
9846
9847 ovn-nbctl ls-add sw
9848 ovn-nbctl lsp-add sw sw-ro
9849 ovn-nbctl lsp-set-type sw-ro router
9850 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9851 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9852 ovn-nbctl lsp-add sw sw-p1
9853 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9854 ovn-nbctl lsp-add sw sw-p2
9855 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9856
9857 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9858 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9859 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9860 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9861
9862 for i in 1 2 ; do
9863 as hv$i
9864 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9865 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9866 options:tx_pcap=hv$i/vif1-tx.pcap \
9867 options:rxq_pcap=hv$i/vif1-rx.pcap \
9868 ofport-request=1
9869 done
9870
9871 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9872 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
9873
9874 reset_pcap_file() {
9875 local iface=$1
9876 local pcap_file=$2
9877 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9878 options:rxq_pcap=dummy-rx.pcap
9879 rm -f ${pcap_file}*.pcap
9880 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9881 options:rxq_pcap=${pcap_file}-rx.pcap
9882
9883 }
9884
9885 construct_expected_ra() {
9886 local src_mac=000000000001
9887 local dst_mac=333300000001
9888 local src_addr=fe80000000000000020000fffe000001
9889 local dst_addr=ff020000000000000000000000000001
9890
9891 local mtu=$1
9892 local ra_mo=$2
9893 local ra_prefix_la=$3
9894
9895 local slla=0101${src_mac}
9896 local mtu_opt=""
9897 if test $mtu != 0; then
9898 mtu_opt=05010000${mtu}
9899 fi
9900 shift 3
9901
9902 local prefix=""
9903 while [[ $# -gt 0 ]] ; do
9904 local size=$1
9905 local net=$2
9906 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9907 shift 2
9908 done
9909
9910 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
9911 local icmp=8600XXXX${ra}
9912
9913 local ip_len=$(expr ${#icmp} / 2)
9914 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
9915
9916 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9917 local eth=${dst_mac}${src_mac}86dd${ip}
9918 local packet=${eth}
9919 echo $packet >> expected
9920 }
9921
9922 ra_test() {
9923 construct_expected_ra $@
9924
9925 for i in hv1 hv2 ; do
9926 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9927
9928 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9929
9930 cat expected | cut -c -112 > expout
9931 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9932
9933 # Skip ICMPv6 checksum.
9934 cat expected | cut -c 117- > expout
9935 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9936
9937 rm -f packets
9938 as $i reset_pcap_file $i-vif1 $i/vif1
9939 done
9940
9941 rm -f expected
9942 }
9943
9944 # Baseline test with no MTU
9945 ra_test 0 00 c0 40 aef00000000000000000000000000000
9946
9947 # Now make sure an MTU option makes it
9948 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9949 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9950
9951 # Now test for multiple network prefixes
9952 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9953 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9954
9955 # Test a different address mode now
9956 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9957 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9958
9959 # And the other address mode
9960 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9961 ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9962
9963 OVN_CLEANUP([hv1],[hv2])
9964 AT_CLEANUP
9965
9966 AT_SETUP([ovn -- ACL reject rule test])
9967 AT_KEYWORDS([acl-reject])
9968 AT_SKIP_IF([test $HAVE_PYTHON = no])
9969 ovn_start
9970
9971 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9972 #
9973 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9974 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9975 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9976 # unreachable frame generated from ACL rule hit
9977 #
9978 # INPORT is a lport number, e.g. 11 for vif11.
9979 # HV is a hypervisor number
9980 # ETH_SRC and ETH_DST are each 12 hex digits.
9981 # IPV4_SRC and IPV4_DST are each 8 hex digits.
9982 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9983 test_ip_packet() {
9984 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9985 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9986 shift 9
9987
9988 local ip_ttl=ff
9989 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9990
9991 local reply_icmp_ttl=ff
9992 local icmp_type_code_response=0301
9993 local icmp_data=00000000
9994 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9995 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9996 echo $reply >> vif$inport.expected
9997
9998 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9999 }
10000
10001 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
10002 #
10003 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
10004 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
10005 # EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
10006 test_ipv6_packet() {
10007 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
10008 shift 7
10009
10010 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
10011 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
10012
10013 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
10014 echo $reply >> vif$inport.expected
10015
10016 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10017 }
10018
10019 # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
10020 #
10021 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10022 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10023 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
10024 #
10025 # INPORT is an lport number, e.g. 11 for vif11.
10026 # HV is an hypervisor number
10027 # ETH_SRC and ETH_DST are each 12 hex digits.
10028 # IPV4_SRC and IPV4_DST are each 8 hex digits.
10029 # TCP_SPORT and TCP_DPORT are 4 hex digits.
10030 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10031 test_tcp_syn_packet() {
10032 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
10033 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10034 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10035 shift 12
10036
10037 local ip_ttl=ff
10038 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10039
10040 local tcp_rst_ttl=ff
10041 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10042 echo $reply >> vif$inport.expected
10043
10044 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10045 }
10046
10047 # Create hypervisors hv[123].
10048 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
10049 # Add all of the vifs to a single logical switch sw0.
10050
10051 net_add n1
10052 ovn-nbctl ls-add sw0
10053 for i in 1 2 3; do
10054 sim_add hv$i
10055 as hv$i
10056 ovs-vsctl add-br br-phys
10057 ovn_attach n1 br-phys 192.168.0.$i
10058
10059 for j in 1 2 3; do
10060 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
10061 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
10062
10063 ovs-vsctl -- add-port br-int vif$i$j -- \
10064 set interface vif$i$j \
10065 external-ids:iface-id=sw0-p$i$j \
10066 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
10067 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
10068 ofport-request=$i$j
10069 done
10070 done
10071
10072 OVN_POPULATE_ARP
10073 # allow some time for ovn-northd and ovn-controller to catch up.
10074 sleep 1
10075
10076 ip_to_hex() {
10077 printf "%02x%02x%02x%02x" "$@"
10078 }
10079
10080 for i in 1 2 3; do
10081 : > vif${i}1.expected
10082 done
10083
10084 ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
10085 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
10086 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
10087
10088 # Allow some time for ovn-northd and ovn-controller to catch up.
10089 ovn-nbctl --timeout=3 --wait=hv sync
10090
10091 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
10092 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
10093 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
10094
10095 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
10096
10097 test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 8b40 3039 0000 7d8d 4486
10098 test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 7d8d 4486
10099 test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 7d82 4486
10100
10101 for i in 1 2 3; do
10102 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
10103 done
10104
10105 OVN_CLEANUP([hv1], [hv2], [hv3])
10106 AT_CLEANUP
10107
10108 AT_SETUP([ovn -- Port Groups])
10109 AT_KEYWORDS([ovnpg])
10110 AT_SKIP_IF([test $HAVE_PYTHON = no])
10111 ovn_start
10112
10113 # Logical network:
10114 #
10115 # Three logical switches ls1, ls2, ls3.
10116 # One logical router lr0 connected to ls[123],
10117 # with nine subnets, three per logical switch:
10118 #
10119 # lrp11 on ls1 for subnet 192.168.11.0/24
10120 # lrp12 on ls1 for subnet 192.168.12.0/24
10121 # lrp13 on ls1 for subnet 192.168.13.0/24
10122 # ...
10123 # lrp33 on ls3 for subnet 192.168.33.0/24
10124 #
10125 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10126 # digits are the subnet and the last digit distinguishes the VIF.
10127 #
10128 # This test will create two port groups and uses them in ACL.
10129
10130 get_lsp_uuid () {
10131 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10132 }
10133
10134 pg1_ports=
10135 pg2_ports=
10136 for i in 1 2 3; do
10137 ovn-nbctl ls-add ls$i
10138 for j in 1 2 3; do
10139 for k in 1 2 3; do
10140 ovn-nbctl \
10141 -- lsp-add ls$i lp$i$j$k \
10142 -- lsp-set-addresses lp$i$j$k \
10143 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
10144 # logical ports lp[12]?1 belongs to port group pg1
10145 if test $i != 3 && test $k == 1; then
10146 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10147 fi
10148 # logical ports lp[23]?2 belongs to port group pg2
10149 if test $i != 1 && test $k == 2; then
10150 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10151 fi
10152 done
10153 done
10154 done
10155
10156 ovn-nbctl lr-add lr0
10157 for i in 1 2 3; do
10158 for j in 1 2 3; do
10159 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10160 ovn-nbctl \
10161 -- lsp-add ls$i lrp$i$j-attachment \
10162 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10163 options:router-port=lrp$i$j \
10164 addresses='"00:00:00:00:ff:'$i$j'"'
10165 done
10166 done
10167
10168 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
10169 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10170
10171 # create ACLs on all lswitches to drop traffic from pg2 to pg1
10172 ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10173 ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10174 ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10175
10176 # Physical network:
10177 #
10178 # Three hypervisors hv[123].
10179 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10180 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10181 # lp?3[123] all on hv3.
10182
10183 # Given the name of a logical port, prints the name of the hypervisor
10184 # on which it is located.
10185 vif_to_hv() {
10186 case $1 in dnl (
10187 ?11) echo 1 ;; dnl (
10188 ?12 | ?21 | ?22) echo 2 ;; dnl (
10189 ?13 | ?23 | ?3?) echo 3 ;;
10190 esac
10191 }
10192
10193 # Given the name of a logical port, prints the name of its logical router
10194 # port, e.g. "vif_to_lrp 123" yields 12.
10195 vif_to_lrp() {
10196 echo ${1%?}
10197 }
10198
10199 # Given the name of a logical port, prints the name of its logical
10200 # switch, e.g. "vif_to_ls 123" yields 1.
10201 vif_to_ls() {
10202 echo ${1%??}
10203 }
10204
10205 net_add n1
10206 for i in 1 2 3; do
10207 sim_add hv$i
10208 as hv$i
10209 ovs-vsctl add-br br-phys
10210 ovn_attach n1 br-phys 192.168.0.$i
10211 done
10212 for i in 1 2 3; do
10213 for j in 1 2 3; do
10214 for k in 1 2 3; do
10215 hv=`vif_to_hv $i$j$k`
10216 as hv$hv ovs-vsctl \
10217 -- add-port br-int vif$i$j$k \
10218 -- set Interface vif$i$j$k \
10219 external-ids:iface-id=lp$i$j$k \
10220 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10221 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10222 ofport-request=$i$j$k
10223 done
10224 done
10225 done
10226
10227 # Pre-populate the hypervisors' ARP tables so that we don't lose any
10228 # packets for ARP resolution (native tunneling doesn't queue packets
10229 # for ARP resolution).
10230 OVN_POPULATE_ARP
10231
10232 # Allow some time for ovn-northd and ovn-controller to catch up.
10233 # XXX This should be more systematic.
10234 sleep 1
10235
10236 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10237 #
10238 # This shell function causes a packet to be received on INPORT. The packet's
10239 # content has Ethernet destination DST and source SRC (each exactly 12 hex
10240 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
10241 # more) list the VIFs on which the packet should be received. INPORT and the
10242 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
10243 for i in 1 2 3; do
10244 for j in 1 2 3; do
10245 for k in 1 2 3; do
10246 : > $i$j$k.expected
10247 done
10248 done
10249 done
10250 test_ip() {
10251 # This packet has bad checksums but logical L3 routing doesn't check.
10252 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10253 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
10254 shift; shift; shift; shift; shift
10255 hv=hv`vif_to_hv $inport`
10256 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
10257 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
10258 in_ls=`vif_to_ls $inport`
10259 in_lrp=`vif_to_lrp $inport`
10260 for outport; do
10261 out_ls=`vif_to_ls $outport`
10262 if test $in_ls = $out_ls; then
10263 # Ports on the same logical switch receive exactly the same packet.
10264 echo $packet
10265 else
10266 # Routing decrements TTL and updates source and dest MAC
10267 # (and checksum).
10268 out_lrp=`vif_to_lrp $outport`
10269 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10270 fi >> $outport.expected
10271 done
10272 }
10273
10274 as hv1 ovs-vsctl --columns=name,ofport list interface
10275 as hv1 ovn-sbctl list port_binding
10276 as hv1 ovn-sbctl list datapath_binding
10277 as hv1 ovn-sbctl list port_group
10278 as hv1 ovn-sbctl list address_set
10279 as hv1 ovn-sbctl dump-flows
10280 as hv1 ovs-ofctl dump-flows br-int
10281
10282 # Send IP packets between all pairs of source and destination ports,
10283 # packets matches ACL (pg2 to pg1) should be dropped
10284 ip_to_hex() {
10285 printf "%02x%02x%02x%02x" "$@"
10286 }
10287 for is in 1 2 3; do
10288 for js in 1 2 3; do
10289 for ks in 1 2 3; do
10290 bcast=
10291 s=$is$js$ks
10292 smac=f00000000$s
10293 sip=`ip_to_hex 192 168 $is$js $ks`
10294 for id in 1 2 3; do
10295 for jd in 1 2 3; do
10296 for kd in 1 2 3; do
10297 d=$id$jd$kd
10298 dip=`ip_to_hex 192 168 $id$jd $kd`
10299 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10300 if test $d != $s; then unicast=$d; else unicast=; fi
10301
10302 # packets matches ACL should be dropped
10303 if test $id != 3 && test $kd == 1; then
10304 if test $is != 1 && test $ks == 2; then
10305 unicast=
10306 fi
10307 fi
10308 test_ip $s $smac $dmac $sip $dip $unicast #1
10309 done
10310 done
10311 done
10312 done
10313 done
10314 done
10315
10316 # Allow some time for packet forwarding.
10317 # XXX This can be improved.
10318 sleep 1
10319
10320 # Now check the packets actually received against the ones expected.
10321 for i in 1 2 3; do
10322 for j in 1 2 3; do
10323 for k in 1 2 3; do
10324 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10325 [$i$j$k.expected])
10326 done
10327 done
10328 done
10329
10330 # Gracefully terminate daemons
10331 OVN_CLEANUP([hv1], [hv2], [hv3])
10332 AT_CLEANUP
10333
10334 AT_SETUP([ovn -- ACLs on Port Groups])
10335 AT_KEYWORDS([ovnpg_acl])
10336 AT_SKIP_IF([test $HAVE_PYTHON = no])
10337 ovn_start
10338
10339 # Logical network:
10340 #
10341 # Three logical switches ls1, ls2, ls3.
10342 # One logical router lr0 connected to ls[123],
10343 # with nine subnets, three per logical switch:
10344 #
10345 # lrp11 on ls1 for subnet 192.168.11.0/24
10346 # lrp12 on ls1 for subnet 192.168.12.0/24
10347 # lrp13 on ls1 for subnet 192.168.13.0/24
10348 # ...
10349 # lrp33 on ls3 for subnet 192.168.33.0/24
10350 #
10351 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10352 # digits are the subnet and the last digit distinguishes the VIF.
10353 #
10354 # This test will create two port groups and ACLs will be applied on them.
10355
10356 get_lsp_uuid () {
10357 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10358 }
10359
10360 pg1_ports=
10361 pg2_ports=
10362 for i in 1 2 3; do
10363 ovn-nbctl ls-add ls$i
10364 for j in 1 2 3; do
10365 for k in 1 2 3; do
10366 ovn-nbctl \
10367 -- lsp-add ls$i lp$i$j$k \
10368 -- lsp-set-addresses lp$i$j$k \
10369 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
10370 # logical ports lp[12]?1 belongs to port group pg1
10371 if test $i != 3 && test $k == 1; then
10372 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10373 fi
10374 # logical ports lp[23]?2 belongs to port group pg2
10375 if test $i != 1 && test $k == 2; then
10376 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10377 fi
10378 done
10379 done
10380 done
10381
10382 ovn-nbctl lr-add lr0
10383 for i in 1 2 3; do
10384 for j in 1 2 3; do
10385 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10386 ovn-nbctl \
10387 -- lsp-add ls$i lrp$i$j-attachment \
10388 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10389 options:router-port=lrp$i$j \
10390 addresses='"00:00:00:00:ff:'$i$j'"'
10391 done
10392 done
10393
10394 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
10395 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10396
10397 # create ACLs on pg1 to drop traffic from pg2 to pg1
10398 ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
10399 ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
10400 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
10401
10402 # Physical network:
10403 #
10404 # Three hypervisors hv[123].
10405 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10406 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10407 # lp?3[123] all on hv3.
10408
10409 # Given the name of a logical port, prints the name of the hypervisor
10410 # on which it is located.
10411 vif_to_hv() {
10412 case $1 in dnl (
10413 ?11) echo 1 ;; dnl (
10414 ?12 | ?21 | ?22) echo 2 ;; dnl (
10415 ?13 | ?23 | ?3?) echo 3 ;;
10416 esac
10417 }
10418
10419 # Given the name of a logical port, prints the name of its logical router
10420 # port, e.g. "vif_to_lrp 123" yields 12.
10421 vif_to_lrp() {
10422 echo ${1%?}
10423 }
10424
10425 # Given the name of a logical port, prints the name of its logical
10426 # switch, e.g. "vif_to_ls 123" yields 1.
10427 vif_to_ls() {
10428 echo ${1%??}
10429 }
10430
10431 net_add n1
10432 for i in 1 2 3; do
10433 sim_add hv$i
10434 as hv$i
10435 ovs-vsctl add-br br-phys
10436 ovn_attach n1 br-phys 192.168.0.$i
10437 done
10438 for i in 1 2 3; do
10439 for j in 1 2 3; do
10440 for k in 1 2 3; do
10441 hv=`vif_to_hv $i$j$k`
10442 as hv$hv ovs-vsctl \
10443 -- add-port br-int vif$i$j$k \
10444 -- set Interface vif$i$j$k \
10445 external-ids:iface-id=lp$i$j$k \
10446 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10447 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10448 ofport-request=$i$j$k
10449 done
10450 done
10451 done
10452
10453 # Pre-populate the hypervisors' ARP tables so that we don't lose any
10454 # packets for ARP resolution (native tunneling doesn't queue packets
10455 # for ARP resolution).
10456 OVN_POPULATE_ARP
10457
10458 # Allow some time for ovn-northd and ovn-controller to catch up.
10459 # XXX This should be more systematic.
10460 sleep 1
10461
10462 lsp_to_mac() {
10463 echo f0:00:00:00:0${1:0:1}:${1:1:2}
10464 }
10465
10466 lrp_to_mac() {
10467 echo 00:00:00:00:ff:$1
10468 }
10469
10470 # test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
10471 #
10472 # This shell function causes a ICMP packet to be received on INPORT.
10473 # The OUTPORTs (zero or more) list the VIFs on which the packet should
10474 # be received. INPORT and the OUTPORTs are specified as logical switch
10475 # port numbers, e.g. 123 for vif123.
10476 for i in 1 2 3; do
10477 for j in 1 2 3; do
10478 for k in 1 2 3; do
10479 : > $i$j$k.expected
10480 done
10481 done
10482 done
10483
10484 test_icmp() {
10485 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
10486 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
10487 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
10488 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
10489 icmp4.code==0"
10490 shift; shift; shift; shift; shift; shift
10491 hv=hv`vif_to_hv $inport`
10492 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
10493 in_ls=`vif_to_ls $inport`
10494 in_lrp=`vif_to_lrp $inport`
10495 for outport; do
10496 out_ls=`vif_to_ls $outport`
10497 if test $in_ls = $out_ls; then
10498 # Ports on the same logical switch receive exactly the same packet.
10499 echo $packet | ovstest test-ovn expr-to-packets
10500 else
10501 # Routing decrements TTL and updates source and dest MAC
10502 # (and checksum).
10503 out_lrp=`vif_to_lrp $outport`
10504 exp_smac=`lrp_to_mac $out_lrp`
10505 exp_dmac=`lsp_to_mac $outport`
10506 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
10507 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
10508 icmp4.type==$icmp_type && icmp4.code==0"
10509 echo $exp_packet | ovstest test-ovn expr-to-packets
10510
10511 fi >> $outport.expected
10512 done
10513 }
10514
10515 as hv1 ovs-vsctl --columns=name,ofport list interface
10516 as hv1 ovn-sbctl list port_binding
10517 as hv1 ovn-sbctl list datapath_binding
10518 as hv1 ovn-sbctl list port_group
10519 as hv1 ovn-sbctl list address_set
10520 as hv1 ovn-sbctl dump-flows
10521 as hv1 ovs-ofctl dump-flows br-int
10522
10523 # Send IP packets between all pairs of source and destination ports,
10524 # packets matches ACL1 but not ACL2 should be dropped
10525 ip_to_hex() {
10526 printf "%02x%02x%02x%02x" "$@"
10527 }
10528 for is in 1 2 3; do
10529 for js in 1 2 3; do
10530 for ks in 1 2 3; do
10531 bcast=
10532 s=$is$js$ks
10533 slsp_mac=`lsp_to_mac $s`
10534 slrp_mac=`lrp_to_mac $is$js`
10535 sip=192.168.$is$js.$ks
10536 for id in 1 2 3; do
10537 for jd in 1 2 3; do
10538 for kd in 1 2 3; do
10539 d=$id$jd$kd
10540 dlsp_mac=`lsp_to_mac $d`
10541 dlrp_mac=`lrp_to_mac $id$jd`
10542 dip=192.168.$id$jd.$kd
10543 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
10544 if test $d != $s; then unicast=$d; else unicast=; fi
10545
10546 # packets matches ACL1 but not ACL2 should be dropped
10547 if test $id != 3 && test $kd == 1; then
10548 if test $is == 1 || test $ks != 2; then
10549 unicast=
10550 fi
10551 fi
10552 # icmp request (type = 8)
10553 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
10554
10555 # if packets are not dropped, test the return traffic (icmp echo)
10556 # to make sure stateful works, too.
10557 if test x$unicast != x; then
10558 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
10559 # icmp echo (type = 0)
10560 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
10561 fi
10562 done
10563 done
10564 done
10565 done
10566 done
10567 done
10568
10569 # Allow some time for packet forwarding.
10570 # XXX This can be improved.
10571 sleep 1
10572
10573 # Now check the packets actually received against the ones expected.
10574 for i in 1 2 3; do
10575 for j in 1 2 3; do
10576 for k in 1 2 3; do
10577 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10578 [$i$j$k.expected])
10579 done
10580 done
10581 done
10582
10583 # Gracefully terminate daemons
10584 OVN_CLEANUP([hv1], [hv2], [hv3])
10585 AT_CLEANUP
10586
10587 AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
10588 ovn_start
10589
10590 ovn-nbctl ls-add ls1
10591
10592 ovn-nbctl lsp-add ls1 lp1
10593 ovn-nbctl lsp-add ls1 lp2
10594 ovn-nbctl lsp-add ls1 lp3
10595
10596 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
10597 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
10598 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
10599
10600 ovn-nbctl create Port_Group name=pg1
10601 ovn-nbctl create Port_Group name=pg2
10602
10603 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
10604 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
10605 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
10606 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
10607
10608 ovn-nbctl --wait=sb sync
10609
10610 dnl Check if port group address sets were populated with ports' addresses
10611 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10612 [0], [[["10.0.0.1", "10.0.0.2"]]
10613 ])
10614 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
10615 [0], [[["10.0.0.2", "10.0.0.3"]]
10616 ])
10617 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10618 [0], [[["2001:db8::1", "2001:db8::2"]]
10619 ])
10620 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
10621 [0], [[["2001:db8::2", "2001:db8::3"]]
10622 ])
10623
10624 ovn-nbctl --wait=sb lsp-set-addresses lp1 \
10625 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
10626
10627 dnl Check if updated address got propagated to the port group address sets
10628 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10629 [0], [[["10.0.0.11", "10.0.0.2"]]
10630 ])
10631 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10632 [0], [[["2001:db8::11", "2001:db8::2"]]
10633 ])
10634
10635 AT_CLEANUP
10636
10637 AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
10638 ovn_start
10639
10640 ovn-nbctl ls-add ls1
10641 ovn-nbctl ls-add ls2
10642 ovn-nbctl ls-add ls3
10643
10644 ovn-nbctl set Logical_Switch ls1 \
10645 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
10646 ovn-nbctl set Logical_Switch ls2 \
10647 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
10648 ovn-nbctl set Logical_Switch ls3 \
10649 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
10650
10651 ovn-nbctl lsp-add ls1 lp1
10652 ovn-nbctl lsp-add ls2 lp2
10653 ovn-nbctl lsp-add ls3 lp3
10654
10655 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
10656 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
10657 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
10658
10659 ovn-nbctl create Port_Group name=pg1
10660 ovn-nbctl create Port_Group name=pg2
10661
10662 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
10663 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
10664 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
10665 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
10666
10667 ovn-nbctl --wait=sb sync
10668
10669 dnl Check if port group address sets were populated with ports' addresses
10670 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10671 [0], [[["10.1.0.2", "10.2.0.2"]]
10672 ])
10673 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
10674 [0], [[["10.2.0.2", "10.3.0.2"]]
10675 ])
10676 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10677 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
10678 ])
10679 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
10680 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
10681 ])
10682
10683 ovn-nbctl set Logical_Switch ls1 \
10684 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
10685
10686 dnl Check if updated address got propagated to the port group address sets
10687 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10688 [0], [[["10.11.0.2", "10.2.0.2"]]
10689 ])
10690 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10691 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
10692 ])
10693
10694 AT_CLEANUP
10695
10696 AT_SETUP([ovn -- ACL conjunction])
10697 ovn_start
10698
10699 ovn-nbctl ls-add ls1
10700
10701 ovn-nbctl lsp-add ls1 ls1-lp1 \
10702 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10703
10704 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10705
10706 ovn-nbctl lsp-add ls1 ls1-lp2 \
10707 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10708
10709 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10710
10711 net_add n1
10712 sim_add hv1
10713
10714 as hv1
10715 ovs-vsctl add-br br-phys
10716 ovn_attach n1 br-phys 192.168.0.1
10717 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10718 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
10719 options:tx_pcap=hv1/vif1-tx.pcap \
10720 options:rxq_pcap=hv1/vif1-rx.pcap \
10721 ofport-request=1
10722
10723 ovs-vsctl -- add-port br-int hv1-vif2 -- \
10724 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
10725 options:tx_pcap=hv1/vif2-tx.pcap \
10726 options:rxq_pcap=hv1/vif2-rx.pcap \
10727 ofport-request=2
10728
10729 ovn-nbctl create Address_Set name=set1 \
10730 addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
10731 ovn-nbctl create Address_Set name=set2 \
10732 addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
10733 ovn-nbctl acl-add ls1 to-lport 1002 \
10734 'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
10735 ovn-nbctl acl-add ls1 to-lport 1001 \
10736 'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
10737
10738 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10739 #
10740 # This shell function causes an ip packet to be received on INPORT.
10741 # The packet's content has Ethernet destination DST and source SRC
10742 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
10743 # The OUTPORTs (zero or more) list the VIFs on which the packet should
10744 # be received. INPORT and the OUTPORTs are specified as logical switch
10745 # port numbers, e.g. 11 for vif11.
10746 test_ip() {
10747 # This packet has bad checksums but logical L3 routing doesn't check.
10748 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10749 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
10750 ${dst_ip}0035111100080000
10751 shift; shift; shift; shift; shift
10752 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
10753 for outport; do
10754 echo $packet >> $outport.expected
10755 done
10756 }
10757
10758 ip_to_hex() {
10759 printf "%02x%02x%02x%02x" "$@"
10760 }
10761
10762 reset_pcap_file() {
10763 local iface=$1
10764 local pcap_file=$2
10765 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10766 options:rxq_pcap=dummy-rx.pcap
10767 rm -f ${pcap_file}*.pcap
10768 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10769 options:rxq_pcap=${pcap_file}-rx.pcap
10770 }
10771
10772
10773 sip=`ip_to_hex 10 0 0 4`
10774 dip=`ip_to_hex 10 0 0 6`
10775
10776 test_ip 1 f00000000001 f00000000002 $sip $dip 2
10777
10778 cat 2.expected > expout
10779 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10780 AT_CHECK([cat 2.packets], [0], [expout])
10781
10782 # There should be total of 12 flows present with conjunction action and 2 flows
10783 # with conj match. Eg.
10784 # table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
10785 # table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
10786 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
10787 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
10788 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
10789 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
10790 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
10791 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
10792 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
10793 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
10794 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
10795 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
10796 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
10797 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
10798
10799 OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
10800 grep conjunction | wc -l`])
10801 OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
10802 grep conj_id | wc -l`])
10803
10804 as hv1 ovs-ofctl dump-flows br-int
10805
10806 # Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
10807 ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10808 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10809
10810 reset_pcap_file hv1-vif2 hv1/vif2
10811
10812 rm -f 2.packets
10813
10814 sip=`ip_to_hex 10 0 0 4`
10815 dip=`ip_to_hex 10 0 0 7`
10816
10817 test_ip 1 f00000000001 f00000000002 $sip $dip
10818 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10819 AT_CHECK([cat 2.packets], [0], [])
10820
10821 AT_CLEANUP
10822
10823 AT_SETUP([ovn -- TTL exceeded])
10824 AT_KEYWORDS([ttl-exceeded])
10825 AT_SKIP_IF([test $HAVE_PYTHON = no])
10826 ovn_start
10827
10828 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
10829 #
10830 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10831 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
10832 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
10833 # generated by OVN logical router
10834 #
10835 # INPORT is a lport number, e.g. 11 for vif11.
10836 # HV is a hypervisor number
10837 # ETH_SRC and ETH_DST are each 12 hex digits.
10838 # IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
10839 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10840 test_ip_packet() {
10841 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
10842 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
10843 shift 10
10844
10845 local ip_ttl=01
10846 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
10847
10848 local reply_icmp_ttl=fe
10849 local icmp_type_code_response=0b00
10850 local icmp_data=00000000
10851 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
10852 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10853 echo $reply >> vif$inport.expected
10854
10855 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10856 }
10857
10858 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
10859 #
10860 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
10861 # packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
10862 # IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
10863 # packet sent by OVN logical router
10864 test_ip6_packet() {
10865 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
10866 shift 8
10867
10868 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
10869 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
10870
10871 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
10872 echo $reply >> vif$inport.expected
10873
10874 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10875 }
10876
10877 ip_to_hex() {
10878 printf "%02x%02x%02x%02x" "$@"
10879 }
10880
10881 for i in 1 2; do
10882 net_add n$i
10883 ovn-nbctl ls-add sw$i
10884
10885 sim_add hv$i
10886 as hv$i
10887 ovs-vsctl add-br br-phys
10888 ovn_attach n$i br-phys 192.168.$i.1
10889
10890 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
10891 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
10892
10893 ovs-vsctl -- add-port br-int vif$i -- \
10894 set interface vif$i \
10895 external-ids:iface-id=sw$i-p${i}0 \
10896 options:tx_pcap=hv$i/vif$i-tx.pcap \
10897 options:rxq_pcap=hv$i/vif$i-rx.pcap \
10898 ofport-request=$i
10899 done
10900
10901 ovn-nbctl lr-add lr0
10902 for i in 1 2; do
10903 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
10904 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
10905 -- set Logical_Switch_Port lrp$i-attachment type=router \
10906 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
10907 done
10908
10909 OVN_POPULATE_ARP
10910 # allow some time for ovn-northd and ovn-controller to catch up.
10911 ovn-nbctl --wait=hv sync
10912
10913 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 1 254) 0000 7dae f4ff
10914 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
10915 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
10916
10917 OVN_CLEANUP([hv1], [hv2])
10918 AT_CLEANUP
10919
10920 AT_SETUP([ovn -- router port unreachable])
10921 AT_KEYWORDS([router-port-unreachable])
10922 AT_SKIP_IF([test $HAVE_PYTHON = no])
10923 ovn_start
10924
10925 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER L4_PROTCOL IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM EXP_ICMP_CODE
10926 #
10927 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10928 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
10929 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
10930 # EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
10931 #
10932 # INPORT is a lport number, e.g. 11 for vif11.
10933 # HV is a hypervisor number
10934 # ETH_SRC and ETH_DST are each 12 hex digits.
10935 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10936 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10937 test_ip_packet() {
10938 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
10939 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
10940 shift 11
10941
10942 local ip_ttl=ff
10943 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
10944
10945 local reply_icmp_ttl=fe
10946 local icmp_data=00000000
10947 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
10948 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10949 echo $reply >> vif$inport.expected
10950
10951 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10952 }
10953
10954 # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
10955 #
10956 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10957 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10958 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
10959 #
10960 # INPORT is an lport number, e.g. 11 for vif11.
10961 # HV is an hypervisor number
10962 # ETH_SRC and ETH_DST are each 12 hex digits.
10963 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10964 # TCP_SPORT and TCP_DPORT are 4 hex digits.
10965 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10966 test_tcp_syn_packet() {
10967 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
10968 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10969 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10970 shift 12
10971
10972 local ip_ttl=ff
10973 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10974
10975 local tcp_rst_ttl=fe
10976 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ip_router}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10977 echo $reply >> vif$inport.expected
10978
10979 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10980 }
10981
10982 # test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
10983 #
10984 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
10985 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
10986 # EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
10987 test_tcp6_packet() {
10988 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
10989 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
10990 local exp_tcp_rst_chksum=${10}
10991 shift 10
10992
10993 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
10994 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10995
10996 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10997 echo $reply >> vif$inport.expected
10998
10999 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11000 }
11001
11002 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
11003 #
11004 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
11005 # packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
11006 # EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
11007 test_ip6_packet() {
11008 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_proto=$7 ipv6_len=$8 data=$9
11009 local exp_icmp_code=${10} exp_icmp_chksum=${11}
11010 shift 11
11011
11012 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
11013 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
11014
11015 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
11016 echo $reply >> vif$inport.expected
11017
11018 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11019 }
11020
11021 ip_to_hex() {
11022 printf "%02x%02x%02x%02x" "$@"
11023 }
11024
11025 for i in 1 2; do
11026 net_add n$i
11027 ovn-nbctl ls-add sw$i
11028
11029 sim_add hv$i
11030 as hv$i
11031 ovs-vsctl add-br br-phys
11032 ovn_attach n$i br-phys 192.168.$i.1
11033
11034 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
11035 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
11036
11037 ovs-vsctl -- add-port br-int vif$i -- \
11038 set interface vif$i \
11039 external-ids:iface-id=sw$i-p${i}0 \
11040 options:tx_pcap=hv$i/vif$i-tx.pcap \
11041 options:rxq_pcap=hv$i/vif$i-rx.pcap \
11042 ofport-request=$i
11043 done
11044
11045 ovn-nbctl lr-add lr0
11046 for i in 1 2; do
11047 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
11048 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
11049 -- set Logical_Switch_Port lrp$i-attachment type=router \
11050 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
11051 done
11052
11053 OVN_POPULATE_ARP
11054 # allow some time for ovn-northd and ovn-controller to catch up.
11055 ovn-nbctl --wait=hv sync
11056
11057 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 11 0000 7dae fcfc 0303
11058 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 84 0000 7dae fcfd 0302
11059 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
11060 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
11061
11062 test_tcp_syn_packet 2 2 000000000002 00000000ff02 $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 2 254) 0000 8b40 3039 0000 7bae 4486
11063 test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
11064 test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
11065 OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
11066
11067 OVN_CLEANUP([hv1], [hv2])
11068 AT_CLEANUP
11069
11070 AT_SETUP([ovn -- ovn-controller exit])
11071 AT_SKIP_IF([test $HAVE_PYTHON = no])
11072 ovn_start
11073 # Logical network:
11074 # One Logical Router: ro, with two logical switches sw1 and sw2.
11075 # sw1 is for subnet 10.0.0.0/8
11076 # sw2 is for subnet 20.0.0.0/8
11077 # sw1 has a single port bound on hv1
11078 # sw2 has a single port bound on hv2
11079
11080 ovn-nbctl lr-add ro
11081 ovn-nbctl ls-add sw1
11082 ovn-nbctl ls-add sw2
11083
11084 sw1_ro_mac=00:00:10:00:00:01
11085 sw1_ro_ip=10.0.0.1
11086 sw2_ro_mac=00:00:20:00:00:01
11087 sw2_ro_ip=20.0.0.1
11088 sw1_p1_mac=00:00:10:00:00:02
11089 sw1_p1_ip=10.0.0.2
11090 sw2_p1_mac=00:00:20:00:00:02
11091 sw2_p1_ip=20.0.0.2
11092
11093 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11094 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11095 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11096 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11097 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11098 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11099
11100 ovn-nbctl lsp-add sw1 sw1-p1 \
11101 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11102
11103 ovn-nbctl lsp-add sw2 sw2-p1 \
11104 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11105
11106 net_add n1
11107
11108 sim_add hv1
11109 as hv1
11110 ovs-vsctl add-br br-phys
11111 ovn_attach n1 br-phys 192.168.0.1
11112 ovs-vsctl -- add-port br-int hv1-vif1 -- \
11113 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11114 options:tx_pcap=hv1/vif1-tx.pcap \
11115 options:rxq_pcap=hv1/vif1-rx.pcap \
11116 ofport-request=1
11117
11118 sim_add hv2
11119 as hv2
11120 ovs-vsctl add-br br-phys
11121 ovn_attach n1 br-phys 192.168.0.2
11122 ovs-vsctl -- add-port br-int hv2-vif1 -- \
11123 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11124 options:tx_pcap=hv2/vif1-tx.pcap \
11125 options:rxq_pcap=hv2/vif1-rx.pcap \
11126 ofport-request=1
11127
11128 OVN_POPULATE_ARP
11129
11130 sleep 1
11131
11132 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11133 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11134 udp && udp.src==53 && udp.dst==4369"
11135
11136 # Start by Sending the packet and make sure it makes it there as expected
11137 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11138
11139 # Expected packet has TTL decreased by 1
11140 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11141 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11142 udp && udp.src==53 && udp.dst==4369"
11143 echo $expected | ovstest test-ovn expr-to-packets > expected
11144
11145 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11146
11147 # Stop ovn-controller on hv2
11148 as hv2 ovs-appctl -t ovn-controller exit
11149
11150 # Now send the packet again. This time, it should not arrive.
11151 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11152
11153 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11154
11155 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
11156 as hv2 start_daemon ovn-controller
11157
11158 OVN_CLEANUP([hv1],[hv2])
11159 AT_CLEANUP
11160
11161 AT_SETUP([ovn -- ovn-controller restart])
11162 AT_SKIP_IF([test $HAVE_PYTHON = no])
11163 ovn_start
11164
11165 # Logical network:
11166 # One Logical Router: ro, with two logical switches sw1 and sw2.
11167 # sw1 is for subnet 10.0.0.0/8
11168 # sw2 is for subnet 20.0.0.0/8
11169 # sw1 has a single port bound on hv1
11170 # sw2 has a single port bound on hv2
11171
11172 ovn-nbctl lr-add ro
11173 ovn-nbctl ls-add sw1
11174 ovn-nbctl ls-add sw2
11175
11176 sw1_ro_mac=00:00:10:00:00:01
11177 sw1_ro_ip=10.0.0.1
11178 sw2_ro_mac=00:00:20:00:00:01
11179 sw2_ro_ip=20.0.0.1
11180 sw1_p1_mac=00:00:10:00:00:02
11181 sw1_p1_ip=10.0.0.2
11182 sw2_p1_mac=00:00:20:00:00:02
11183 sw2_p1_ip=20.0.0.2
11184
11185 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11186 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11187 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11188 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11189 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11190 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11191
11192 ovn-nbctl lsp-add sw1 sw1-p1 \
11193 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11194
11195 ovn-nbctl lsp-add sw2 sw2-p1 \
11196 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11197
11198 net_add n1
11199
11200 sim_add hv1
11201 as hv1
11202 ovs-vsctl add-br br-phys
11203 ovn_attach n1 br-phys 192.168.0.1
11204 ovs-vsctl -- add-port br-int hv1-vif1 -- \
11205 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11206 options:tx_pcap=hv1/vif1-tx.pcap \
11207 options:rxq_pcap=hv1/vif1-rx.pcap \
11208 ofport-request=1
11209
11210 sim_add hv2
11211 as hv2
11212 ovs-vsctl add-br br-phys
11213 ovn_attach n1 br-phys 192.168.0.2
11214 ovs-vsctl -- add-port br-int hv2-vif1 -- \
11215 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11216 options:tx_pcap=hv2/vif1-tx.pcap \
11217 options:rxq_pcap=hv2/vif1-rx.pcap \
11218 ofport-request=1
11219
11220 OVN_POPULATE_ARP
11221
11222 sleep 1
11223
11224 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11225 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11226 udp && udp.src==53 && udp.dst==4369"
11227
11228 # Start by Sending the packet and make sure it makes it there as expected
11229 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11230
11231 # Expected packet has TTL decreased by 1
11232 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11233 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11234 udp && udp.src==53 && udp.dst==4369"
11235 echo $expected | ovstest test-ovn expr-to-packets > expected
11236
11237 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11238
11239 # Stop ovn-controller on hv2 with --restart flag
11240 as hv2 ovs-appctl -t ovn-controller exit --restart
11241
11242 # Now send the packet again. This time, it should still arrive
11243 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11244
11245 cat expected expected > expected2
11246
11247 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
11248
11249 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
11250 as hv2 start_daemon ovn-controller
11251
11252 OVN_CLEANUP([hv1],[hv2])
11253
11254 AT_CLEANUP
11255
11256 AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
11257 ovn_start
11258
11259 # Set up a switch with some switch ports of varying address types
11260 ovn-nbctl ls-add sw1
11261 ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
11262
11263 ovn-nbctl lsp-add sw1 sw1-p1
11264 ovn-nbctl lsp-add sw1 sw1-p2
11265 ovn-nbctl lsp-add sw1 sw1-p3
11266 ovn-nbctl lsp-add sw1 sw1-p4
11267
11268 ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1" "00:00:00:00:00:02 10.0.0.2 aef0::2"
11269 ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
11270 ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
11271 ovn-nbctl lsp-set-addresses sw1-p4 "router"
11272 ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
11273
11274 ovn-nbctl list logical_switch_port
11275
11276 # Now try to add duplicate addresses on a new port. These should all fail
11277 ovn-nbctl lsp-add sw1 sw1-p5
11278 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
11279 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
11280 ])
11281 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
11282 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
11283 ])
11284 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
11285 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
11286 ])
11287 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
11288 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
11289 ])
11290 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
11291 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
11292 ])
11293 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
11294 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
11295 ])
11296
11297 # Now try re-setting sw1-p1. This should succeed
11298 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
11299
11300 # Now create a new switch and try setting IP addresses the same as the
11301 # first switch. This should succeed.
11302 ovn-nbctl ls-add sw2
11303 ovn-nbctl lsp-add sw2 sw2-p1
11304
11305 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
11306 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
11307 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
11308 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
11309
11310 AT_CLEANUP
11311
11312 AT_SETUP([ovn -- IP packet buffering])
11313 AT_KEYWORDS([ip-buffering])
11314 AT_SKIP_IF([test $HAVE_PYTHON = no])
11315 ovn_start
11316
11317 # Logical network:
11318 # One LR lr0 that has switches sw0 (192.168.1.0/24) and
11319 # sw1 (172.16.1.0/24) connected to it.
11320 #
11321 # Physical network:
11322 # Tw0 hypervisors hv[12].
11323 # hv1 hosts vif sw0-p0.
11324 # hv1 hosts vif sw1-p0.
11325
11326 send_icmp_packet() {
11327 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
11328 shift 8
11329
11330 local ip_ttl=ff
11331 local ip_len=001c
11332 local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
11333 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
11334 }
11335
11336 send_icmp6_packet() {
11337 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
11338 shift 8
11339
11340 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
11341 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
11342
11343 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
11344 }
11345
11346 get_arp_req() {
11347 local eth_src=$1 spa=$2 tpa=$3
11348 local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
11349 echo $request
11350 }
11351
11352 send_arp_reply() {
11353 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
11354 local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
11355 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
11356 }
11357
11358 send_na() {
11359 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
11360 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
11361 local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
11362
11363 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
11364 }
11365
11366 get_nd() {
11367 local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
11368 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
11369 request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
11370
11371 echo $request
11372 }
11373
11374 net_add n1
11375
11376 sim_add hv1
11377 as hv1
11378 ovs-vsctl add-br br-phys
11379 ovn_attach n1 br-phys 192.168.0.1
11380 ovs-vsctl -- add-port br-int hv1-vif1 -- \
11381 set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
11382 options:tx_pcap=hv1/vif1-tx.pcap \
11383 options:rxq_pcap=hv1/vif1-rx.pcap \
11384 ofport-request=1
11385
11386 sim_add hv2
11387 as hv2
11388 ovs-vsctl add-br br-phys
11389 ovn_attach n1 br-phys 192.168.0.2
11390 ovs-vsctl -- add-port br-int hv2-vif1 -- \
11391 set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
11392 options:tx_pcap=hv2/vif1-tx.pcap \
11393 options:rxq_pcap=hv2/vif1-rx.pcap \
11394 ofport-request=1
11395
11396 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
11397 ovn-nbctl ls-add sw0
11398 ovn-nbctl ls-add sw1
11399
11400 ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001::1/64
11401 ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
11402 type=router options:router-port=sw0 \
11403 -- lsp-set-addresses rp-sw0 router
11404
11405 ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002::1/64
11406 ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
11407 type=router options:router-port=sw1 \
11408 -- lsp-set-addresses rp-sw1 router
11409
11410 ovn-nbctl lsp-add sw0 sw0-p0 \
11411 -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
11412
11413 ovn-nbctl lsp-add sw1 sw1-p0 \
11414 -- lsp-set-addresses sw1-p0 unknown
11415
11416 OVN_POPULATE_ARP
11417 ovn-nbctl --wait=hv sync
11418
11419 ip_to_hex() {
11420 printf "%02x%02x%02x%02x" "$@"
11421 }
11422
11423 src_mac=f00000010203
11424 src_ip=$(ip_to_hex 192 168 1 2)
11425 src_ip6=20010000000000000000000000000002
11426
11427 router_mac0=000001010203
11428 router_mac1=000002010203
11429 router_ip=$(ip_to_hex 172 16 1 1)
11430 router_ip6=20020000000000000000000000000001
11431
11432 dst_mac=001122334455
11433 dst_ip=$(ip_to_hex 172 16 1 10)
11434 dst_ip6=20020000000000000000000000000010
11435
11436 data=0800bee4391a0001
11437
11438 send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
11439 send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
11440 echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
11441 echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
11442
11443 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11444
11445 nd_ip=ff0200000000000000000001ff000010
11446 ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
11447
11448 send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
11449 echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
11450 echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
11451 send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
11452
11453 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11454
11455 OVN_CLEANUP([hv1],[hv2])
11456 AT_CLEANUP