]> git.proxmox.com Git - mirror_ovs.git/blob - tests/ovn.at
checkpatch: Check FOR_EACH loops with numbers.
[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_name="ovn.org",wpad="https://example.org",bootfile_name="https://127.0.0.1/boot.ipxe",path_prefix="/tftpboot");
1108 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain_name = "ovn.org", wpad = "https://example.org", bootfile_name = "https://127.0.0.1/boot.ipxe", path_prefix = "/tftpboot");
1109 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.43.1b.68.74.74.70.73.3a.2f.2f.31.32.37.2e.30.2e.30.2e.31.2f.62.6f.6f.74.2e.69.70.78.65.d2.09.2f.74.66.74.70.62.6f.6f.74,pause)
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,tftp_server_address={10.0.0.4,10.0.0.5});
1111 formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, ethernet_encap = 1, router_discovery = 0, tftp_server_address = {10.0.0.4, 10.0.0.5});
1112 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00.96.08.0a.00.00.04.0a.00.00.05,pause)
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_name=1.2.3.4);
1129 DHCPv4 option domain_name 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 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.aa.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
1264 has prereqs ip6
1265 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);
1266 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.aa.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
1267 has prereqs ip6
1268 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1269 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1270 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1271 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1272 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1273 Syntax error at `dhcpv6_stateless' expecting constant.
1274 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1275 Invalid value for "prefix" option
1276 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1277 Invalid value for "addr_mode" option
1278 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1279 IPv6 ND RA option mtu requires numeric value.
1280 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1281 Invalid value for "mtu" option
1282
1283 # icmp4
1284 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1285 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1286 has prereqs ip4
1287
1288 icmp4 { };
1289 formats as icmp4 { drop; };
1290 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1291 has prereqs ip4
1292
1293 # icmp4 with icmp4.frag_mtu
1294 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
1295 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1296 has prereqs ip4
1297
1298 # icmp4_error
1299 icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1300 encodes as controller(userdata=00.00.00.0e.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1301 has prereqs ip4
1302
1303 icmp4_error { };
1304 formats as icmp4_error { drop; };
1305 encodes as controller(userdata=00.00.00.0e.00.00.00.00)
1306 has prereqs ip4
1307
1308 # icmp4_error with icmp4.frag_mtu
1309 icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
1310 encodes as controller(userdata=00.00.00.0e.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1311 has prereqs ip4
1312
1313 icmp4.frag_mtu = 1500;
1314 encodes as controller(userdata=00.00.00.0d.00.00.00.00.05.dc,pause)
1315
1316 # icmp6
1317 icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1318 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1319 has prereqs ip6
1320
1321 icmp6 { };
1322 formats as icmp6 { drop; };
1323 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1324 has prereqs ip6
1325
1326 # tcp_reset
1327 tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1328 encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1329 has prereqs tcp
1330
1331 tcp_reset { };
1332 formats as tcp_reset { drop; };
1333 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1334 has prereqs tcp
1335
1336 # Contradictionary prerequisites (allowed but not useful):
1337 ip4.src = ip6.src[0..31];
1338 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1339 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1340 ip4.src <-> ip6.src[0..31];
1341 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[]
1342 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1343
1344 # check_pkt_larger
1345 reg0[0] = check_pkt_larger(1500);
1346 encodes as check_pkt_larger(1500)->NXM_NX_XXREG0[96]
1347
1348 reg0 = check_pkt_larger(1500);
1349 Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
1350
1351 reg0 = check_pkt_larger(foo);
1352 Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
1353
1354 reg0[0] = check_pkt_larger(foo);
1355 Syntax error at `foo' expecting `;'.
1356
1357 # Miscellaneous negative tests.
1358 ;
1359 Syntax error at `;'.
1360 xyzzy;
1361 Syntax error at `xyzzy' expecting action.
1362 next; 123;
1363 Syntax error at `123'.
1364 next; xyzzy;
1365 Syntax error at `xyzzy' expecting action.
1366 next
1367 Syntax error at end of input expecting `;'.
1368 ]])
1369 sed '/^[[ ]]/d' test-cases.txt > input.txt
1370 cp test-cases.txt expout
1371 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1372 AT_CLEANUP
1373
1374 AT_BANNER([OVN end-to-end tests])
1375
1376 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1377 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1378 AT_KEYWORDS([ovnarp])
1379 AT_SKIP_IF([test $HAVE_PYTHON = no])
1380 ovn_start
1381
1382 # Create hypervisors hv[123].
1383 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1384 # Add all of the vifs to a single logical switch lsw0.
1385 # Turn on port security on all the vifs except vif[123]1.
1386 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1387 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1388 ovn-nbctl ls-add lsw0
1389 net_add n1
1390 for i in 1 2 3; do
1391 sim_add hv$i
1392 as hv$i
1393 ovs-vsctl add-br br-phys
1394 ovn_attach n1 br-phys 192.168.0.$i
1395
1396 for j in 1 2 3; do
1397 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
1398 ovn-nbctl lsp-add lsw0 lp$i$j
1399 if test $j = 1; then
1400 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1401 else
1402 if test $j = 3; then
1403 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1404 else
1405 ip_addrs="192.168.0.$i$j"
1406 fi
1407 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1408 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1409 fi
1410 done
1411 done
1412 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1413 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1414 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1415 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\"
1416 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1417
1418 get_lsp_uuid () {
1419 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1420 }
1421
1422 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1423 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1424
1425 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1426 # packets for ARP resolution (native tunneling doesn't queue packets
1427 # for ARP resolution).
1428 OVN_POPULATE_ARP
1429
1430 # Allow some time for ovn-northd and ovn-controller to catch up.
1431 # XXX This should be more systematic.
1432 sleep 1
1433
1434 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1435 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1436 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1437 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1438
1439 # Given the name of a logical port, prints the name of the hypervisor
1440 # on which it is located.
1441 vif_to_hv() {
1442 echo hv${1%?}
1443 }
1444
1445 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1446 #
1447 # This shell function causes a packet to be received on INPORT. The packet's
1448 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1449 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1450 # more) list the VIFs on which the packet should be received. INPORT and the
1451 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1452 for i in 1 2 3; do
1453 for j in 1 2 3; do
1454 : > $i$j.expected
1455 done
1456 done
1457 test_packet() {
1458 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1459 hv=`vif_to_hv $inport`
1460 vif=vif$inport
1461 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1462 for outport; do
1463 echo $packet >> $outport.expected
1464 done
1465 }
1466
1467 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1468 #
1469 # Causes a packet to be received on INPORT. The packet is an ARP
1470 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1471 # it should be the hardware address of the target to expect to receive in an
1472 # ARP reply; otherwise no reply is expected.
1473 #
1474 # INPORT is an logical switch port number, e.g. 11 for vif11.
1475 # SHA and REPLY_HA are each 12 hex digits.
1476 # SPA and TPA are each 8 hex digits.
1477 test_arp() {
1478 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1479 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1480 hv=`vif_to_hv $inport`
1481 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1482
1483 if test X$reply_ha = X; then
1484 # Expect to receive the broadcast ARP on the other logical switch ports
1485 # if no reply is expected.
1486 local i j
1487 for i in 1 2 3; do
1488 for j in 1 2 3; do
1489 if test $i$j != $inport; then
1490 echo $request >> $i$j.expected
1491 fi
1492 done
1493 done
1494 else
1495 # Expect to receive the reply, if any.
1496 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1497 echo $reply >> $inport.expected
1498 fi
1499 }
1500
1501 ip_to_hex() {
1502 printf "%02x%02x%02x%02x" "$@"
1503 }
1504
1505 # Send packets between all pairs of source and destination ports:
1506 #
1507 # 1. Unicast packets are delivered to exactly one logical switch port
1508 # (except that packets destined to their input ports are dropped).
1509 #
1510 # 2. Broadcast and multicast are delivered to all logical switch ports
1511 # except the input port.
1512 #
1513 # 3. When port security is turned on, the switch drops packets from the wrong
1514 # MAC address.
1515 #
1516 # 4. The switch drops all packets with a VLAN tag.
1517 #
1518 # 5. The switch drops all packets with a multicast source address. (This only
1519 # affects behavior when port security is turned off, since otherwise port
1520 # security would drop the packet anyway.)
1521 #
1522 # 6. The switch delivers packets with an unknown destination to logical
1523 # switch ports with "unknown" among their MAC addresses (and port
1524 # security disabled).
1525 #
1526 # 7. The switch drops unicast packets that violate an ACL.
1527 #
1528 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1529 #
1530 # 9. OVN generates responses to ARP requests for known IPs, except for
1531 # requests from a port for the port's own IP.
1532 #
1533 # 10. No response to ARP requests for unknown IPs.
1534
1535 for is in 1 2 3; do
1536 for js in 1 2 3; do
1537 s=$is$js
1538 bcast=
1539 unknown=
1540 bacl2=
1541 bacl3=
1542 for id in 1 2 3; do
1543 for jd in 1 2 3; do
1544 d=$id$jd
1545
1546 if test $d != $s; then unicast=$d; else unicast=; fi
1547 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1548
1549 if test $d != $s && test $js = 1; then
1550 impersonate=$d
1551 else
1552 impersonate=
1553 fi
1554 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1555
1556 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1557 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1558 if test $d = $s || (test $js = 1 && test $d = 33); then
1559 # Source of 11, 21, or 31 and dest of 33 should be dropped
1560 # due to the 4th ACL that uses address_set(set1).
1561 acl4=
1562 else
1563 acl4=$d
1564 fi
1565 if test $d = $s || test $d = 22 || test $d = 33; then
1566 # dest of 22 and 33 should be dropped
1567 # due to the 5th ACL that uses port_group(pg1).
1568 acl5=
1569 else
1570 acl5=$d
1571 fi
1572 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1573 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1574 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1575 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1576 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
1577
1578 test_packet $s f000000000$d f00000000055 810000091234 #4
1579 test_packet $s f000000000$d 0100000000$s $s$d #5
1580
1581 if test $d != $s && test $jd = 1; then
1582 unknown="$unknown $d"
1583 fi
1584 bcast="$bcast $unicast"
1585 bacl2="$bacl2 $acl2"
1586 bacl3="$bacl3 $acl3"
1587
1588 sip=`ip_to_hex 192 168 0 $is$js`
1589 tip=`ip_to_hex 192 168 0 $id$jd`
1590 tip_unknown=`ip_to_hex 11 11 11 11`
1591 if test $d != $s; then
1592 reply_ha=f000000000$d
1593 else
1594 reply_ha=
1595 fi
1596 test_arp $s f000000000$s $sip $tip $reply_ha #9
1597 test_arp $s f000000000$s $sip $tip_unknown #10
1598
1599 if test $jd = 3; then
1600 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1601 tip=`ip_to_hex 192 169 0 $id$jd`
1602 test_arp $s f000000000$s $sip $tip $reply_ha #9
1603 fi
1604 done
1605 done
1606
1607 # Broadcast and multicast.
1608 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1609 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1610 if test $js = 1; then
1611 bcast_impersonate=$bcast
1612 else
1613 bcast_impersonate=
1614 fi
1615 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1616
1617 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1618
1619 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1620 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1621 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1622 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1623 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1624 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1625 done
1626 done
1627
1628 # set address for lp13 with invalid characters.
1629 # lp13 should be configured with only 192.168.0.13.
1630 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1631
1632 # Allow some time for ovn-northd and ovn-controller to catch up.
1633 # XXX This should be more systematic.
1634 sleep 1
1635
1636 sip=`ip_to_hex 192 168 0 11`
1637 tip=`ip_to_hex 192 168 0 13`
1638 test_arp 11 f00000000011 $sip $tip f00000000013
1639
1640 tip=`ip_to_hex 192 169 0 13`
1641 #arp request for 192.169.0.13 should be flooded
1642 test_arp 11 f00000000011 $sip $tip
1643
1644 # dump information and flows with counters
1645 ovn-sbctl dump-flows -- list multicast_group
1646
1647 echo "------ hv1 dump ------"
1648 as hv1 ovs-vsctl show
1649 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1650
1651 echo "------ hv2 dump ------"
1652 as hv2 ovs-vsctl show
1653 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1654
1655 echo "------ hv3 dump ------"
1656 as hv3 ovs-vsctl show
1657 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1658
1659 # Now check the packets actually received against the ones expected.
1660 for i in 1 2 3; do
1661 for j in 1 2 3; do
1662 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1663 done
1664 done
1665
1666 OVN_CLEANUP([hv1],[hv2],[hv3])
1667
1668 AT_CLEANUP
1669
1670 # 2 hypervisors, one logical switch, 2 logical ports per hypervisor
1671 # logical ports bound to chassis encap-ip.
1672 AT_SETUP([ovn -- 2 HVs, 1 LS, 2 lports/HV])
1673 AT_KEYWORDS([ovnarp])
1674 AT_SKIP_IF([test $HAVE_PYTHON = no])
1675 ovn_start
1676
1677 # Create hypervisors hv[12].
1678 # Add vif1[12] to hv1, vif2[12] to hv2
1679 ovn-nbctl ls-add lsw0
1680 net_add n1
1681 for i in 1 2; do
1682 sim_add hv$i
1683 as hv$i
1684 ovs-vsctl add-br br-phys
1685 ovn_attach n1 br-phys 192.168.0.$i
1686
1687 for j in 1 2; do
1688 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
1689 ovn-nbctl lsp-add lsw0 lp$i$j
1690 ip_addrs="192.168.0.$i$j"
1691 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1692 ovn-nbctl --wait=hv lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1693 done
1694 done
1695
1696 get_lsp_uuid () {
1697 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1698 }
1699
1700 # XXX-Check how to pass lp$i1 in AT_CHECK_UNQUOTED, for now just do it
1701 # explictly
1702
1703 # For Chassis hv1
1704 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp11], [0], [dnl
1705 encap : [[]]
1706 ])
1707 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp12], [0], [dnl
1708 encap : [[]]
1709 ])
1710
1711 # For Chassis hv2
1712 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp21], [0], [dnl
1713 encap : [[]]
1714 ])
1715 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp22], [0], [dnl
1716 encap : [[]]
1717 ])
1718
1719 # Bind the ports to the encap-ip
1720 for i in 1 2; do
1721 for j in 1 2; do
1722 as hv$i
1723 ovs-vsctl set Interface vif$i$j external-ids:encap-ip=192.168.0.$i
1724 done
1725 done
1726
1727 sleep 1
1728
1729 # dump port bindings; since we have vxlan and geneve tunnels, we expect the
1730 # ports to be bound to geneve tunnels.
1731
1732 # For Chassis 1
1733 encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv1 type=geneve ip=192.168.0.1`
1734
1735 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp11], [0], [dnl
1736 encap : ${encap_rec}
1737 ])
1738
1739 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp12], [0], [dnl
1740 encap : ${encap_rec}
1741 ])
1742
1743 # For Chassis 2
1744 encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv2 type=geneve ip=192.168.0.2`
1745
1746 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp21], [0], [dnl
1747 encap : ${encap_rec}
1748 ])
1749
1750 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp22], [0], [dnl
1751 encap : ${encap_rec}
1752 ])
1753
1754 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1755 # packets for ARP resolution (native tunneling doesn't queue packets
1756 # for ARP resolution).
1757 OVN_POPULATE_ARP
1758
1759 # Allow some time for ovn-northd and ovn-controller to catch up.
1760 # XXX This should be more systematic.
1761 sleep 1
1762
1763 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1764 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1765 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1766 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1767
1768 # Given the name of a logical port, prints the name of the hypervisor
1769 # on which it is located.
1770 vif_to_hv() {
1771 echo hv${1%?}
1772 }
1773
1774 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1775 #
1776 # This shell function causes a packet to be received on INPORT. The packet's
1777 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1778 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1779 # more) list the VIFs on which the packet should be received. INPORT and the
1780 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1781 for i in 1 2; do
1782 for j in 1 2; do
1783 : > $i$j.expected
1784 done
1785 done
1786 test_packet() {
1787 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1788 hv=`vif_to_hv $inport`
1789 vif=vif$inport
1790 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1791 for outport; do
1792 echo $packet >> $outport.expected
1793 done
1794 }
1795
1796 ip_to_hex() {
1797 printf "%02x%02x%02x%02x" "$@"
1798 }
1799
1800 # Send packets between all pairs of source and destination ports:
1801 #
1802 # 1. Unicast packets are delivered to exactly one logical switch port
1803 # (except that packets destined to their input ports are dropped).
1804
1805 for is in 1 2; do
1806 for js in 1 2; do
1807 s=$is$js
1808 bcast=
1809 unknown=
1810 bacl2=
1811 bacl3=
1812 for id in 1 2 3; do
1813 for jd in 1 2 3; do
1814 d=$id$jd
1815
1816 if test $d != $s; then unicast=$d; else unicast=; fi
1817 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1818 done
1819 done
1820
1821 done
1822 done
1823
1824 # dump information and flows with counters
1825 ovn-sbctl dump-flows -- list multicast_group
1826
1827 echo "------ hv1 dump ------"
1828 as hv1 ovs-vsctl show
1829 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1830
1831 echo "------ hv2 dump ------"
1832 as hv2 ovs-vsctl show
1833 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1834
1835 echo "------ hv3 dump ------"
1836 as hv3 ovs-vsctl show
1837 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1838
1839 # Now check the packets actually received against the ones expected.
1840 for i in 1 2; do
1841 for j in 1 2; do
1842 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1843 done
1844 done
1845
1846 OVN_CLEANUP([hv1],[hv2])
1847
1848 AT_CLEANUP
1849
1850 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1851 AT_SKIP_IF([test $HAVE_PYTHON = no])
1852 ovn_start
1853
1854 # Create a logical switch and some logical ports.
1855 # Turn on port security on all lports except ls1.
1856 # Make ls1 a destination for unknown MACs.
1857 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1858 ovn-nbctl ls-add lsw0
1859 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1860 for i in 1 2 3; do
1861 ovn-nbctl lsp-add lsw0 lp$i
1862 done
1863 ovn-nbctl --wait=sb sync
1864 for i in 1 2 3; do
1865 ovn-sbctl lsp-bind lp$i hv0
1866 if test $i = 1; then
1867 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1868 else
1869 if test $i = 3; then
1870 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1871 else
1872 ip_addrs="192.168.0.$i"
1873 fi
1874 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1875 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1876 fi
1877 done
1878 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1879 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1880 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1881 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1882 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1883
1884 ovn-nbctl --wait=sb sync
1885 on_exit 'kill `cat ovn-trace.pid`'
1886 ovn-trace --detach --pidfile --no-chdir
1887
1888 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1889 #
1890 # This shell function causes a packet to be received on INPORT. The packet's
1891 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1892 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1893 # more) list the VIFs on which the packet should be received. INPORT and the
1894 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1895 test_packet() {
1896 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1897 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1898 while :; do
1899 case $1 in # (
1900 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1901 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1902 *) break ;;
1903 esac
1904 done
1905 for outport; do
1906 echo "output(\"lp$outport\");"
1907 done > expout
1908
1909 AT_CAPTURE_FILE([trace])
1910 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1911 }
1912
1913 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1914 #
1915 # Causes a packet to be received on INPORT. The packet is an ARP
1916 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1917 # it should be the hardware address of the target to expect to receive in an
1918 # ARP reply; otherwise no reply is expected.
1919 #
1920 # INPORT is an logical switch port number, e.g. 11 for vif11.
1921 # SHA and REPLY_HA are each 12 hex digits.
1922 # SPA and TPA are each 8 hex digits.
1923 test_arp() {
1924 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1925
1926 local request="inport == \"lp$inport\"
1927 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1928 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1929 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1930
1931 if test -z "$reply_ha"; then
1932 reply=
1933 local i
1934 for i in 1 2 3; do
1935 if test $i != $inport; then
1936 reply="${reply}output(\"lp$i\");
1937 "
1938 fi
1939 done
1940 else
1941 reply="\
1942 eth.dst = $sha;
1943 eth.src = $reply_ha;
1944 arp.op = 2;
1945 arp.tha = $sha;
1946 arp.sha = $reply_ha;
1947 arp.tpa = $spa;
1948 arp.spa = $tpa;
1949 output(\"lp$inport\");
1950 "
1951 fi
1952
1953 AT_CAPTURE_FILE([trace])
1954 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1955 }
1956
1957 # Send packets between all pairs of source and destination ports:
1958 #
1959 # 1. Unicast packets are delivered to exactly one logical switch port
1960 # (except that packets destined to their input ports are dropped).
1961 #
1962 # 2. Broadcast and multicast are delivered to all logical switch ports
1963 # except the input port.
1964 #
1965 # 3. When port security is turned on, the switch drops packets from the wrong
1966 # MAC address.
1967 #
1968 # 4. The switch drops all packets with a VLAN tag.
1969 #
1970 # 5. The switch drops all packets with a multicast source address. (This only
1971 # affects behavior when port security is turned off, since otherwise port
1972 # security would drop the packet anyway.)
1973 #
1974 # 6. The switch delivers packets with an unknown destination to logical
1975 # switch ports with "unknown" among their MAC addresses (and port
1976 # security disabled).
1977 #
1978 # 7. The switch drops unicast packets that violate an ACL.
1979 #
1980 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1981 #
1982 # 9. OVN generates responses to ARP requests for known IPs, except for
1983 # requests from a port for the port's own IP.
1984 #
1985 # 10. No response to ARP requests for unknown IPs.
1986
1987 for s in 1 2 3; do
1988 bcast=
1989 unknown=
1990 bacl2=
1991 bacl3=
1992 for d in 1 2 3; do
1993 echo
1994 echo "lp$s -> lp$d"
1995 if test $d != $s; then unicast=$d; else unicast=; fi
1996 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1997
1998 if test $d != $s && test $s = 1; then
1999 impersonate=$d
2000 else
2001 impersonate=
2002 fi
2003 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
2004
2005 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
2006 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
2007 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
2008 # Source of 1 or 2 and dest of 3 should be dropped
2009 # due to the 4th ACL that uses address_set(set1).
2010 acl4=
2011 else
2012 acl4=$d
2013 fi
2014
2015 #7, acl1 to acl4:
2016 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
2017 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
2018 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
2019 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
2020
2021 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
2022 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
2023
2024 if test $d != $s && test $d = 1; then
2025 unknown="$unknown $d"
2026 fi
2027 bcast="$bcast $unicast"
2028 bacl2="$bacl2 $acl2"
2029 bacl3="$bacl3 $acl3"
2030
2031 sip=192.168.0.$s
2032 tip=192.168.0.$d
2033 tip_unknown=11.11.11.11
2034 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
2035 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
2036 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
2037
2038 if test $d = 3; then
2039 # lp3 has an additional ip 192.169.0.[123]3.
2040 tip=192.169.0.$d
2041 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
2042 fi
2043 done
2044
2045 # Broadcast and multicast.
2046 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
2047 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
2048 if test $s = 1; then
2049 bcast_impersonate=$bcast
2050 else
2051 bcast_impersonate=
2052 fi
2053 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
2054
2055 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
2056
2057 #8, acl1 to acl3:
2058 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
2059 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
2060 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
2061
2062 #8, acl1 to acl3:
2063 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
2064 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
2065 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
2066 done
2067
2068 AT_CLEANUP
2069
2070 # 2 hypervisors, 4 logical ports per HV
2071 # 2 locally attached networks (one flat, one vlan tagged over same device)
2072 # 2 ports per HV on each network
2073 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
2074 AT_SKIP_IF([test $HAVE_PYTHON = no])
2075 ovn_start
2076
2077 # In this test cases we create 3 switches, all connected to same
2078 # physical network (through br-phys on each HV). Each switch has
2079 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
2080 # of VIF port name indicates the hypervisor it is bound to, e.g.
2081 # lp23 means VIF 3 on hv2.
2082 #
2083 # Each switch's VLAN tag and their logical switch ports are:
2084 # - ls1:
2085 # - untagged
2086 # - ports: lp11, lp12, lp21, lp22
2087 #
2088 # - ls2:
2089 # - tagged with VLAN 101
2090 # - ports: lp13, lp14, lp23, lp24
2091 # - ls3:
2092 # - untagged
2093 # - ports: lp15, lp25
2094 #
2095 # Note: a localnet port is created for each switch to connect to
2096 # physical network.
2097
2098 for i in 1 2 3; do
2099 ls_name=ls$i
2100 ovn-nbctl ls-add $ls_name
2101 ln_port_name=ln$i
2102 if test $i -eq 2; then
2103 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
2104 else
2105 ovn-nbctl lsp-add $ls_name $ln_port_name
2106 fi
2107 ovn-nbctl lsp-set-addresses $ln_port_name unknown
2108 ovn-nbctl lsp-set-type $ln_port_name localnet
2109 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
2110 done
2111
2112 # lsp_to_ls LSP
2113 #
2114 # Prints the name of the logical switch that contains LSP.
2115 lsp_to_ls () {
2116 case $1 in dnl (
2117 lp?[[12]]) echo ls1 ;; dnl (
2118 lp?[[34]]) echo ls2 ;; dnl (
2119 lp?5) echo ls3 ;; dnl (
2120 *) AT_FAIL_IF([:]) ;;
2121 esac
2122 }
2123
2124 net_add n1
2125 for i in 1 2; do
2126 sim_add hv$i
2127 as hv$i
2128 ovs-vsctl add-br br-phys
2129 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
2130 ovn_attach n1 br-phys 192.168.0.$i
2131
2132 for j in 1 2 3 4 5; do
2133 ovs-vsctl add-port br-int vif$i$j -- \
2134 set Interface vif$i$j external-ids:iface-id=lp$i$j \
2135 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
2136 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
2137 ofport-request=$i$j
2138
2139 lsp_name=lp$i$j
2140 ls_name=$(lsp_to_ls $lsp_name)
2141
2142 ovn-nbctl lsp-add $ls_name $lsp_name
2143 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
2144 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
2145
2146 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
2147 done
2148 done
2149 ovn-nbctl --wait=sb sync
2150 ovn-sbctl dump-flows
2151
2152 OVN_POPULATE_ARP
2153
2154 # XXX This is now the 3rd copy of these functions in this file ...
2155
2156 # Given the name of a logical port, prints the name of the hypervisor
2157 # on which it is located.
2158 vif_to_hv() {
2159 echo hv${1%?}
2160 }
2161 #
2162 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
2163 #
2164 # This shell function causes a packet to be received on INPORT. The packet's
2165 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2166 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
2167 # logical switch port numbers, e.g. 11 for vif11.
2168 #
2169 # EOUT is the end-to-end output port, that is, where the packet will end up
2170 # after possibly bouncing through one or more localnet ports. LOUT is the
2171 # logical output port, which might be a localnet port, as seen by ovn-trace
2172 # (which doesn't know what localnet ports are connected to and therefore can't
2173 # figure out the end-to-end answer).
2174 for i in 1 2; do
2175 for j in 1 2 3 4 5; do
2176 : > $i$j.expected
2177 done
2178 done
2179 test_packet() {
2180 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
2181 echo "$@"
2182
2183 # First try tracing the packet.
2184 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
2185 if test $lout != drop; then
2186 echo "output(\"$lout\");"
2187 fi > expout
2188 AT_CAPTURE_FILE([trace])
2189 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
2190
2191 # Then actually send a packet, for an end-to-end test.
2192 local packet=$(echo $dst$src | sed 's/://g')${eth}
2193 hv=`vif_to_hv $inport`
2194 vif=vif$inport
2195 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2196 if test $eout != drop; then
2197 echo $packet >> ${eout#lp}.expected
2198 fi
2199 }
2200
2201 # lp11 and lp21 are on the same network (phys, untagged)
2202 # and on different hypervisors
2203 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
2204 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
2205
2206 # lp11 and lp12 are on the same network (phys, untagged)
2207 # and on the same hypervisor
2208 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
2209 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
2210
2211 # lp13 and lp23 are on the same network (phys, VLAN 101)
2212 # and on different hypervisors
2213 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
2214 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
2215
2216 # lp13 and lp14 are on the same network (phys, VLAN 101)
2217 # and on the same hypervisor
2218 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
2219 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
2220
2221 # lp11 and lp15 are on the same network (phys, untagged),
2222 # same hypervisor, and on different switches
2223 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2224 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
2225
2226 # lp11 and lp25 are on the same network (phys, untagged),
2227 # different hypervisors, and on different switches
2228 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2229 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
2230
2231 # Ports that should not be able to communicate
2232 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2233 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2234 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2235 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2236 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2237 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2238 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2239 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
2240
2241 # Dump a bunch of info helpful for debugging if there's a failure.
2242
2243 echo "------ OVN dump ------"
2244 ovn-nbctl show
2245 ovn-sbctl show
2246
2247 echo "------ hv1 dump ------"
2248 as hv1 ovs-vsctl show
2249 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2250
2251 echo "------ hv2 dump ------"
2252 as hv2 ovs-vsctl show
2253 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2254
2255 # Now check the packets actually received against the ones expected.
2256 for i in 1 2; do
2257 for j in 1 2 3 4 5; do
2258 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2259 done
2260 done
2261
2262 OVN_CLEANUP([hv1],[hv2])
2263
2264 AT_CLEANUP
2265
2266 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2267 AT_KEYWORDS([vtep])
2268 AT_SKIP_IF([test $HAVE_PYTHON = no])
2269 ovn_start
2270
2271 # Configure the Northbound database
2272 ovn-nbctl ls-add lsw0
2273
2274 ovn-nbctl lsp-add lsw0 lp1
2275 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2276
2277 ovn-nbctl lsp-add lsw0 lp2
2278 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2279
2280 ovn-nbctl lsp-add lsw0 lp-vtep
2281 ovn-nbctl lsp-set-type lp-vtep vtep
2282 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2283 ovn-nbctl lsp-set-addresses lp-vtep unknown
2284
2285 # lpr, lr and lrp1 are used for the ARP request handling test only.
2286 ovn-nbctl lsp-add lsw0 lpr
2287 ovn-nbctl lr-add lr
2288 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2289 ovn-nbctl set Logical_Switch_Port lpr type=router \
2290 options:router-port=lrp1 \
2291 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2292
2293
2294 net_add n1 # Network to connect hv1, hv2, and vtep
2295 net_add n2 # Network to connect vtep and hv3
2296
2297 # Create hypervisor hv1 connected to n1
2298 sim_add hv1
2299 as hv1
2300 ovs-vsctl add-br br-phys
2301 ovn_attach n1 br-phys 192.168.0.1
2302 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
2303
2304 # Create hypervisor hv2 connected to n1
2305 sim_add hv2
2306 as hv2
2307 ovs-vsctl add-br br-phys
2308 ovn_attach n1 br-phys 192.168.0.2
2309 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
2310
2311
2312 # Start the vtep emulator with a leg in both networks
2313 sim_add vtep
2314 as vtep
2315
2316 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2317 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2318
2319 ovs-vsctl add-br br-phys
2320 net_attach n1 br-phys
2321
2322 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2323 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2324 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2325 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2326
2327 ovs-vsctl add-br br-vtep
2328 net_attach n2 br-vtep
2329
2330 vtep-ctl add-ps br-vtep
2331 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2332 vtep-ctl add-ls lsw0
2333
2334 start_daemon ovs-vtep br-vtep
2335 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2336
2337 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
2338
2339 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2340 grep -- source`"])
2341 # It takes more time for the update to be processed by ovs-vtep.
2342 sleep 1
2343
2344 # Add hv3 on the other side of the vtep
2345 sim_add hv3
2346 as hv3
2347 ovs-vsctl add-br br-phys
2348 net_attach n2 br-phys
2349
2350 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
2351
2352 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2353 # packets for ARP resolution (native tunneling doesn't queue packets
2354 # for ARP resolution).
2355 OVN_POPULATE_ARP
2356
2357 # Allow some time for ovn-northd and ovn-controller to catch up.
2358 # XXX This should be more systematic.
2359 sleep 1
2360
2361 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2362 #
2363 # This shell function causes a packet to be received on INPORT. The packet's
2364 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2365 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2366 # more) list the VIFs on which the packet should be received. INPORT and the
2367 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
2368 for i in 1 2 3; do
2369 : > $i.expected
2370 done
2371 test_packet() {
2372 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2373 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2374 hv=hv$inport
2375 vif=vif$inport
2376 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2377 for outport; do
2378 echo $packet >> $outport.expected
2379 done
2380 }
2381
2382 # Send packets between all pairs of source and destination ports:
2383 #
2384 # 1. Unicast packets are delivered to exactly one logical switch port
2385 # (except that packets destined to their input ports are dropped).
2386 #
2387 # 2. Broadcast and multicast are delivered to all logical switch ports
2388 # except the input port.
2389 #
2390 # 3. The switch delivers packets with an unknown destination to logical
2391 # switch ports with "unknown" among their MAC addresses (and port
2392 # security disabled).
2393 for s in 1 2 3; do
2394 bcast=
2395 unknown=
2396 for d in 1 2 3; do
2397 if test $d != $s; then unicast=$d; else unicast=; fi
2398 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2399
2400 # The vtep (vif3) is the only one configured for "unknown"
2401 if test $d != $s && test $d = 3; then
2402 unknown="$unknown $d"
2403 fi
2404 bcast="$bcast $unicast"
2405 done
2406
2407 # Broadcast and multicast.
2408 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2409 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2410
2411 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2412 done
2413
2414 # ARP request should not be responded to by logical switch router
2415 # type arp responder on HV1 and HV2 and should reach directly to
2416 # vif1 and vif2
2417 ip_to_hex() {
2418 printf "%02x%02x%02x%02x" "$@"
2419 }
2420 sha=f00000000003
2421 spa=`ip_to_hex 192 168 1 2`
2422 tpa=`ip_to_hex 192 168 1 1`
2423 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2424 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2425 echo $request >> 1.expected
2426 echo $request >> 2.expected
2427
2428 # dump information with counters
2429 echo "------ OVN dump ------"
2430 ovn-nbctl show
2431 ovn-sbctl show
2432
2433 echo "---------SB dump-----"
2434 ovn-sbctl list datapath_binding
2435 echo "---------------------"
2436 ovn-sbctl list port_binding
2437 echo "---------------------"
2438 ovn-sbctl dump-flows
2439
2440 echo "------ hv1 dump ------"
2441 as hv1 ovs-vsctl show
2442 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2443 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2444
2445 echo "------ hv2 dump ------"
2446 as hv2 ovs-vsctl show
2447 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2448 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2449
2450 echo "------ hv3 dump ------"
2451 as hv3 ovs-vsctl show
2452 # note: hv3 has no logical port bind, thus it should not have br-int
2453 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2454 [ovs-ofctl: br-int is not a bridge or a socket
2455 ])
2456
2457 # Now check the packets actually received against the ones expected.
2458 for i in 1 2 3; do
2459 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2460 done
2461
2462 # Gracefully terminate daemons
2463 OVN_CLEANUP([hv1],[hv2],[vtep])
2464 OVN_CLEANUP_VSWITCH([hv3])
2465
2466 AT_CLEANUP
2467
2468 # Similar test to "hardware GW"
2469 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2470 AT_SKIP_IF([test $HAVE_PYTHON = no])
2471 ovn_start
2472
2473 # Configure the Northbound database
2474 ovn-nbctl ls-add lsw0
2475
2476 ovn-nbctl lsp-add lsw0 lp1
2477 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2478
2479 ovn-nbctl lsp-add lsw0 lp2
2480 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2481
2482 ovn-nbctl lsp-add lsw0 lp-gw
2483 ovn-nbctl lsp-set-type lp-gw l2gateway
2484 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2485 ovn-nbctl lsp-set-addresses lp-gw unknown
2486
2487 net_add n1 # Network to connect hv1, hv2, and gw
2488 net_add n2 # Network to connect gw and hv3
2489
2490 # Create hypervisor hv1 connected to n1
2491 sim_add hv1
2492 as hv1
2493 ovs-vsctl add-br br-phys
2494 ovn_attach n1 br-phys 192.168.0.1
2495 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
2496
2497 # Create hypervisor hv2 connected to n1
2498 sim_add hv2
2499 as hv2
2500 ovs-vsctl add-br br-phys
2501 ovn_attach n1 br-phys 192.168.0.2
2502 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
2503
2504 # Create hypervisor hv_gw connected to n1 and n2
2505 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2506 sim_add hv_gw
2507 as hv_gw
2508 ovs-vsctl add-br br-phys
2509 ovn_attach n1 br-phys 192.168.0.3
2510 ovs-vsctl add-br br-phys2
2511 net_attach n2 br-phys2
2512 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2513
2514 # Add hv3 on the other side of the GW
2515 sim_add hv3
2516 as hv3
2517 ovs-vsctl add-br br-phys
2518 net_attach n2 br-phys
2519 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
2520
2521
2522 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2523 # packets for ARP resolution (native tunneling doesn't queue packets
2524 # for ARP resolution).
2525 OVN_POPULATE_ARP
2526
2527 # Allow some time for ovn-northd and ovn-controller to catch up.
2528 # XXX This should be more systematic.
2529 sleep 1
2530
2531 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2532 #
2533 # This shell function causes a packet to be received on INPORT. The packet's
2534 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2535 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2536 # more) list the VIFs on which the packet should be received. INPORT and the
2537 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2538 for i in 1 2 3; do
2539 : > $i.expected
2540 done
2541 test_packet() {
2542 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2543 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2544 hv=hv$inport
2545 vif=vif$inport
2546 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2547 for outport; do
2548 echo $packet >> $outport.expected
2549 done
2550 }
2551
2552 # Send packets between all pairs of source and destination ports:
2553 #
2554 # 1. Unicast packets are delivered to exactly one lport (except that packets
2555 # destined to their input ports are dropped).
2556 #
2557 # 2. Broadcast and multicast are delivered to all lports except the input port.
2558 #
2559 # 3. The lswitch delivers packets with an unknown destination to lports with
2560 # "unknown" among their MAC addresses (and port security disabled).
2561 for s in 1 2 3 ; do
2562 bcast=
2563 unknown=
2564 for d in 1 2 3 ; do
2565 if test $d != $s; then unicast=$d; else unicast=; fi
2566 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2567
2568 # The vtep (vif3) is the only one configured for "unknown"
2569 if test $d != $s && test $d = 3; then
2570 unknown="$unknown $d"
2571 fi
2572 bcast="$bcast $unicast"
2573 done
2574
2575 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2576 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2577 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2578 done
2579
2580 echo "------ ovn-nbctl show ------"
2581 ovn-nbctl show
2582 echo "------ ovn-sbctl show ------"
2583 ovn-sbctl show
2584
2585 echo "------ hv1 ------"
2586 as hv1 ovs-vsctl show
2587 echo "------ hv1 br-int ------"
2588 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2589 echo "------ hv1 br-phys ------"
2590 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2591
2592 echo "------ hv2 ------"
2593 as hv2 ovs-vsctl show
2594 echo "------ hv2 br-int ------"
2595 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2596 echo "------ hv2 br-phys ------"
2597 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2598
2599 echo "------ hv_gw ------"
2600 as hv_gw ovs-vsctl show
2601 echo "------ hv_gw br-phys ------"
2602 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2603 echo "------ hv_gw br-phys2 ------"
2604 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2605
2606 echo "------ hv3 ------"
2607 as hv3 ovs-vsctl show
2608 echo "------ hv3 br-phys ------"
2609 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2610
2611 # Now check the packets actually received against the ones expected.
2612 for i in 1 2 3; do
2613 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2614 done
2615 AT_CLEANUP
2616
2617 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2618 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2619 AT_SKIP_IF([test $HAVE_PYTHON = no])
2620 ovn_start
2621
2622 # Logical network:
2623 #
2624 # Three logical switches ls1, ls2, ls3.
2625 # One logical router lr0 connected to ls[123],
2626 # with nine subnets, three per logical switch:
2627 #
2628 # lrp11 on ls1 for subnet 192.168.11.0/24
2629 # lrp12 on ls1 for subnet 192.168.12.0/24
2630 # lrp13 on ls1 for subnet 192.168.13.0/24
2631 # ...
2632 # lrp33 on ls3 for subnet 192.168.33.0/24
2633 #
2634 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2635 # digits are the subnet and the last digit distinguishes the VIF.
2636 for i in 1 2 3; do
2637 ovn-nbctl ls-add ls$i
2638 for j in 1 2 3; do
2639 for k in 1 2 3; do
2640 # Add "unknown" to MAC addresses for lp?11, so packets for
2641 # MAC-IP bindings discovered via ARP later have somewhere to go.
2642 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2643
2644 ovn-nbctl \
2645 -- lsp-add ls$i lp$i$j$k \
2646 -- lsp-set-addresses lp$i$j$k \
2647 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
2648 done
2649 done
2650 done
2651
2652 ovn-nbctl lr-add lr0
2653 for i in 1 2 3; do
2654 for j in 1 2 3; do
2655 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2656 ovn-nbctl \
2657 -- lsp-add ls$i lrp$i$j-attachment \
2658 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2659 options:router-port=lrp$i$j \
2660 addresses='"00:00:00:00:ff:'$i$j'"'
2661 done
2662 done
2663
2664 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2665 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2666
2667 # Physical network:
2668 #
2669 # Three hypervisors hv[123].
2670 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2671 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2672 # lp?3[123] all on hv3.
2673
2674
2675 # Given the name of a logical port, prints the name of the hypervisor
2676 # on which it is located.
2677 vif_to_hv() {
2678 case $1 in dnl (
2679 ?11) echo 1 ;; dnl (
2680 ?12 | ?21 | ?22) echo 2 ;; dnl (
2681 ?13 | ?23 | ?3?) echo 3 ;;
2682 esac
2683 }
2684
2685 # Given the name of a logical port, prints the name of its logical router
2686 # port, e.g. "vif_to_lrp 123" yields 12.
2687 vif_to_lrp() {
2688 echo ${1%?}
2689 }
2690
2691 # Given the name of a logical port, prints the name of its logical
2692 # switch, e.g. "vif_to_ls 123" yields 1.
2693 vif_to_ls() {
2694 echo ${1%??}
2695 }
2696
2697 net_add n1
2698 for i in 1 2 3; do
2699 sim_add hv$i
2700 as hv$i
2701 ovs-vsctl add-br br-phys
2702 ovn_attach n1 br-phys 192.168.0.$i
2703 done
2704 for i in 1 2 3; do
2705 for j in 1 2 3; do
2706 for k in 1 2 3; do
2707 hv=`vif_to_hv $i$j$k`
2708 as hv$hv ovs-vsctl \
2709 -- add-port br-int vif$i$j$k \
2710 -- set Interface vif$i$j$k \
2711 external-ids:iface-id=lp$i$j$k \
2712 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2713 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2714 ofport-request=$i$j$k
2715 done
2716 done
2717 done
2718
2719 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2720 # packets for ARP resolution (native tunneling doesn't queue packets
2721 # for ARP resolution).
2722 OVN_POPULATE_ARP
2723
2724 # Allow some time for ovn-northd and ovn-controller to catch up.
2725 # XXX This should be more systematic.
2726 sleep 1
2727
2728 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2729 #
2730 # This shell function causes a packet to be received on INPORT. The packet's
2731 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2732 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2733 # more) list the VIFs on which the packet should be received. INPORT and the
2734 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2735 for i in 1 2 3; do
2736 for j in 1 2 3; do
2737 for k in 1 2 3; do
2738 : > $i$j$k.expected
2739 done
2740 done
2741 done
2742 test_ip() {
2743 # This packet has bad checksums but logical L3 routing doesn't check.
2744 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2745 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2746 shift; shift; shift; shift; shift
2747 hv=hv`vif_to_hv $inport`
2748 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2749 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2750 in_ls=`vif_to_ls $inport`
2751 in_lrp=`vif_to_lrp $inport`
2752 for outport; do
2753 out_ls=`vif_to_ls $outport`
2754 if test $in_ls = $out_ls; then
2755 # Ports on the same logical switch receive exactly the same packet.
2756 echo $packet
2757 else
2758 # Routing decrements TTL and updates source and dest MAC
2759 # (and checksum).
2760 out_lrp=`vif_to_lrp $outport`
2761 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2762 fi >> $outport.expected
2763 done
2764 }
2765
2766 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2767 #
2768 # Causes a packet to be received on INPORT. The packet is an ARP
2769 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2770 # it should be the hardware address of the target to expect to receive in an
2771 # ARP reply; otherwise no reply is expected.
2772 #
2773 # INPORT is an logical switch port number, e.g. 11 for vif11.
2774 # SHA and REPLY_HA are each 12 hex digits.
2775 # SPA and TPA are each 8 hex digits.
2776 test_arp() {
2777 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2778 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2779 hv=hv`vif_to_hv $inport`
2780 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2781 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2782
2783 # Expect to receive the broadcast ARP on the other logical switch ports if
2784 # IP address is not configured to the switch patch port.
2785 local i=`vif_to_ls $inport`
2786 local j k
2787 for j in 1 2 3; do
2788 for k in 1 2 3; do
2789 # 192.168.33.254 is configured to the switch patch port for lrp33,
2790 # so no ARP flooding expected for it.
2791 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2792 echo $request >> $i$j$k.expected
2793 fi
2794 done
2795 done
2796
2797 # Expect to receive the reply, if any.
2798 if test X$reply_ha != X; then
2799 lrp=`vif_to_lrp $inport`
2800 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2801 echo $reply >> $inport.expected
2802 fi
2803 }
2804
2805 as hv1 ovs-vsctl --columns=name,ofport list interface
2806 as hv1 ovn-sbctl list port_binding
2807 as hv1 ovn-sbctl list datapath_binding
2808 as hv1 ovn-sbctl dump-flows
2809 as hv1 ovs-ofctl dump-flows br-int
2810
2811 # Send IP packets between all pairs of source and destination ports:
2812 #
2813 # 1. Unicast IP packets are delivered to exactly one logical switch port
2814 # (except that packets destined to their input ports are dropped).
2815 #
2816 # 2. Broadcast IP packets are delivered to all logical switch ports
2817 # except the input port.
2818 ip_to_hex() {
2819 printf "%02x%02x%02x%02x" "$@"
2820 }
2821 for is in 1 2 3; do
2822 for js in 1 2 3; do
2823 for ks in 1 2 3; do
2824 bcast=
2825 s=$is$js$ks
2826 smac=f00000000$s
2827 sip=`ip_to_hex 192 168 $is$js $ks`
2828 for id in 1 2 3; do
2829 for jd in 1 2 3; do
2830 for kd in 1 2 3; do
2831 d=$id$jd$kd
2832 dip=`ip_to_hex 192 168 $id$jd $kd`
2833 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2834 if test $d != $s; then unicast=$d; else unicast=; fi
2835
2836 test_ip $s $smac $dmac $sip $dip $unicast #1
2837
2838 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2839 done
2840 done
2841 done
2842 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2843 done
2844 done
2845 done
2846
2847 : > mac_bindings.expected
2848
2849 # 3. Send an IP packet from every logical port to every other subnet,
2850 # to an IP address that does not have a static IP-MAC binding.
2851 # This should generate a broadcast ARP request for the destination
2852 # IP address in the destination subnet.
2853 # Moreover generate an ARP reply for each of the IP addresses ARPed
2854 for is in 1 2 3; do
2855 for js in 1 2 3; do
2856 for ks in 1 2 3; do
2857 s=$is$js$ks
2858 smac=f00000000$s
2859 sip=`ip_to_hex 192 168 $is$js $ks`
2860 for id in 1 2 3; do
2861 for jd in 1 2 3; do
2862 if test $is$js = $id$jd; then
2863 continue
2864 fi
2865
2866 # Send the packet.
2867 dmac=00000000ff$is$js
2868 # Calculate a 4th octet for the destination that is
2869 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2870 # that have static MAC bindings, and fits in the range
2871 # 0-255.
2872 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2873 dip=`ip_to_hex 192 168 $id$jd $o4`
2874 test_ip $s $smac $dmac $sip $dip
2875
2876 # Every LP on the destination subnet's lswitch should
2877 # receive the ARP request.
2878 lrmac=00000000ff$id$jd
2879 lrip=`ip_to_hex 192 168 $id$jd 254`
2880 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2881 for jd2 in 1 2 3; do
2882 for kd in 1 2 3; do
2883 echo $arp >> $id$jd2$kd.expected
2884 done
2885 done
2886
2887 hmac=8000000000$o4
2888 rmac=00000000ff$id$jd
2889 echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
2890
2891 host_mac=8000000000$o4
2892 lrmac=00000000ff$id$jd
2893
2894 arp_reply=${lrmac}${host_mac}08060001080006040002${host_mac}${dip}${lrmac}${lrip}
2895
2896 hv=hv`vif_to_hv ${id}${jd}1`
2897 as $hv ovs-appctl netdev-dummy/receive vif${id}${jd}1 $arp_reply
2898
2899 host_ip_pretty=192.168.$id$jd.$o4
2900 host_mac_pretty=80:00:00:00:00:$o4
2901 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2902 done
2903 done
2904 done
2905 done
2906 done
2907
2908 # Test router replies to ARP requests from all source ports:
2909 #
2910 # 4. Router replies to query for its MAC address from port's own IP address.
2911 #
2912 # 5. Router replies to query for its MAC address from any random IP address
2913 # in its subnet.
2914 #
2915 # 6. No reply to query for IP address other than router IP.
2916 #
2917 # 7. No reply to query from another subnet.
2918 for i in 1 2 3; do
2919 for j in 1 2 3; do
2920 for k in 1 2 3; do
2921 smac=f00000000$i$j$k # Source MAC
2922 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2923 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2924 rmac=00000000ff$i$j # Router MAC
2925 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2926 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2927
2928 test_arp $i$j$k $smac $sip $rip $rmac #4
2929 test_arp $i$j$k $smac $otherip $rip $rmac #5
2930 test_arp $i$j$k $smac $sip $otherip #6
2931
2932 # When rip is 192.168.33.254, ARP request from externalip won't be
2933 # filtered, because 192.168.33.254 is configured to switch peer port
2934 # for lrp33.
2935 lrp33_rsp=
2936 if test $i = 3 && test $j = 3; then
2937 lrp33_rsp=$rmac
2938 fi
2939 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2940
2941 # MAC binding should be learned from ARP request.
2942 host_mac_pretty=f0:00:00:00:0$i:$j$k
2943
2944 host_ip_pretty=192.168.$i$j.$k
2945 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2946
2947 # mac_binding is learned and overwritten so only the last one remains.
2948 if test $k = 3; then
2949 # lrp33 will not learn from ARP request, because 192.168.33.254 is
2950 # configured to switch peer port for lrp33.
2951 if test $i != 3 || test $j != 3; then
2952 host_ip_pretty=192.168.$i$j.55
2953 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2954 fi
2955 fi
2956
2957 done
2958 done
2959 done
2960
2961
2962 # Allow some time for packet forwarding.
2963 # XXX This can be improved.
2964 sleep 1
2965
2966 # 8. Send an IP packet from every logical port to every other subnet. These
2967 # are the same packets already sent as #3, but now the destinations' IP-MAC
2968 # bindings have been discovered via ARP, so instead of provoking an ARP
2969 # request, these packets now get routed to their destinations (which don't
2970 # have static MAC bindings, so they go to the port we've designated as
2971 # accepting "unknown" MACs.)
2972 for is in 1 2 3; do
2973 for js in 1 2 3; do
2974 for ks in 1 2 3; do
2975 s=$is$js$ks
2976 smac=f00000000$s
2977 sip=`ip_to_hex 192 168 $is$js $ks`
2978 for id in 1 2 3; do
2979 for jd in 1 2 3; do
2980 if test $is$js = $id$jd; then
2981 continue
2982 fi
2983
2984 # Send the packet.
2985 dmac=00000000ff$is$js
2986 # Calculate a 4th octet for the destination that is
2987 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2988 # that have static MAC bindings, and fits in the range
2989 # 0-255.
2990 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2991 dip=`ip_to_hex 192 168 $id$jd $o4`
2992 test_ip $s $smac $dmac $sip $dip
2993
2994 # Expect the packet egress.
2995 host_mac=8000000000$o4
2996 outport=${id}11
2997 out_lrp=$id$jd
2998 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2999 done
3000 done
3001 done
3002 done
3003 done
3004
3005 ovn-sbctl -f csv -d bare --no-heading \
3006 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
3007
3008 # Now check the packets actually received against the ones expected.
3009 for i in 1 2 3; do
3010 for j in 1 2 3; do
3011 for k in 1 2 3; do
3012 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
3013 [$i$j$k.expected])
3014 done
3015 done
3016 done
3017
3018 # Check the MAC bindings against those expected.
3019 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
3020 ])
3021
3022 # Gracefully terminate daemons
3023 OVN_CLEANUP([hv1], [hv2], [hv3])
3024
3025 AT_CLEANUP
3026
3027 AT_SETUP([ovn -- IP relocation using GARP request])
3028 AT_SKIP_IF([test $HAVE_PYTHON = no])
3029 ovn_start
3030
3031 # Logical network:
3032 #
3033 # Two logical switches ls1, ls2.
3034 # One logical router lr0 connected to ls[12],
3035 # with 2 subnets, 1 per logical switch:
3036 #
3037 # lrp1 on ls1 for subnet 192.168.1.1/24
3038 # lrp2 on ls2 for subnet 192.168.2.1/24
3039 #
3040 # 4 VIFs, 2 per LS lp[12][12], first digit being LS.
3041 # VIFs' fixed IP addresses are 192.168.[12].1[12].
3042 #
3043 # There is a secondary IP 192.168.1.100 that is unknown in NB and learned
3044 # through ARP only, and it can move between lp11 and lp12.
3045 #
3046 ovn-nbctl lr-add lr0
3047 for i in 1 2 ; do
3048 ovn-nbctl ls-add ls$i
3049 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
3050 ovn-nbctl \
3051 -- lsp-add ls$i lrp$i-attachment \
3052 -- set Logical_Switch_Port lrp$i-attachment type=router \
3053 options:router-port=lrp$i \
3054 addresses=router
3055 for j in 1 2; do
3056 ovn-nbctl \
3057 -- lsp-add ls$i lp$i$j \
3058 -- lsp-set-addresses lp$i$j \
3059 "f0:00:00:00:00:$i$j 192.168.$i.1$j"
3060 done
3061 done
3062
3063 # Physical network:
3064 # 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
3065
3066 # Given the name of a logical port, prints the name of the hypervisor
3067 # on which it is located, e.g. "vif_to_hv 12" yields 2.
3068 vif_to_hv() {
3069 echo ${1#?}
3070 }
3071
3072 # Given the name of a logical port, prints the name of its logical router
3073 # port, e.g. "vif_to_lrp 12" yields 1.
3074 vif_to_lrp() {
3075 echo ${1%?}
3076 }
3077
3078 # Given the name of a logical port, prints the name of its logical
3079 # switch, e.g. "vif_to_ls 12" yields 1.
3080 vif_to_ls() {
3081 echo ${1%?}
3082 }
3083
3084 net_add n1
3085 for i in 1 2; do
3086 sim_add hv$i
3087 as hv$i
3088 ovs-vsctl add-br br-phys
3089 ovn_attach n1 br-phys 192.168.0.$i
3090 done
3091 for i in 1 2; do
3092 for j in 1 2; do
3093 hv=`vif_to_hv $i$j`
3094 as hv$hv ovs-vsctl \
3095 -- add-port br-int vif$i$j \
3096 -- set Interface vif$i$j \
3097 external-ids:iface-id=lp$i$j \
3098 options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
3099 options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
3100 ofport-request=$i$j
3101 done
3102 done
3103
3104 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3105 # packets for ARP resolution (native tunneling doesn't queue packets
3106 # for ARP resolution).
3107 OVN_POPULATE_ARP
3108
3109 # Allow some time for ovn-northd and ovn-controller to catch up.
3110 # XXX This should be more systematic.
3111 sleep 1
3112
3113 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3114 #
3115 # This shell function causes a packet to be received on INPORT. The packet's
3116 # content has Ethernet destination DST and source SRC (each exactly 12 hex
3117 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
3118 # more) list the VIFs on which the packet should be received. INPORT and the
3119 # OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
3120 for i in 1 2; do
3121 for j in 1 2; do
3122 : > $i$j.expected
3123 done
3124 done
3125 test_ip() {
3126 # This packet has bad checksums but logical L3 routing doesn't check.
3127 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3128 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3129 shift; shift; shift; shift; shift
3130 hv=hv`vif_to_hv $inport`
3131 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3132 in_ls=`vif_to_ls $inport`
3133 in_lrp=`vif_to_lrp $inport`
3134 for outport; do
3135 out_ls=`vif_to_ls $outport`
3136 if test $in_ls = $out_ls; then
3137 # Ports on the same logical switch receive exactly the same packet.
3138 echo $packet
3139 else
3140 # Routing decrements TTL and updates source and dest MAC
3141 # (and checksum).
3142 out_lrp=`vif_to_lrp $outport`
3143 echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
3144 fi >> $outport.expected
3145 done
3146 }
3147
3148 # test_arp INPORT SHA SPA TPA [REPLY_HA]
3149 #
3150 # Causes a packet to be received on INPORT. The packet is an ARP
3151 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3152 # it should be the hardware address of the target to expect to receive in an
3153 # ARP reply; otherwise no reply is expected.
3154 #
3155 # INPORT is an logical switch port number, e.g. 11 for vif11.
3156 # SHA and REPLY_HA are each 12 hex digits.
3157 # SPA and TPA are each 8 hex digits.
3158 test_arp() {
3159 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
3160 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3161 hv=hv`vif_to_hv $inport`
3162 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3163
3164 # Expect to receive the broadcast ARP on the other logical switch ports if
3165 # IP address is not configured to the switch patch port.
3166 local i=`vif_to_ls $inport`
3167 local j
3168 for j in 1 2; do
3169 if test $i$j != $inport; then
3170 echo $request >> $i$j$k.expected
3171 fi
3172 done
3173
3174 # Expect to receive the reply, if any.
3175 if test X$reply_ha != X; then
3176 lrp=`vif_to_lrp $inport`
3177 local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3178 echo $reply >> $inport.expected
3179 fi
3180 }
3181
3182 ip_to_hex() {
3183 printf "%02x%02x%02x%02x" "$@"
3184 }
3185
3186 # lp11 send GARP request to announce ownership of 192.168.1.100.
3187
3188 sha=f00000000011
3189 spa=`ip_to_hex 192 168 1 100`
3190 tpa=$spa
3191 test_arp 11 $sha $spa $tpa
3192 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
3193 ovn-nbctl --wait=hv sync
3194
3195 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
3196
3197 smac=f00000000021
3198 dmac=00000000ff02
3199 sip=`ip_to_hex 192 168 2 11`
3200 dip=`ip_to_hex 192 168 1 100`
3201 test_ip 21 $smac $dmac $sip $dip 11
3202
3203 # lp12 send GARP request to announce ownership of 192.168.1.100.
3204
3205 sha=f00000000012
3206 test_arp 12 $sha $spa $tpa
3207 OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
3208 ovn-nbctl --wait=hv sync
3209 # give to the hv the time to send queued ip packets
3210 sleep 1
3211
3212 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
3213
3214 test_ip 21 $smac $dmac $sip $dip 12
3215
3216 # Now check the packets actually received against the ones expected.
3217 for i in 1 2; do
3218 for j in 1 2; do
3219 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
3220 [$i$j.expected])
3221 done
3222 done
3223
3224 # Gracefully terminate daemons
3225 OVN_CLEANUP([hv1], [hv2])
3226
3227 AT_CLEANUP
3228
3229 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
3230 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
3231 AT_SKIP_IF([test $HAVE_PYTHON = no])
3232 ovn_start
3233
3234 # Create hypervisors hv[123].
3235 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
3236 # Add all of the vifs to a single logical switch lsw0.
3237 # Turn off port security on vifs vif[123]1
3238 # Turn on l2 port security on vifs vif[123]2
3239 # Turn of l2 and l3 port security on vifs vif[123]3
3240 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
3241 ovn-nbctl ls-add lsw0
3242 net_add n1
3243 for i in 1 2 3; do
3244 sim_add hv$i
3245 as hv$i
3246 ovs-vsctl add-br br-phys
3247 ovn_attach n1 br-phys 192.168.0.$i
3248
3249 for j in 1 2 3; do
3250 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
3251 ovn-nbctl lsp-add lsw0 lp$i$j
3252 if test $j = 1; then
3253 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
3254 elif test $j = 2; then
3255 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
3256 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
3257 else
3258 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
3259 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3260 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3261 fi
3262 done
3263 done
3264
3265 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3266 # packets for ARP resolution (native tunneling doesn't queue packets
3267 # for ARP resolution).
3268 OVN_POPULATE_ARP
3269
3270 # Allow some time for ovn-northd and ovn-controller to catch up.
3271 # XXX This should be more systematic.
3272 sleep 1
3273
3274 # Given the name of a logical port, prints the name of the hypervisor
3275 # on which it is located.
3276 vif_to_hv() {
3277 echo hv${1%?}
3278 }
3279
3280 for i in 1 2 3; do
3281 for j in 1 2 3; do
3282 : > $i$j.expected
3283 done
3284 done
3285
3286 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3287 #
3288 # This shell function causes an ip packet to be received on INPORT.
3289 # The packet's content has Ethernet destination DST and source SRC
3290 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
3291 # The OUTPORTs (zero or more) list the VIFs on which the packet should
3292 # be received. INPORT and the OUTPORTs are specified as logical switch
3293 # port numbers, e.g. 11 for vif11.
3294 test_ip() {
3295 # This packet has bad checksums but logical L3 routing doesn't check.
3296 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3297 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3298 shift; shift; shift; shift; shift
3299 hv=`vif_to_hv $inport`
3300 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3301 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3302 for outport; do
3303 echo $packet >> $outport.expected
3304 done
3305 }
3306
3307 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
3308 #
3309 # Causes a packet to be received on INPORT. The packet is an ARP
3310 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3311 # it should be the hardware address of the target to expect to receive in an
3312 # ARP reply; otherwise no reply is expected.
3313 #
3314 # INPORT is an logical switch port number, e.g. 11 for vif11.
3315 # SHA and REPLY_HA are each 12 hex digits.
3316 # SPA and TPA are each 8 hex digits.
3317 test_arp() {
3318 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
3319 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3320 hv=`vif_to_hv $inport`
3321 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3322 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
3323 if test $drop != 1; then
3324 if test X$reply_ha = X; then
3325 # Expect to receive the broadcast ARP on the other logical switch ports
3326 # if no reply is expected.
3327 local i j
3328 for i in 1 2 3; do
3329 for j in 1 2 3; do
3330 if test $i$j != $inport; then
3331 echo $request >> $i$j.expected
3332 fi
3333 done
3334 done
3335 else
3336 # Expect to receive the reply, if any.
3337 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3338 echo $reply >> $inport.expected
3339 fi
3340 fi
3341 }
3342
3343 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3344 # This function is similar to test_ip() except that it sends
3345 # ipv6 packet
3346 test_ipv6() {
3347 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3348 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
3349 shift; shift; shift; shift; shift
3350 hv=`vif_to_hv $inport`
3351 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3352 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3353 for outport; do
3354 echo $packet >> $outport.expected
3355 done
3356 }
3357
3358 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
3359 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
3360 # of the test packet
3361 test_icmpv6() {
3362 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
3363 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
3364 shift; shift; shift; shift; shift; shift
3365 hv=`vif_to_hv $inport`
3366 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3367 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3368 for outport; do
3369 echo $packet >> $outport.expected
3370 done
3371 }
3372
3373 ip_to_hex() {
3374 printf "%02x%02x%02x%02x" "$@"
3375 }
3376
3377 # no port security
3378 sip=`ip_to_hex 192 168 0 12`
3379 tip=`ip_to_hex 192 168 0 13`
3380 # the arp packet should be allowed even if lp[123]1 is
3381 # not configured with mac f00000000023 and ip 192.168.0.12
3382 for i in 1 2 3; do
3383 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
3384 for j in 1 2 3; do
3385 if test $i != $j; then
3386 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
3387 fi
3388 done
3389 done
3390
3391 # l2 port security
3392 sip=`ip_to_hex 192 168 0 12`
3393 tip=`ip_to_hex 192 168 0 13`
3394
3395 # arp packet should be allowed since lp22 is configured with
3396 # mac f00000000022
3397 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
3398
3399 # arp packet should not be allowed since lp32 is not configured with
3400 # mac f00000000021
3401 test_arp 32 f00000000021 f00000000021 $sip $tip 1
3402
3403 # arp packet with sha set to f00000000021 should not be allowed
3404 # for lp12
3405 test_arp 12 f00000000012 f00000000021 $sip $tip 1
3406
3407 # ip packets should be allowed and received since lp[123]2 do not
3408 # have l3 port security
3409 sip=`ip_to_hex 192 168 0 55`
3410 tip=`ip_to_hex 192 168 0 66`
3411 for i in 1 2 3; do
3412 for j in 1 2 3; do
3413 if test $i != $j; then
3414 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3415 fi
3416 done
3417 done
3418
3419 # ipv6 packets should be received by lp[123]2
3420 # lp[123]1 can send ipv6 traffic as there is no port security
3421 sip=fe800000000000000000000000000000
3422 tip=ff020000000000000000000000000000
3423
3424 for i in 1 2 3; do
3425 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3426 done
3427
3428
3429 # l2 and l3 port security
3430 sip=`ip_to_hex 192 168 0 13`
3431 tip=`ip_to_hex 192 168 0 22`
3432 # arp packet should be allowed since lp13 is configured with
3433 # f00000000013 and 192.168.0.13
3434 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3435
3436 # the arp packet should be dropped because lp23 is not configured
3437 # with mac f00000000022
3438 sip=`ip_to_hex 192 168 0 13`
3439 tip=`ip_to_hex 192 168 0 22`
3440 test_arp 23 f00000000022 f00000000022 $sip $tip 1
3441
3442 # the arp packet should be dropped because lp33 is not configured
3443 # with ip 192.168.0.55
3444 spa=`ip_to_hex 192 168 0 55`
3445 tpa=`ip_to_hex 192 168 0 22`
3446 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3447
3448 # ip packets should not be received by lp[123]3 since
3449 # l3 port security is enabled
3450 sip=`ip_to_hex 192 168 0 55`
3451 tip=`ip_to_hex 192 168 0 66`
3452 for i in 1 2 3; do
3453 for j in 1 2 3; do
3454 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3455 done
3456 done
3457
3458 # ipv6 packets should be dropped for lp[123]3 since
3459 # it is configured with only ipv4 address
3460 sip=fe800000000000000000000000000000
3461 tip=ff020000000000000000000000000000
3462
3463 for i in 1 2 3; do
3464 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3465 done
3466
3467 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3468 # lp[123]1 can send ipv6 traffic as there is no port security
3469 for i in 1 2 3; do
3470 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3471 done
3472
3473 # lp13 has extra port security with mac f0000000113 and ipv6 addr
3474 # fe80::ea2a:eaff:fe28:0012
3475
3476 # ipv4 packet should be dropped for lp13 with mac f0000000113
3477 sip=`ip_to_hex 192 168 0 13`
3478 tip=`ip_to_hex 192 168 0 23`
3479 test_ip 13 f00000000113 f00000000023 $sip $tip
3480
3481 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3482 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
3483 # lp11 can send ipv6 traffic as there is no port security
3484 sip=ee800000000000000000000000000000
3485 for i in 1 2 3; do
3486 tip=fe80000000000000ea2aeafffe2800${i}3
3487 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
3488 done
3489
3490
3491 # ipv6 packet should not be received by lp33 with mac f0000000333
3492 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3493 # configured with fe80::ea2a:eaff:fe28:0033
3494 # lp11 can send ipv6 traffic as there is no port security
3495
3496 sip=ee800000000000000000000000000000
3497 tip=fe80000000000000ea2aeafffe280023
3498 test_ipv6 11 f00000000011 f00000000333 $sip $tip
3499
3500 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3501 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
3502 # and should be dropped for any other ip6.src
3503 # lp21 can receive ipv6 traffic as there is no port security
3504
3505 tip=ee800000000000000000000000000000
3506 for i in 1 2 3; do
3507 sip=fe80000000000000ea2aeafffe2800${i}3
3508 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3509
3510 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
3511 sip=00000000000000000000000000000000
3512 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3513 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3514 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3515 # Traffic to non-multicast traffic should be dropped
3516 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3517 # Traffic of other ICMPv6 types should be dropped
3518 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
3519
3520 # should be dropped
3521 sip=ae80000000000000ea2aeafffe2800aa
3522 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3523 done
3524
3525 # configure lsp13 to send and received IPv4 packets with an address range
3526 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"
3527
3528 sleep 2
3529
3530 sip=`ip_to_hex 10 0 0 13`
3531 tip=`ip_to_hex 192 168 0 22`
3532 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
3533 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3534
3535 sip=`ip_to_hex 10 0 0 14`
3536 tip=`ip_to_hex 192 168 0 23`
3537 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
3538 # with dst ip 192.168.0.23 should be allowed
3539 test_ip 13 f00000000013 f00000000023 $sip $tip 23
3540
3541 sip=`ip_to_hex 192 168 0 33`
3542 tip=`ip_to_hex 10 0 0 15`
3543 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3544 # with dst ip 10.0.0.15 should be received by lsp13
3545 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3546
3547 sip=`ip_to_hex 192 168 0 33`
3548 tip=`ip_to_hex 20 0 0 4`
3549 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3550 # with dst ip 20.0.0.4 should be received by lsp13
3551 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3552
3553 sip=`ip_to_hex 192 168 0 33`
3554 tip=`ip_to_hex 20 0 0 5`
3555 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3556 # with dst ip 20.0.0.5 should not be received by lsp13
3557 test_ip 33 f00000000033 f00000000013 $sip $tip
3558
3559 sip=`ip_to_hex 192 168 0 33`
3560 tip=`ip_to_hex 20 0 0 255`
3561 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3562 # with dst ip 20.0.0.255 should be received by lsp13
3563 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3564
3565 sip=`ip_to_hex 192 168 0 33`
3566 tip=`ip_to_hex 192 168 0 255`
3567 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3568 # with dst ip 192.168.0.255 should not be received by lsp13
3569 test_ip 33 f00000000033 f00000000013 $sip $tip
3570
3571 sip=`ip_to_hex 192 168 0 33`
3572 tip=`ip_to_hex 224 0 0 4`
3573 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3574 # with dst ip 224.0.0.4 should be received by lsp13
3575 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3576
3577 #dump information including flow counters
3578 ovn-nbctl show
3579 ovn-sbctl dump-flows -- list multicast_group
3580
3581 echo "------ hv1 dump ------"
3582 as hv1 ovs-vsctl show
3583 as hv1 ovs-ofctl -O OpenFlow13 show br-int
3584 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3585
3586 echo "------ hv2 dump ------"
3587 as hv2 ovs-vsctl show
3588 as hv2 ovs-ofctl -O OpenFlow13 show br-int
3589 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3590
3591 echo "------ hv3 dump ------"
3592 as hv3 ovs-vsctl show
3593 as hv3 ovs-ofctl -O OpenFlow13 show br-int
3594 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3595
3596 # Now check the packets actually received against the ones expected.
3597 for i in 1 2 3; do
3598 for j in 1 2 3; do
3599 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3600 done
3601 done
3602
3603 OVN_CLEANUP([hv1],[hv2],[hv3])
3604
3605 AT_CLEANUP
3606
3607 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3608 AT_SKIP_IF([test $HAVE_PYTHON = no])
3609 ovn_start
3610
3611 # Logical network:
3612 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3613 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3614 # R2 has ls2 (172.16.1.0/24) connected to it.
3615
3616 ls1_lp1_mac="f0:00:00:01:02:03"
3617 rp_ls1_mac="00:00:00:01:02:03"
3618 rp_ls2_mac="00:00:00:01:02:04"
3619 ls2_lp1_mac="f0:00:00:01:02:04"
3620
3621 ls1_lp1_ip="192.168.1.2"
3622 ls2_lp1_ip="172.16.1.2"
3623
3624 ovn-nbctl lr-add R1
3625 ovn-nbctl lr-add R2
3626
3627 ovn-nbctl ls-add ls1
3628 ovn-nbctl ls-add ls2
3629
3630 # Connect ls1 to R1
3631 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3632
3633 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3634 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3635
3636 # Connect ls2 to R2
3637 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3638
3639 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3640 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3641
3642 # Connect R1 to R2
3643 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3644 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3645
3646 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3647 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3648
3649 # Create logical port ls1-lp1 in ls1
3650 ovn-nbctl lsp-add ls1 ls1-lp1 \
3651 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3652
3653 # Create logical port ls2-lp1 in ls2
3654 ovn-nbctl lsp-add ls2 ls2-lp1 \
3655 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3656
3657 # Create two hypervisor and create OVS ports corresponding to logical ports.
3658 net_add n1
3659
3660 sim_add hv1
3661 as hv1
3662 ovs-vsctl add-br br-phys
3663 ovn_attach n1 br-phys 192.168.0.1
3664 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3665 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3666 options:tx_pcap=hv1/vif1-tx.pcap \
3667 options:rxq_pcap=hv1/vif1-rx.pcap \
3668 ofport-request=1
3669
3670 sim_add hv2
3671 as hv2
3672 ovs-vsctl add-br br-phys
3673 ovn_attach n1 br-phys 192.168.0.2
3674 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3675 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3676 options:tx_pcap=hv2/vif1-tx.pcap \
3677 options:rxq_pcap=hv2/vif1-rx.pcap \
3678 ofport-request=1
3679
3680
3681 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3682 # packets for ARP resolution (native tunneling doesn't queue packets
3683 # for ARP resolution).
3684 OVN_POPULATE_ARP
3685
3686 # Allow some time for ovn-northd and ovn-controller to catch up.
3687 # XXX This should be more systematic.
3688 sleep 1
3689
3690 # Packet to send.
3691 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3692 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3693 udp && udp.src==53 && udp.dst==4369"
3694 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3695
3696
3697 echo "---------NB dump-----"
3698 ovn-nbctl show
3699 echo "---------------------"
3700 ovn-nbctl list logical_router
3701 echo "---------------------"
3702 ovn-nbctl list logical_router_port
3703 echo "---------------------"
3704
3705 echo "---------SB dump-----"
3706 ovn-sbctl list datapath_binding
3707 echo "---------------------"
3708 ovn-sbctl list port_binding
3709 echo "---------------------"
3710
3711 echo "------ hv1 dump ----------"
3712 as hv1 ovs-ofctl show br-int
3713 as hv1 ovs-ofctl dump-flows br-int
3714 echo "------ hv2 dump ----------"
3715 as hv2 ovs-ofctl show br-int
3716 as hv2 ovs-ofctl dump-flows br-int
3717
3718 # Packet to Expect
3719 # The TTL should be decremented by 2.
3720 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3721 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3722 udp && udp.src==53 && udp.dst==4369"
3723 echo $packet | ovstest test-ovn expr-to-packets > expected
3724
3725 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3726
3727 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3728 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3729 ])
3730
3731 # Disable the ls2-lp1 port.
3732 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3733
3734 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3735 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3736 ])
3737
3738 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3739 # Packet to send.
3740 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3741 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3742 udp && udp.src==53 && udp.dst==4369"
3743
3744 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3745 # The 2nd packet sent shound not be received.
3746 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3747
3748 OVN_CLEANUP([hv1],[hv2])
3749
3750 AT_CLEANUP
3751
3752
3753 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3754 AT_KEYWORDS([router-admin-state])
3755 AT_SKIP_IF([test $HAVE_PYTHON = no])
3756 ovn_start
3757
3758 # Logical network:
3759 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3760 # and 172.16.1.0/24) connected to it.
3761
3762 ovn-nbctl lr-add R1
3763
3764 ovn-nbctl ls-add ls1
3765
3766 # Connect ls1 to R1
3767 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3768 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3769 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3770
3771 # Create logical port ls1-lp1 in ls1
3772 ovn-nbctl lsp-add ls1 ls1-lp1 \
3773 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3774
3775 # Create logical port ls1-lp2 in ls1
3776 ovn-nbctl lsp-add ls1 ls1-lp2 \
3777 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3778
3779 # Create one hypervisor and create OVS ports corresponding to logical ports.
3780 net_add n1
3781
3782 sim_add hv1
3783 as hv1
3784 ovs-vsctl add-br br-phys
3785 ovn_attach n1 br-phys 192.168.0.1
3786 ovs-vsctl -- add-port br-int vif1 -- \
3787 set interface vif1 external-ids:iface-id=ls1-lp1 \
3788 options:tx_pcap=hv1/vif1-tx.pcap \
3789 options:rxq_pcap=hv1/vif1-rx.pcap \
3790 ofport-request=1
3791
3792 ovs-vsctl -- add-port br-int vif2 -- \
3793 set interface vif2 external-ids:iface-id=ls1-lp2 \
3794 options:tx_pcap=hv1/vif2-tx.pcap \
3795 options:rxq_pcap=hv1/vif2-rx.pcap \
3796 ofport-request=1
3797
3798
3799 # Allow some time for ovn-northd and ovn-controller to catch up.
3800 # XXX This should be more systematic.
3801 sleep 1
3802
3803 # Send ip packets between the two ports.
3804 ip_to_hex() {
3805 printf "%02x%02x%02x%02x" "$@"
3806 }
3807
3808 # Packet to send.
3809 src_mac="f00000010203"
3810 dst_mac="000000010203"
3811 src_ip=`ip_to_hex 192 168 1 2`
3812 dst_ip=`ip_to_hex 172 16 1 2`
3813 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3814 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3815
3816
3817 echo "---------NB dump-----"
3818 ovn-nbctl show
3819 echo "---------------------"
3820 ovn-nbctl list logical_router
3821 echo "---------------------"
3822 ovn-nbctl list logical_router_port
3823 echo "---------------------"
3824
3825 echo "---------SB dump-----"
3826 ovn-sbctl list datapath_binding
3827 echo "---------------------"
3828 ovn-sbctl list logical_flow
3829 echo "---------------------"
3830
3831 echo "------ hv1 dump ----------"
3832 as hv1 ovs-ofctl dump-flows br-int
3833
3834
3835 #Disable router R1
3836 ovn-nbctl set Logical_Router R1 enabled=false
3837
3838 # Allow some time for ovn-northd and ovn-controller to catch up.
3839 # XXX This should be more systematic.
3840 sleep 1
3841
3842 echo "---------SB dump-----"
3843 ovn-sbctl list datapath_binding
3844 echo "---------------------"
3845 ovn-sbctl list logical_flow
3846 echo "---------------------"
3847
3848 echo "------ hv1 dump ----------"
3849 as hv1 ovs-ofctl dump-flows br-int
3850
3851 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3852
3853 # Packet to Expect
3854 expect_src_mac="000000010203"
3855 expect_dst_mac="f00000010204"
3856 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3857
3858 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3859
3860 OVN_CLEANUP([hv1])
3861
3862 AT_CLEANUP
3863
3864
3865 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3866 AT_KEYWORDS([router-admin-state])
3867 AT_SKIP_IF([test $HAVE_PYTHON = no])
3868 ovn_start
3869
3870 # Logical network:
3871 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3872 # and has switch ls2 (172.16.1.0/24) connected to it.
3873
3874 ovn-nbctl lr-add R1
3875
3876 ovn-nbctl ls-add ls1
3877 ovn-nbctl ls-add ls2
3878
3879 # Connect ls1 to R1
3880 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3881 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3882 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3883
3884 # Connect ls2 to R1
3885 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3886 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3887 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3888
3889 # Create logical port ls1-lp1 in ls1
3890 ovn-nbctl lsp-add ls1 ls1-lp1 \
3891 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3892
3893 # Create logical port ls2-lp1 in ls2
3894 ovn-nbctl lsp-add ls2 ls2-lp1 \
3895 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3896
3897 # Create one hypervisor and create OVS ports corresponding to logical ports.
3898 net_add n1
3899
3900 sim_add hv1
3901 as hv1
3902 ovs-vsctl add-br br-phys
3903 ovn_attach n1 br-phys 192.168.0.1
3904 ovs-vsctl -- add-port br-int vif1 -- \
3905 set interface vif1 external-ids:iface-id=ls1-lp1 \
3906 options:tx_pcap=hv1/vif1-tx.pcap \
3907 options:rxq_pcap=hv1/vif1-rx.pcap \
3908 ofport-request=1
3909
3910 ovs-vsctl -- add-port br-int vif2 -- \
3911 set interface vif2 external-ids:iface-id=ls2-lp1 \
3912 options:tx_pcap=hv1/vif2-tx.pcap \
3913 options:rxq_pcap=hv1/vif2-rx.pcap \
3914 ofport-request=1
3915
3916
3917 # Allow some time for ovn-northd and ovn-controller to catch up.
3918 # XXX This should be more systematic.
3919 sleep 1
3920
3921 # Send ip packets between the two ports.
3922 ip_to_hex() {
3923 printf "%02x%02x%02x%02x" "$@"
3924 }
3925
3926 # Packet to send.
3927 src_mac="f00000010203"
3928 dst_mac="000000010203"
3929 src_ip=`ip_to_hex 192 168 1 2`
3930 dst_ip=`ip_to_hex 172 16 1 2`
3931 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3932 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3933
3934
3935 echo "---------NB dump-----"
3936 ovn-nbctl show
3937 echo "---------------------"
3938 ovn-nbctl list logical_router
3939 echo "---------------------"
3940 ovn-nbctl list logical_router_port
3941 echo "---------------------"
3942
3943 echo "---------SB dump-----"
3944 ovn-sbctl list datapath_binding
3945 echo "---------------------"
3946 ovn-sbctl list logical_flow
3947 echo "---------------------"
3948
3949 echo "------ hv1 dump ----------"
3950 as hv1 ovs-ofctl dump-flows br-int
3951
3952 #Disable router R1
3953 ovn-nbctl set Logical_Router R1 enabled=false
3954
3955 echo "---------SB dump-----"
3956 ovn-sbctl list datapath_binding
3957 echo "---------------------"
3958 ovn-sbctl list logical_flow
3959 echo "---------------------"
3960
3961 echo "------ hv1 dump ----------"
3962 as hv1 ovs-ofctl dump-flows br-int
3963
3964 # Allow some time for the disabling of logical router R1 to propagate.
3965 # XXX This should be more systematic.
3966 sleep 1
3967
3968 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3969
3970 # Packet to Expect
3971 expect_src_mac="000000010204"
3972 expect_dst_mac="f00000010204"
3973 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3974
3975 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3976
3977 OVN_CLEANUP([hv1])
3978
3979 AT_CLEANUP
3980
3981 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3982 AT_SKIP_IF([test $HAVE_PYTHON = no])
3983 ovn_start
3984
3985 # Logical network:
3986 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3987 # network. R1 has switchess foo (192.168.1.0/24)
3988 # connected to it.
3989 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3990
3991 ovn-nbctl lr-add R1
3992 ovn-nbctl lr-add R2
3993
3994 ovn-nbctl ls-add foo
3995 ovn-nbctl ls-add alice
3996 ovn-nbctl ls-add bob
3997
3998 # Connect foo to R1
3999 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
4000 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4001 options:router-port=foo addresses=\"00:00:00:01:02:03\"
4002
4003 # Connect alice to R2
4004 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
4005 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4006 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
4007
4008 # Connect bob to R2
4009 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
4010 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
4011 options:router-port=bob addresses=\"00:00:00:01:02:05\"
4012
4013 # Connect R1 to R2
4014 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
4015 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
4016
4017 #install static routes
4018 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4019 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
4020 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4021
4022 # Create logical port foo1 in foo
4023 ovn-nbctl lsp-add foo foo1 \
4024 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4025
4026 # Create logical port alice1 in alice
4027 ovn-nbctl lsp-add alice alice1 \
4028 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4029
4030 # Create logical port bob1 in bob
4031 ovn-nbctl lsp-add bob bob1 \
4032 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
4033
4034 # Create two hypervisor and create OVS ports corresponding to logical ports.
4035 net_add n1
4036
4037 sim_add hv1
4038 as hv1
4039 ovs-vsctl add-br br-phys
4040 ovn_attach n1 br-phys 192.168.0.1
4041 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4042 set interface hv1-vif1 external-ids:iface-id=foo1 \
4043 options:tx_pcap=hv1/vif1-tx.pcap \
4044 options:rxq_pcap=hv1/vif1-rx.pcap \
4045 ofport-request=1
4046
4047 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4048 set interface hv1-vif2 external-ids:iface-id=alice1 \
4049 options:tx_pcap=hv1/vif2-tx.pcap \
4050 options:rxq_pcap=hv1/vif2-rx.pcap \
4051 ofport-request=2
4052
4053 sim_add hv2
4054 as hv2
4055 ovs-vsctl add-br br-phys
4056 ovn_attach n1 br-phys 192.168.0.2
4057 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4058 set interface hv2-vif1 external-ids:iface-id=bob1 \
4059 options:tx_pcap=hv2/vif1-tx.pcap \
4060 options:rxq_pcap=hv2/vif1-rx.pcap \
4061 ofport-request=1
4062
4063
4064 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4065 # packets for ARP resolution (native tunneling doesn't queue packets
4066 # for ARP resolution).
4067 OVN_POPULATE_ARP
4068
4069 # Allow some time for ovn-northd and ovn-controller to catch up.
4070 # XXX This should be more systematic.
4071 sleep 1
4072
4073 ip_to_hex() {
4074 printf "%02x%02x%02x%02x" "$@"
4075 }
4076
4077 # Send ip packets between foo1 and alice1
4078 src_mac="f00000010203"
4079 dst_mac="000000010203"
4080 src_ip=`ip_to_hex 192 168 1 2`
4081 dst_ip=`ip_to_hex 172 16 1 2`
4082 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4083 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4084
4085 # Send ip packets between foo1 and bob1
4086 src_mac="f00000010203"
4087 dst_mac="000000010203"
4088 src_ip=`ip_to_hex 192 168 1 2`
4089 dst_ip=`ip_to_hex 172 16 2 2`
4090 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4091 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4092
4093 echo "---------NB dump-----"
4094 ovn-nbctl show
4095 echo "---------------------"
4096 ovn-nbctl list logical_router
4097 echo "---------------------"
4098 ovn-nbctl list logical_router_port
4099 echo "---------------------"
4100
4101 echo "---------SB dump-----"
4102 ovn-sbctl list datapath_binding
4103 echo "---------------------"
4104 ovn-sbctl list port_binding
4105 echo "---------------------"
4106
4107 echo "------ hv1 dump ----------"
4108 as hv1 ovs-ofctl dump-flows br-int
4109 echo "------ hv2 dump ----------"
4110 as hv2 ovs-ofctl dump-flows br-int
4111
4112 # Packet to Expect at bob1
4113 src_mac="000000010205"
4114 dst_mac="f00000010205"
4115 src_ip=`ip_to_hex 192 168 1 2`
4116 dst_ip=`ip_to_hex 172 16 2 2`
4117 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4118
4119 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4120
4121 # Packet to Expect at alice1
4122 src_mac="000000010204"
4123 dst_mac="f00000010204"
4124 src_ip=`ip_to_hex 192 168 1 2`
4125 dst_ip=`ip_to_hex 172 16 1 2`
4126 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4127
4128 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4129
4130 OVN_CLEANUP([hv1],[hv2])
4131
4132 AT_CLEANUP
4133
4134 AT_SETUP([ovn -- send gratuitous arp on localnet])
4135 AT_SKIP_IF([test $HAVE_PYTHON = no])
4136 ovn_start
4137 ovn-nbctl ls-add lsw0
4138 net_add n1
4139 sim_add hv
4140 as hv
4141 ovs-vsctl \
4142 -- add-br br-phys \
4143 -- add-br br-eth0
4144
4145 ovn_attach n1 br-phys 192.168.0.1
4146
4147 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
4148 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])
4149
4150 # Create a vif.
4151 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
4152 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
4153 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
4154
4155 # Create a localnet port.
4156 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
4157 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
4158 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
4159 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
4160
4161 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
4162
4163 # Wait for packet to be received.
4164 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4165 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
4166
4167 # Check GARP packet when restart openflow connection.
4168 as hv
4169 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4170
4171 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
4172
4173 as hv
4174 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
4175
4176 # Wait for packet to be received.
4177 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4178 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
4179
4180 # Delete the localnet ports.
4181 AT_CHECK([ovs-vsctl del-port localvif1])
4182 AT_CHECK([ovn-nbctl lsp-del ln_port])
4183
4184 OVN_CLEANUP([hv])
4185
4186 AT_CLEANUP
4187
4188 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
4189 AT_SKIP_IF([test $HAVE_PYTHON = no])
4190 ovn_start
4191
4192 # Logical network:
4193 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
4194 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4195 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
4196 # connected to it.
4197
4198 ovn-nbctl lr-add R1
4199 ovn-nbctl lr-add R2
4200 ovn-nbctl lr-add R3
4201
4202 ovn-nbctl ls-add foo
4203 ovn-nbctl ls-add alice
4204 ovn-nbctl ls-add bob
4205 ovn-nbctl ls-add join
4206
4207 # Connect foo to R1
4208 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4209 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4210 options:router-port=foo addresses=\"00:00:01:01:02:03\"
4211
4212 # Connect alice to R2
4213 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4214 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4215 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4216
4217 # Connect bob to R3
4218 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
4219 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
4220 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
4221
4222 # Connect R1 to join
4223 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4224 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4225 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4226
4227 # Connect R2 to join
4228 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4229 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4230 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4231
4232 # Connect R3 to join
4233 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
4234 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
4235 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
4236
4237 #install static routes
4238 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4239 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
4240
4241 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4242 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
4243
4244 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
4245 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
4246
4247 # Create logical port foo1 in foo
4248 ovn-nbctl lsp-add foo foo1 \
4249 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4250
4251 # Create logical port alice1 in alice
4252 ovn-nbctl lsp-add alice alice1 \
4253 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4254
4255 # Create logical port bob1 in bob
4256 ovn-nbctl lsp-add bob bob1 \
4257 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
4258
4259 # Create two hypervisor and create OVS ports corresponding to logical ports.
4260 net_add n1
4261
4262 sim_add hv1
4263 as hv1
4264 ovs-vsctl add-br br-phys
4265 ovn_attach n1 br-phys 192.168.0.1
4266 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4267 set interface hv1-vif1 external-ids:iface-id=foo1 \
4268 options:tx_pcap=hv1/vif1-tx.pcap \
4269 options:rxq_pcap=hv1/vif1-rx.pcap \
4270 ofport-request=1
4271
4272 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4273 set interface hv1-vif2 external-ids:iface-id=alice1 \
4274 options:tx_pcap=hv1/vif2-tx.pcap \
4275 options:rxq_pcap=hv1/vif2-rx.pcap \
4276 ofport-request=2
4277
4278 sim_add hv2
4279 as hv2
4280 ovs-vsctl add-br br-phys
4281 ovn_attach n1 br-phys 192.168.0.2
4282 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4283 set interface hv2-vif1 external-ids:iface-id=bob1 \
4284 options:tx_pcap=hv2/vif1-tx.pcap \
4285 options:rxq_pcap=hv2/vif1-rx.pcap \
4286 ofport-request=1
4287
4288
4289 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4290 # packets for ARP resolution (native tunneling doesn't queue packets
4291 # for ARP resolution).
4292 OVN_POPULATE_ARP
4293
4294 # Allow some time for ovn-northd and ovn-controller to catch up.
4295 # XXX This should be more systematic.
4296 sleep 1
4297
4298 ip_to_hex() {
4299 printf "%02x%02x%02x%02x" "$@"
4300 }
4301
4302 # Send ip packets between foo1 and alice1
4303 src_mac="f00000010203"
4304 dst_mac="000001010203"
4305 src_ip=`ip_to_hex 192 168 1 2`
4306 dst_ip=`ip_to_hex 172 16 1 2`
4307 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4308 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4309 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4310
4311 # Send ip packets between foo1 and bob1
4312 src_mac="f00000010203"
4313 dst_mac="000001010203"
4314 src_ip=`ip_to_hex 192 168 1 2`
4315 dst_ip=`ip_to_hex 10 32 1 2`
4316 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4317 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4318
4319 echo "---------NB dump-----"
4320 ovn-nbctl show
4321 echo "---------------------"
4322 ovn-nbctl list logical_router
4323 echo "---------------------"
4324 ovn-nbctl list logical_router_port
4325 echo "---------------------"
4326
4327 echo "---------SB dump-----"
4328 ovn-sbctl list datapath_binding
4329 echo "---------------------"
4330 ovn-sbctl list port_binding
4331 echo "---------------------"
4332 ovn-sbctl dump-flows
4333 echo "---------------------"
4334
4335 echo "------ hv1 dump ----------"
4336 as hv1 ovs-ofctl show br-int
4337 as hv1 ovs-ofctl dump-flows br-int
4338 echo "------ hv2 dump ----------"
4339 as hv2 ovs-ofctl show br-int
4340 as hv2 ovs-ofctl dump-flows br-int
4341 echo "----------------------------"
4342
4343 # Packet to Expect at bob1
4344 src_mac="000003010203"
4345 dst_mac="f00000010205"
4346 src_ip=`ip_to_hex 192 168 1 2`
4347 dst_ip=`ip_to_hex 10 32 1 2`
4348 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4349
4350 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4351
4352 # Packet to Expect at alice1
4353 src_mac="000002010203"
4354 dst_mac="f00000010204"
4355 src_ip=`ip_to_hex 192 168 1 2`
4356 dst_ip=`ip_to_hex 172 16 1 2`
4357 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4358
4359 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4360
4361 OVN_CLEANUP([hv1],[hv2])
4362
4363 AT_CLEANUP
4364
4365 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
4366 AT_SKIP_IF([test $HAVE_PYTHON = no])
4367 ovn_start
4368
4369 ovn-nbctl ls-add ls1
4370
4371 ovn-nbctl lsp-add ls1 ls1-lp1 \
4372 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4373
4374 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4375
4376 ovn-nbctl lsp-add ls1 ls1-lp2 \
4377 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4378
4379 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4380
4381 ovn-nbctl ls-add ls2
4382 ovn-nbctl lsp-add ls2 ls2-lp1 \
4383 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4384 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4385 ovn-nbctl lsp-add ls2 ls2-lp2 \
4386 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4387 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4388
4389 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
4390 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
4391 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
4392
4393 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4394 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4395
4396 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
4397 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
4398 \"lease_time\"=\"3600\"")"
4399
4400 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
4401
4402 net_add n1
4403 sim_add hv1
4404
4405 as hv1
4406 ovs-vsctl add-br br-phys
4407 ovn_attach n1 br-phys 192.168.0.1
4408 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4409 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4410 options:tx_pcap=hv1/vif1-tx.pcap \
4411 options:rxq_pcap=hv1/vif1-rx.pcap \
4412 ofport-request=1
4413
4414 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4415 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4416 options:tx_pcap=hv1/vif2-tx.pcap \
4417 options:rxq_pcap=hv1/vif2-rx.pcap \
4418 ofport-request=2
4419
4420 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4421 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4422 options:tx_pcap=hv1/vif3-tx.pcap \
4423 options:rxq_pcap=hv1/vif3-rx.pcap \
4424 ofport-request=3
4425
4426 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4427 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4428 options:tx_pcap=hv1/vif4-tx.pcap \
4429 options:rxq_pcap=hv1/vif4-rx.pcap \
4430 ofport-request=4
4431
4432 OVN_POPULATE_ARP
4433
4434 sleep 2
4435
4436 as hv1 ovs-vsctl show
4437
4438 # This shell function sends a DHCP request packet
4439 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP REQUEST_IP ...
4440 test_dhcp() {
4441 local inport=$1 src_mac=$2 dhcp_type=$3 ciaddr=$4 offer_ip=$5 request_ip=$6 use_ip=$7
4442 shift; shift; shift; shift; shift; shift; shift;
4443 if test $use_ip != 0; then
4444 src_ip=$1
4445 dst_ip=$2
4446 shift; shift;
4447 else
4448 src_ip=`ip_to_hex 0 0 0 0`
4449 dst_ip=`ip_to_hex 255 255 255 255`
4450 fi
4451 if test $request_ip != 0; then
4452 ip_len=0120
4453 udp_len=010b
4454 else
4455 ip_len=011a
4456 udp_len=0106
4457 fi
4458 local request=ffffffffffff${src_mac}08004510${ip_len}0000000080110000${src_ip}${dst_ip}
4459 # udp header and dhcp header
4460 request=${request}00440043${udp_len}0000
4461 request=${request}010106006359aa7600000000${ciaddr}000000000000000000000000${src_mac}
4462 # client hardware padding
4463 request=${request}00000000000000000000
4464 # server hostname
4465 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4466 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4467 # boot file name
4468 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4469 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4470 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4471 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4472 # dhcp magic cookie
4473 request=${request}63825363
4474 # dhcp message type
4475 request=${request}3501${dhcp_type}
4476 # dhcp unknown option
4477 request=${request}d70701020304050607
4478 # dhcp pad option
4479 request=${request}00
4480 if test $request_ip != 0; then
4481 # dhcp requested ip
4482 request=${request}3204${request_ip}
4483 fi
4484 # dhcp end option
4485 request=${request}ff
4486
4487 for port in $inport "$@"; do
4488 : >> $port.expected
4489 done
4490 if test $offer_ip != 0; then
4491 local srv_mac=$1 srv_ip=$2 dhcp_reply_type=$3 expected_dhcp_opts=$4
4492 # total IP length will be the IP length of the request packet
4493 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4494 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4495 udp_len=`expr $ip_len - 20`
4496 ip_len=$(printf "%x" $ip_len)
4497 udp_len=$(printf "%x" $udp_len)
4498 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4499 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4500 # udp header and dhcp header.
4501 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
4502 reply=${reply}004300440${udp_len}0000020106006359aa7600000000${ciaddr}
4503 # your ip address; 0 for NAK
4504 if test $dhcp_reply_type = 06; then
4505 reply=${reply}00000000
4506 else
4507 reply=${reply}${offer_ip}
4508 fi
4509 # next server ip address, relay agent ip address, client mac address
4510 reply=${reply}0000000000000000${src_mac}
4511 # client hardware padding
4512 reply=${reply}00000000000000000000
4513 # server hostname
4514 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4515 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4516 # boot file name
4517 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4518 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4519 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4520 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4521 # dhcp magic cookie
4522 reply=${reply}63825363
4523 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
4524 echo $reply >> $inport.expected
4525 else
4526 for outport; do
4527 echo $request >> $outport.expected
4528 done
4529 fi
4530 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4531 }
4532
4533 reset_pcap_file() {
4534 local iface=$1
4535 local pcap_file=$2
4536 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4537 options:rxq_pcap=dummy-rx.pcap
4538 rm -f ${pcap_file}*.pcap
4539 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4540 options:rxq_pcap=${pcap_file}-rx.pcap
4541 }
4542
4543 ip_to_hex() {
4544 printf "%02x%02x%02x%02x" "$@"
4545 }
4546
4547 AT_CAPTURE_FILE([ofctl_monitor0.log])
4548 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4549 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4550
4551 echo "---------NB dump-----"
4552 ovn-nbctl show
4553 echo "---------------------"
4554 echo "---------SB dump-----"
4555 ovn-sbctl list datapath_binding
4556 echo "---------------------"
4557 ovn-sbctl list logical_flow
4558 echo "---------------------"
4559
4560 echo "---------------------"
4561 ovn-sbctl dump-flows
4562 echo "---------------------"
4563
4564 echo "------ hv1 dump ----------"
4565 as hv1 ovs-ofctl dump-flows br-int
4566
4567 # Send DHCPDISCOVER.
4568 offer_ip=`ip_to_hex 10 0 0 4`
4569 server_ip=`ip_to_hex 10 0 0 1`
4570 ciaddr=`ip_to_hex 0 0 0 0`
4571 request_ip=0
4572 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4573 test_dhcp 1 f00000000001 01 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 02 $expected_dhcp_opts
4574
4575 # NXT_RESUMEs should be 1.
4576 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4577
4578 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4579 cat 1.expected | cut -c -48 > expout
4580 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4581 # Skipping the IPv4 checksum.
4582 cat 1.expected | cut -c 53- > expout
4583 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4584
4585 # ovs-ofctl also resumes the packets and this causes other ports to receive
4586 # the DHCP request packet. So reset the pcap files so that its easier to test.
4587 reset_pcap_file hv1-vif1 hv1/vif1
4588 reset_pcap_file hv1-vif2 hv1/vif2
4589 rm -f 1.expected
4590 rm -f 2.expected
4591
4592 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
4593 # address in the Requested IP Address option.
4594 offer_ip=`ip_to_hex 10 0 0 6`
4595 server_ip=`ip_to_hex 10 0 0 1`
4596 ciaddr=`ip_to_hex 0 0 0 0`
4597 request_ip=$offer_ip
4598 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4599 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
4600
4601 # NXT_RESUMEs should be 2.
4602 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4603
4604 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4605 cat 2.expected | cut -c -48 > expout
4606 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4607 # Skipping the IPv4 checksum.
4608 cat 2.expected | cut -c 53- > expout
4609 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4610
4611 reset_pcap_file hv1-vif1 hv1/vif1
4612 reset_pcap_file hv1-vif2 hv1/vif2
4613 rm -f 1.expected
4614 rm -f 2.expected
4615
4616 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with a mismatched IP in
4617 # the Requested IP Address option, expect a DHCPNAK.
4618 offer_ip=`ip_to_hex 10 0 0 6`
4619 server_ip=`ip_to_hex 10 0 0 1`
4620 ciaddr=`ip_to_hex 0 0 0 0`
4621 request_ip=`ip_to_hex 10 0 0 7`
4622 expected_dhcp_opts=""
4623 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 06 $expected_dhcp_opts
4624
4625 # NXT_RESUMEs should be 3.
4626 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4627
4628 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4629 cat 2.expected | cut -c -48 > expout
4630 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4631 # Skipping the IPv4 checksum.
4632 cat 2.expected | cut -c 53- > expout
4633 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4634
4635 reset_pcap_file hv1-vif1 hv1/vif1
4636 reset_pcap_file hv1-vif2 hv1/vif2
4637 rm -f 1.expected
4638 rm -f 2.expected
4639
4640 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4641 # but should be resumed without the reply.
4642 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4643 # one from ovn-controller and the other from "ovs-ofctl resume."
4644 ciaddr=`ip_to_hex 0 0 0 0`
4645 offer_ip=0
4646 request_ip=0
4647 test_dhcp 2 f00000000002 08 $ciaddr $offer_ip $request_ip 0 1 1
4648
4649 # NXT_RESUMEs should be 4.
4650 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4651
4652 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4653 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4654
4655 reset_pcap_file hv1-vif1 hv1/vif1
4656 reset_pcap_file hv1-vif2 hv1/vif2
4657 rm -f 1.expected
4658 rm -f 2.expected
4659
4660 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4661 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4662
4663 ciaddr=`ip_to_hex 0 0 0 0`
4664 test_dhcp 3 f00000000003 01 $ciaddr 0 0 4 0
4665
4666 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4667 # this lport.
4668 ciaddr=`ip_to_hex 0 0 0 0`
4669 test_dhcp 4 f00000000004 01 $ciaddr 0 0 3 0
4670
4671 # NXT_RESUMEs should be 4.
4672 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4673
4674 #OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4675 #OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4676
4677 # Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4678 # and ip4.dst set to 10.0.0.1.
4679 offer_ip=`ip_to_hex 10 0 0 6`
4680 server_ip=`ip_to_hex 10 0 0 1`
4681 ciaddr=$offer_ip
4682 request_ip=0
4683 src_ip=$offer_ip
4684 dst_ip=$server_ip
4685 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4686 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
4687
4688 # NXT_RESUMEs should be 5.
4689 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4690
4691 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4692 cat 2.expected | cut -c -48 > expout
4693 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4694 # Skipping the IPv4 checksum.
4695 cat 2.expected | cut -c 53- > expout
4696 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4697
4698 reset_pcap_file hv1-vif1 hv1/vif1
4699 reset_pcap_file hv1-vif2 hv1/vif2
4700 rm -f 1.expected
4701 rm -f 2.expected
4702
4703 # Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4704 # and ip4.dst set to 255.255.255.255.
4705 offer_ip=`ip_to_hex 10 0 0 6`
4706 server_ip=`ip_to_hex 10 0 0 1`
4707 ciaddr=$offer_ip
4708 request_ip=0
4709 src_ip=$offer_ip
4710 dst_ip=`ip_to_hex 255 255 255 255`
4711 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4712 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
4713
4714 # NXT_RESUMEs should be 6.
4715 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4716
4717 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4718 cat 2.expected | cut -c -48 > expout
4719 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4720 # Skipping the IPv4 checksum.
4721 cat 2.expected | cut -c 53- > expout
4722 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4723
4724 reset_pcap_file hv1-vif1 hv1/vif1
4725 reset_pcap_file hv1-vif2 hv1/vif2
4726 rm -f 1.expected
4727 rm -f 2.expected
4728
4729 # Send DHCPREQUEST in the RENEWING/REBINDING state with a mismatched IP in the
4730 # ciaddr, expect a DHCPNAK.
4731 offer_ip=`ip_to_hex 10 0 0 6`
4732 server_ip=`ip_to_hex 10 0 0 1`
4733 ciaddr=`ip_to_hex 10 0 0 7`
4734 request_ip=0
4735 src_ip=$offer_ip
4736 dst_ip=`ip_to_hex 255 255 255 255`
4737 expected_dhcp_opts=""
4738 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
4739
4740 # NXT_RESUMEs should be 7.
4741 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4742
4743 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4744 cat 2.expected | cut -c -48 > expout
4745 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4746 # Skipping the IPv4 checksum.
4747 cat 2.expected | cut -c 53- > expout
4748 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4749
4750 reset_pcap_file hv1-vif1 hv1/vif1
4751 reset_pcap_file hv1-vif2 hv1/vif2
4752 rm -f 1.expected
4753 rm -f 2.expected
4754
4755 # Send DHCPREQUEST in the RENEWING/REBINDING state without a specifyied ciaddr,
4756 # expect a DHCPNAK.
4757 offer_ip=`ip_to_hex 10 0 0 6`
4758 server_ip=`ip_to_hex 10 0 0 1`
4759 ciaddr=`ip_to_hex 0 0 0 0`
4760 request_ip=0
4761 src_ip=$offer_ip
4762 dst_ip=`ip_to_hex 255 255 255 255`
4763 expected_dhcp_opts=""
4764 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
4765
4766 # NXT_RESUMEs should be 8.
4767 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4768
4769 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4770 cat 2.expected | cut -c -48 > expout
4771 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4772 # Skipping the IPv4 checksum.
4773 cat 2.expected | cut -c 53- > expout
4774 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4775
4776 reset_pcap_file hv1-vif1 hv1/vif1
4777 reset_pcap_file hv1-vif2 hv1/vif2
4778 rm -f 1.expected
4779 rm -f 2.expected
4780
4781 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4782 # The packet should not be received by ovn-controller.
4783 ciaddr=`ip_to_hex 0 0 0 0`
4784 src_ip=`ip_to_hex 10 0 0 6`
4785 dst_ip=`ip_to_hex 10 0 0 4`
4786 test_dhcp 2 f00000000002 03 $ciaddr 0 0 1 $src_ip $dst_ip 1
4787
4788 # NXT_RESUMEs should be 8.
4789 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4790
4791 # vif1-tx.pcap should have received the DHCPv4 request packet
4792 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4793
4794 OVN_CLEANUP([hv1])
4795
4796 AT_CLEANUP
4797
4798 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4799 AT_SKIP_IF([test $HAVE_PYTHON = no])
4800 ovn_start
4801
4802 ovn-nbctl ls-add ls1
4803 ovn-nbctl lsp-add ls1 ls1-lp1 \
4804 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4805
4806 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4807
4808 ovn-nbctl lsp-add ls1 ls1-lp2 \
4809 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4810
4811 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4812
4813 ovn-nbctl lsp-add ls1 ls1-lp3 \
4814 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4815
4816 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4817
4818 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4819 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4820
4821 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4822 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4823
4824 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4825 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4826
4827 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4828
4829 ovn-nbctl ls-add ls2
4830 ovn-nbctl lsp-add ls2 ls2-lp1 \
4831 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4832 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4833 ovn-nbctl lsp-add ls2 ls2-lp2 \
4834 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4835 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4836
4837 net_add n1
4838 sim_add hv1
4839
4840 as hv1
4841 ovs-vsctl add-br br-phys
4842 ovn_attach n1 br-phys 192.168.0.1
4843 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4844 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4845 options:tx_pcap=hv1/vif1-tx.pcap \
4846 options:rxq_pcap=hv1/vif1-rx.pcap \
4847 ofport-request=1
4848
4849 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4850 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4851 options:tx_pcap=hv1/vif2-tx.pcap \
4852 options:rxq_pcap=hv1/vif2-rx.pcap \
4853 ofport-request=2
4854
4855 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4856 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4857 options:tx_pcap=hv1/vif3-tx.pcap \
4858 options:rxq_pcap=hv1/vif3-rx.pcap \
4859 ofport-request=3
4860
4861 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4862 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4863 options:tx_pcap=hv1/vif4-tx.pcap \
4864 options:rxq_pcap=hv1/vif4-rx.pcap \
4865 ofport-request=4
4866
4867 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4868 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4869 options:tx_pcap=hv1/vif5-tx.pcap \
4870 options:rxq_pcap=hv1/vif5-rx.pcap \
4871 ofport-request=5
4872
4873 OVN_POPULATE_ARP
4874
4875 sleep 2
4876
4877 trim_zeros() {
4878 sed 's/\(00\)\{1,\}$//'
4879 }
4880
4881 # This shell function sends a DHCPv6 request packet
4882 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4883 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4884 # packet should be received twice (one from ovn-controller and the other
4885 # from the "ovs-ofctl monitor br-int resume"
4886 test_dhcpv6() {
4887 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4888 if test $msg_code != 0b; then
4889 req_len=2a
4890 else
4891 req_len=1a
4892 fi
4893 local request=ffffffffffff${src_mac}86dd0000000000${req_len}1101${src_lla}
4894 # dst ip ff02::1:2
4895 request=${request}ff020000000000000000000000010002
4896 # udp header and dhcpv6 header
4897 request=${request}0222022300${req_len}ffff${msg_code}010203
4898 # Client identifier
4899 request=${request}0001000a00030001${src_mac}
4900 # Add IA-NA (Identity Association for Non Temporary Address) if msg_code
4901 # is not 11 (information request packet)
4902 if test $msg_code != 0b; then
4903 request=${request}0003000c0102030400000e1000001518
4904 fi
4905 shift; shift; shift; shift; shift;
4906 if test $offer_ip != 0; then
4907 local server_mac=000000100001
4908 local server_lla=fe80000000000000020000fffe100001
4909 local reply_code=07
4910 if test $msg_code = 01; then
4911 reply_code=02
4912 fi
4913 local msg_len=54
4914 if test $offer_ip = 1; then
4915 msg_len=28
4916 fi
4917 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4918 # udp header and dhcpv6 header
4919 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4920 # Client identifier
4921 reply=${reply}0001000a00030001${src_mac}
4922 # IA-NA
4923 if test $offer_ip != 1; then
4924 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4925 fi
4926 # Server identifier
4927 reply=${reply}0002000a00030001${server_mac}
4928 echo $reply | trim_zeros >> $inport.expected
4929 else
4930 for outport; do
4931 echo $request | trim_zeros >> $outport.expected
4932 done
4933 fi
4934
4935 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4936 }
4937
4938 reset_pcap_file() {
4939 local iface=$1
4940 local pcap_file=$2
4941 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4942 options:rxq_pcap=dummy-rx.pcap
4943 rm -f ${pcap_file}*.pcap
4944 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4945 options:rxq_pcap=${pcap_file}-rx.pcap
4946 }
4947
4948 AT_CAPTURE_FILE([ofctl_monitor0.log])
4949 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4950 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4951
4952 echo "---------NB dump-----"
4953 ovn-nbctl show
4954 echo "---------------------"
4955 echo "---------SB dump-----"
4956 ovn-sbctl list datapath_binding
4957 echo "---------------------"
4958 ovn-sbctl list logical_flow
4959 echo "---------------------"
4960
4961 echo "---------------------"
4962 ovn-sbctl dump-flows
4963 echo "---------------------"
4964
4965 echo "------ hv1 dump ----------"
4966 as hv1 ovs-ofctl dump-flows br-int
4967
4968 src_mac=f00000000001
4969 src_lla=fe80000000000000f20000fffe000001
4970 offer_ip=ae700000000000000000000000000004
4971 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4972
4973 # NXT_RESUMEs should be 1.
4974 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4975
4976 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4977 # cat 1.expected | trim_zeros > expout
4978 cat 1.expected | cut -c -120 > expout
4979 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4980 # Skipping the UDP checksum
4981 cat 1.expected | cut -c 125- > expout
4982 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4983
4984 rm 1.expected
4985
4986 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4987 # without any modifications and the packet should be received by ls1-lp1.
4988 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4989 # resume and the other from ovs-ofctl monitor resume.
4990
4991 reset_pcap_file hv1-vif1 hv1/vif1
4992 reset_pcap_file hv1-vif2 hv1/vif2
4993
4994 src_mac=f00000000002
4995 src_lla=fe80000000000000f20000fffe000002
4996 offer_ip=ae700000000000000000000000000005
4997 # Set invalid msg_type
4998
4999 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
5000
5001 # NXT_RESUMEs should be 2.
5002 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5003
5004 # vif2-tx.pcap should not have received the DHCPv6 reply packet
5005 rm 2.packets
5006 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
5007 AT_CHECK([cat 2.packets], [0], [])
5008
5009 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
5010 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
5011 cat 1.expected > expout
5012 AT_CHECK([cat 1.packets], [0], [expout])
5013
5014 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
5015 # There should be no DHCPv6 reply from ovn-controller and the request packet
5016 # should be received by ls2-lp2.
5017
5018 src_mac=f00000000003
5019 src_lla=fe80000000000000f20000fffe000003
5020 test_dhcpv6 3 $src_mac $src_lla 01 0 4
5021
5022 # NXT_RESUMEs should be 2 only.
5023 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5024
5025 # vif3-tx.pcap should not have received the DHCPv6 reply packet
5026 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
5027 AT_CHECK([cat 3.packets], [0], [])
5028
5029 # vif4-tx.pcap should have received the DHCPv6 request packet
5030 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
5031 cat 4.expected > expout
5032 AT_CHECK([cat 4.packets], [0], [expout])
5033
5034 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
5035 # The DHCPv6 reply shouldn't contain offer_ip.
5036 src_mac=f00000000022
5037 src_lla=fe80000000000000f20000fffe000022
5038 reset_pcap_file hv1-vif5 hv1/vif5
5039 test_dhcpv6 5 $src_mac $src_lla 01 1 5
5040
5041 # NXT_RESUMEs should be 3.
5042 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5043
5044 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
5045 # Skipping the UDP checksum
5046 cat 5.expected | cut -c 1-120,125- > expout
5047 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
5048
5049 # Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
5050 # shouldn't contain offer_ip
5051 src_mac=f00000000022
5052 src_lla=fe80000000000000f20000fffe000022
5053 reset_pcap_file hv1-vif5 hv1/vif5
5054 rm -f 5.expected
5055 test_dhcpv6 5 $src_mac $src_lla 0b 1 5
5056
5057 # NXT_RESUMEs should be 4.
5058 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5059
5060 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap |
5061 trim_zeros > 5.packets
5062 # Skipping the UDP checksum
5063 cat 5.expected | cut -c 1-120,125- > expout
5064 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
5065
5066 OVN_CLEANUP([hv1])
5067
5068 AT_CLEANUP
5069
5070 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
5071 AT_SKIP_IF([test $HAVE_PYTHON = no])
5072 ovn_start
5073
5074 # Logical network:
5075 # Two LRs - R1 and R2 that are connected to each other via LS "join"
5076 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
5077 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
5078 # R2 is a gateway router.
5079
5080
5081
5082 # Create two hypervisor and create OVS ports corresponding to logical ports.
5083 net_add n1
5084
5085 sim_add hv1
5086 as hv1
5087 ovs-vsctl add-br br-phys
5088 ovn_attach n1 br-phys 192.168.0.1
5089 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5090 set interface hv1-vif1 external-ids:iface-id=foo1 \
5091 options:tx_pcap=hv1/vif1-tx.pcap \
5092 options:rxq_pcap=hv1/vif1-rx.pcap \
5093 ofport-request=1
5094
5095
5096 sim_add hv2
5097 as hv2
5098 ovs-vsctl add-br br-phys
5099 ovn_attach n1 br-phys 192.168.0.2
5100 ovs-vsctl -- add-port br-int hv2-vif1 -- \
5101 set interface hv2-vif1 external-ids:iface-id=alice1 \
5102 options:tx_pcap=hv2/vif1-tx.pcap \
5103 options:rxq_pcap=hv2/vif1-rx.pcap \
5104 ofport-request=1
5105
5106 # Pre-populate the hypervisors' ARP tables so that we don't lose any
5107 # packets for ARP resolution (native tunneling doesn't queue packets
5108 # for ARP resolution).
5109 OVN_POPULATE_ARP
5110
5111 ovn-nbctl create Logical_Router name=R1
5112 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5113
5114 ovn-nbctl ls-add foo
5115 ovn-nbctl ls-add alice
5116 ovn-nbctl ls-add join
5117
5118 # Connect foo to R1
5119 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5120 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5121 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5122
5123 # Connect alice to R2
5124 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5125 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
5126 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
5127
5128 # Connect R1 to join
5129 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
5130 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
5131 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
5132
5133 # Connect R2 to join
5134 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
5135 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
5136 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
5137
5138
5139 #install static routes
5140 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5141 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
5142 R1 static_routes @lrt
5143
5144 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5145 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5146 R2 static_routes @lrt
5147
5148 # Create logical port foo1 in foo
5149 ovn-nbctl lsp-add foo foo1 \
5150 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5151
5152 # Create logical port alice1 in alice
5153 ovn-nbctl lsp-add alice alice1 \
5154 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
5155
5156
5157 # Allow some time for ovn-northd and ovn-controller to catch up.
5158 # XXX This should be more systematic.
5159 sleep 2
5160
5161 ip_to_hex() {
5162 printf "%02x%02x%02x%02x" "$@"
5163 }
5164
5165 # Send ip packets between foo1 and alice1
5166 src_mac="f00000010203"
5167 dst_mac="000001010203"
5168 src_ip=`ip_to_hex 192 168 1 2`
5169 dst_ip=`ip_to_hex 172 16 1 2`
5170 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5171
5172 echo "---------NB dump-----"
5173 ovn-nbctl show
5174 echo "---------------------"
5175 ovn-nbctl list logical_router
5176 echo "---------------------"
5177 ovn-nbctl list logical_router_port
5178 echo "---------------------"
5179
5180 echo "---------SB dump-----"
5181 ovn-sbctl list datapath_binding
5182 echo "---------------------"
5183 ovn-sbctl list port_binding
5184 echo "---------------------"
5185 ovn-sbctl dump-flows
5186 echo "---------------------"
5187 ovn-sbctl list chassis
5188 ovn-sbctl list encap
5189 echo "---------------------"
5190
5191 # Packet to Expect at alice1
5192 src_mac="000002010203"
5193 dst_mac="f00000010204"
5194 src_ip=`ip_to_hex 192 168 1 2`
5195 dst_ip=`ip_to_hex 172 16 1 2`
5196 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
5197
5198
5199 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5200 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
5201
5202 echo "------ hv1 dump after packet 1 ----------"
5203 as hv1 ovs-ofctl show br-int
5204 as hv1 ovs-ofctl dump-flows br-int
5205 echo "------ hv2 dump after packet 1 ----------"
5206 as hv2 ovs-ofctl show br-int
5207 as hv2 ovs-ofctl dump-flows br-int
5208 echo "----------------------------"
5209
5210 echo $expected > expected
5211 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
5212
5213 # Delete the router and re-create it. Things should work as before.
5214 ovn-nbctl lr-del R2
5215 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5216 # Connect alice to R2
5217 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5218 # Connect R2 to join
5219 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
5220
5221 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5222 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5223 R2 static_routes @lrt
5224
5225 # Wait for ovn-controller to catch up.
5226 sleep 1
5227
5228 # Send the packet again.
5229 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5230
5231 echo "------ hv1 dump after packet 2 ----------"
5232 as hv1 ovs-ofctl show br-int
5233 as hv1 ovs-ofctl dump-flows br-int
5234 echo "------ hv2 dump after packet 2 ----------"
5235 as hv2 ovs-ofctl show br-int
5236 as hv2 ovs-ofctl dump-flows br-int
5237 echo "----------------------------"
5238
5239 echo $expected >> expected
5240 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
5241
5242 OVN_CLEANUP([hv1],[hv2])
5243
5244 AT_CLEANUP
5245
5246 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5247 AT_KEYWORDS([router-icmp-reply])
5248 AT_SKIP_IF([test $HAVE_PYTHON = no])
5249 ovn_start
5250
5251 # Logical network:
5252 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5253 # and has switch ls2 (172.16.1.0/24) connected to it.
5254
5255 ovn-nbctl lr-add R1
5256
5257 ovn-nbctl ls-add ls1
5258 ovn-nbctl ls-add ls2
5259
5260 # Connect ls1 to R1
5261 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
5262 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5263 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5264
5265 # Connect ls2 to R1
5266 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
5267 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5268 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5269
5270 # Create logical port ls1-lp1 in ls1
5271 ovn-nbctl lsp-add ls1 ls1-lp1 \
5272 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
5273
5274 # Create logical port ls2-lp1 in ls2
5275 ovn-nbctl lsp-add ls2 ls2-lp1 \
5276 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
5277
5278 # Create one hypervisor and create OVS ports corresponding to logical ports.
5279 net_add n1
5280
5281 sim_add hv1
5282 as hv1
5283 ovs-vsctl add-br br-phys
5284 ovn_attach n1 br-phys 192.168.0.1
5285 ovs-vsctl -- add-port br-int vif1 -- \
5286 set interface vif1 external-ids:iface-id=ls1-lp1 \
5287 options:tx_pcap=hv1/vif1-tx.pcap \
5288 options:rxq_pcap=hv1/vif1-rx.pcap \
5289 ofport-request=1
5290
5291 ovs-vsctl -- add-port br-int vif2 -- \
5292 set interface vif2 external-ids:iface-id=ls2-lp1 \
5293 options:tx_pcap=hv1/vif2-tx.pcap \
5294 options:rxq_pcap=hv1/vif2-rx.pcap \
5295 ofport-request=1
5296
5297
5298 # Allow some time for ovn-northd and ovn-controller to catch up.
5299 # XXX This should be more systematic.
5300 sleep 1
5301
5302
5303 ip_to_hex() {
5304 printf "%02x%02x%02x%02x" "$@"
5305 }
5306 for i in 1 2; do
5307 : > vif$i.expected
5308 done
5309 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
5310 #
5311 # Causes a packet to be received on INPORT. The packet is an ICMPv4
5312 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
5313 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
5314 # provided, then it should be the ip and icmp checksums of the packet
5315 # responded; otherwise, no reply is expected.
5316 # In the absence of an ip checksum calculation helpers, this relies
5317 # on the caller to provide the checksums for the ip and icmp headers.
5318 # XXX This should be more systematic.
5319 #
5320 # INPORT is an lport number, e.g. 11 for vif11.
5321 # ETH_SRC and ETH_DST are each 12 hex digits.
5322 # IPV4_SRC and IPV4_DST are each 8 hex digits.
5323 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
5324 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
5325 test_ipv4_icmp_request() {
5326 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
5327 local exp_ip_chksum=$8 exp_icmp_chksum=$9
5328 shift; shift; shift; shift; shift; shift; shift
5329 shift; shift
5330
5331 # Use ttl to exercise section 4.2.2.9 of RFC1812
5332 local ip_ttl=01
5333 local icmp_id=5fbf
5334 local icmp_seq=0001
5335 local icmp_data=$(seq 1 56 | xargs printf "%02x")
5336 local icmp_type_code_request=0800
5337 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5338 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
5339
5340 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
5341 if test X$exp_icmp_chksum != X; then
5342 # Expect to receive the reply, if any. In same port where packet was sent.
5343 # Note: src and dst fields are expected to be reversed.
5344 local icmp_type_code_response=0000
5345 local reply_icmp_ttl=fe
5346 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5347 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
5348 echo $reply >> vif$inport.expected
5349 fi
5350 }
5351
5352 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
5353 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
5354 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
5355 l1_ip=$(ip_to_hex 192 168 1 2)
5356 l2_ip=$(ip_to_hex 172 16 1 2)
5357
5358 # Ping router ip address that is on same subnet as the logical port
5359 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
5360 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
5361
5362 # Ping router ip address that is on the other side of the logical ports
5363 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
5364 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
5365
5366
5367 echo "---------NB dump-----"
5368 ovn-nbctl show
5369 echo "---------------------"
5370 ovn-nbctl list logical_router
5371 echo "---------------------"
5372 ovn-nbctl list logical_router_port
5373 echo "---------------------"
5374
5375 echo "---------SB dump-----"
5376 ovn-sbctl list datapath_binding
5377 echo "---------------------"
5378 ovn-sbctl list logical_flow
5379 echo "---------------------"
5380
5381 echo "------ hv1 dump ----------"
5382 as hv1 ovs-ofctl dump-flows br-int
5383
5384 # Now check the packets actually received against the ones expected.
5385 for inport in 1 2; do
5386 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
5387 done
5388
5389 OVN_CLEANUP([hv1])
5390 AT_CLEANUP
5391
5392 AT_SETUP([ovn -- policy-based routing: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5393 AT_KEYWORDS([policy-based-routing])
5394 AT_SKIP_IF([test $HAVE_PYTHON = no])
5395 ovn_start
5396
5397 # Logical network:
5398 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5399 # and has switch ls2 (172.16.1.0/24) connected to it.
5400
5401 ovn-nbctl lr-add R1
5402
5403 ovn-nbctl ls-add ls1
5404 ovn-nbctl ls-add ls2
5405 ovn-nbctl ls-add ls3
5406
5407 # Connect ls1 to R1
5408 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
5409 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5410 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5411
5412 # Connect ls2 to R1
5413 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
5414 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5415 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5416
5417 # Connect ls3 to R1
5418 ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 20.20.1.1/24
5419 ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
5420 type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
5421
5422 # Create logical port ls1-lp1 in ls1
5423 ovn-nbctl lsp-add ls1 ls1-lp1 \
5424 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
5425
5426 # Create logical port ls2-lp1 in ls2
5427 ovn-nbctl lsp-add ls2 ls2-lp1 \
5428 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
5429
5430 # Create logical port ls3-lp1 in ls3
5431 ovn-nbctl lsp-add ls3 ls3-lp1 \
5432 -- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 20.20.1.2"
5433
5434 # Create one hypervisor and create OVS ports corresponding to logical ports.
5435 net_add n1
5436
5437 sim_add pbr-hv
5438 as pbr-hv
5439 ovs-vsctl add-br br-phys
5440 ovn_attach n1 br-phys 192.168.0.1
5441
5442 ovs-vsctl -- add-port br-int vif1 -- \
5443 set interface vif1 external-ids:iface-id=ls1-lp1 \
5444 options:tx_pcap=pbr-hv/vif1-tx.pcap \
5445 options:rxq_pcap=pbr-hv/vif1-rx.pcap \
5446 ofport-request=1
5447
5448 ovs-vsctl -- add-port br-int vif2 -- \
5449 set interface vif2 external-ids:iface-id=ls2-lp1 \
5450 options:tx_pcap=pbr-hv/vif2-tx.pcap \
5451 options:rxq_pcap=pbr-hv/vif2-rx.pcap \
5452 ofport-request=1
5453
5454 ovs-vsctl -- add-port br-int vif3 -- \
5455 set interface vif3 external-ids:iface-id=ls3-lp1 \
5456 options:tx_pcap=pbr-hv/vif3-tx.pcap \
5457 options:rxq_pcap=pbr-hv/vif3-rx.pcap \
5458 ofport-request=1
5459
5460 # Allow some time for ovn-northd and ovn-controller to catch up.
5461 # XXX This should be more systematic.
5462 sleep 1
5463
5464 ls1_ro_mac=00:00:00:01:02:f1
5465 ls1_ro_ip=192.168.1.1
5466
5467 ls2_ro_mac=00:00:00:01:02:f2
5468 ls2_ro_ip=172.16.1.1
5469
5470 ls3_ro_mac=00:00:00:01:02:f3
5471
5472 ls1_p1_mac=00:00:00:01:02:03
5473 ls1_p1_ip=192.168.1.2
5474
5475 ls2_p1_mac=00:00:00:01:02:04
5476 ls2_p1_ip=172.16.1.2
5477
5478 ls3_p1_mac=00:00:00:01:02:05
5479
5480 # Create a drop policy
5481 ovn-nbctl lr-policy-add R1 10 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" drop
5482
5483 # Check logical flow
5484 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
5485 1
5486 ])
5487
5488 # Send packet.
5489 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5490 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5491 udp && udp.src==53 && udp.dst==4369"
5492
5493 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5494
5495 # Check if packet hit the drop policy
5496 AT_CHECK([ovs-ofctl dump-flows br-int | \
5497 grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24 actions=drop" | \
5498 grep "priority=10" | \
5499 grep "n_packets=1" | wc -l], [0], [dnl
5500 1
5501 ])
5502
5503 # Expected to drop the packet.
5504 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
5505 rcvd_packet=`cat vif2.packets`
5506 AT_FAIL_IF([rcvd_packet = ""])
5507
5508 # Override drop policy with allow
5509 ovn-nbctl lr-policy-add R1 20 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" allow
5510
5511 # Check logical flow
5512 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
5513 2
5514 ])
5515
5516 # Send packet.
5517 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5518 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5519 udp && udp.src==53 && udp.dst==4369"
5520 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5521
5522 # Check if packet hit the allow policy
5523 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5524 grep "192.168.1.0" | \
5525 grep "priority=20" | wc -l], [0], [dnl
5526 1
5527 ])
5528
5529 # Expected packet has TTL decreased by 1
5530 expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
5531 ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5532 udp && udp.src==53 && udp.dst==4369"
5533 echo $expected | ovstest test-ovn expr-to-packets > expected
5534
5535 OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
5536
5537 # Override allow policy with reroute
5538 ovn-nbctl lr-policy-add R1 30 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" reroute 20.20.1.2
5539
5540 # Check logical flow
5541 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5542 grep "192.168.1.0" | \
5543 grep "priority=30" | wc -l], [0], [dnl
5544 1
5545 ])
5546
5547 # Send packet.
5548 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5549 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5550 udp && udp.src==53 && udp.dst==4369"
5551 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5552
5553 echo "southbound flows"
5554
5555 ovn-sbctl dump-flows | grep lr_in_policy
5556 echo "ovs flows"
5557 ovs-ofctl dump-flows br-int
5558 # Check if packet hit the allow policy
5559 AT_CHECK([ovs-ofctl dump-flows br-int | \
5560 grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24" | \
5561 grep "priority=30" | \
5562 grep "n_packets=1" | wc -l], [0], [dnl
5563 1
5564 ])
5565 echo "packet hit reroute policy"
5566
5567 # Expected packet has TTL decreased by 1
5568 expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
5569 ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5570 udp && udp.src==53 && udp.dst==4369"
5571 echo $expected | ovstest test-ovn expr-to-packets > 3.expected
5572
5573 OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
5574
5575 OVN_CLEANUP([pbr-hv])
5576 AT_CLEANUP
5577
5578 AT_SETUP([ovn -- policy-based routing IPv6: 1 HVs, 3 LSs, 1 lport/LS, 1 LR])
5579 AT_KEYWORDS([policy-based-routing])
5580 AT_SKIP_IF([test $HAVE_PYTHON = no])
5581 ovn_start
5582
5583 # Logical network:
5584 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5585 # and has switch ls2 (172.16.1.0/24) connected to it.
5586
5587 ovn-nbctl lr-add R1
5588
5589 ovn-nbctl ls-add ls1
5590 ovn-nbctl ls-add ls2
5591 ovn-nbctl ls-add ls3
5592
5593 # Connect ls1 to R1
5594 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 2001::1/64
5595 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5596 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5597
5598 # Connect ls2 to R1
5599 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 2002::1/64
5600 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5601 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5602
5603 # Connect ls3 to R1
5604 ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 2003::1/64
5605 ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
5606 type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
5607
5608 # Create logical port ls1-lp1 in ls1
5609 ovn-nbctl lsp-add ls1 ls1-lp1 \
5610 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 2001::2"
5611
5612 # Create logical port ls2-lp1 in ls2
5613 ovn-nbctl lsp-add ls2 ls2-lp1 \
5614 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 2002::2"
5615
5616 # Create logical port ls3-lp1 in ls3
5617 ovn-nbctl lsp-add ls3 ls3-lp1 \
5618 -- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 2003::2"
5619
5620 # Create one hypervisor and create OVS ports corresponding to logical ports.
5621 net_add n1
5622
5623 sim_add pbr-hv
5624 as pbr-hv
5625 ovs-vsctl add-br br-phys
5626 ovn_attach n1 br-phys 192.168.0.1
5627
5628 ovs-vsctl -- add-port br-int vif1 -- \
5629 set interface vif1 external-ids:iface-id=ls1-lp1 \
5630 options:tx_pcap=pbr-hv/vif1-tx.pcap \
5631 options:rxq_pcap=pbr-hv/vif1-rx.pcap \
5632 ofport-request=1
5633
5634 ovs-vsctl -- add-port br-int vif2 -- \
5635 set interface vif2 external-ids:iface-id=ls2-lp1 \
5636 options:tx_pcap=pbr-hv/vif2-tx.pcap \
5637 options:rxq_pcap=pbr-hv/vif2-rx.pcap \
5638 ofport-request=1
5639
5640 ovs-vsctl -- add-port br-int vif3 -- \
5641 set interface vif3 external-ids:iface-id=ls3-lp1 \
5642 options:tx_pcap=pbr-hv/vif3-tx.pcap \
5643 options:rxq_pcap=pbr-hv/vif3-rx.pcap \
5644 ofport-request=1
5645
5646 # Allow some time for ovn-northd and ovn-controller to catch up.
5647 # XXX This should be more systematic.
5648 sleep 1
5649
5650 ls1_ro_mac=00:00:00:01:02:f1
5651 ls1_ro_ip=2001::1
5652
5653 ls2_ro_mac=00:00:00:01:02:f2
5654 ls2_ro_ip=2002::1
5655
5656 ls3_ro_mac=00:00:00:01:02:f3
5657
5658 ls1_p1_mac=00:00:00:01:02:03
5659 ls1_p1_ip=2001::2
5660
5661 ls2_p1_mac=00:00:00:01:02:04
5662 ls2_p1_ip=2002::2
5663
5664 ls3_p1_mac=00:00:00:01:02:05
5665
5666 # Create a drop policy
5667 ovn-nbctl lr-policy-add R1 10 "ip6.src==2001::/64 && ip6.dst==2002::/64" drop
5668
5669 # Check logical flow
5670 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
5671 1
5672 ])
5673
5674 # Send packet.
5675 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5676 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5677 udp && udp.src==53 && udp.dst==4369"
5678
5679 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5680
5681 # Check if packet hit the drop policy
5682 AT_CHECK([ovs-ofctl dump-flows br-int | \
5683 grep "ipv6_src=2001::/64,ipv6_dst=2002::/64 actions=drop" | \
5684 grep "priority=10" | \
5685 grep "n_packets=1" | wc -l], [0], [dnl
5686 1
5687 ])
5688
5689 # Expected to drop the packet.
5690 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
5691 rcvd_packet=`cat vif2.packets`
5692 AT_FAIL_IF([rcvd_packet = ""])
5693
5694 # Override drop policy with allow
5695 ovn-nbctl lr-policy-add R1 20 "ip6.src==2001::/64 && ip6.dst==2002::/64" allow
5696
5697 # Check logical flow
5698 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
5699 2
5700 ])
5701
5702 # Send packet.
5703 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5704 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5705 udp && udp.src==53 && udp.dst==4369"
5706 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5707
5708 # Check if packet hit the allow policy
5709 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5710 grep "2001" | \
5711 grep "priority=20" | wc -l], [0], [dnl
5712 1
5713 ])
5714
5715 # Expected packet has TTL decreased by 1
5716 expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
5717 ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5718 udp && udp.src==53 && udp.dst==4369"
5719 echo $expected | ovstest test-ovn expr-to-packets > expected
5720
5721 OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
5722
5723 # Override allow policy with reroute
5724 ovn-nbctl lr-policy-add R1 30 "ip6.src==2001::/64 && ip6.dst==2002::/64" reroute 2003::2
5725
5726 # Check logical flow
5727 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5728 grep "2001" | \
5729 grep "priority=30" | wc -l], [0], [dnl
5730 1
5731 ])
5732
5733 # Send packet.
5734 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5735 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5736 udp && udp.src==53 && udp.dst==4369"
5737 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5738
5739 echo "southbound flows"
5740
5741 ovn-sbctl dump-flows | grep lr_in_policy
5742 echo "ovs flows"
5743 ovs-ofctl dump-flows br-int
5744 # Check if packet hit the allow policy
5745 AT_CHECK([ovs-ofctl dump-flows br-int | \
5746 grep "ipv6_src=2001::/64,ipv6_dst=2002::/64" | \
5747 grep "priority=30" | \
5748 grep "n_packets=1" | wc -l], [0], [dnl
5749 1
5750 ])
5751 echo "packet hit reroute policy"
5752
5753 # Expected packet has TTL decreased by 1
5754 expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
5755 ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5756 udp && udp.src==53 && udp.dst==4369"
5757 echo $expected | ovstest test-ovn expr-to-packets > 3.expected
5758
5759 OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
5760
5761 OVN_CLEANUP([pbr-hv])
5762 AT_CLEANUP
5763
5764 # 1 hypervisor, 1 port
5765 # make sure that the port state is properly set to up and back down
5766 # when created and deleted.
5767 AT_SETUP([ovn -- port state up and down])
5768 ovn_start
5769
5770 ovn-nbctl ls-add ls1
5771 ovn-nbctl lsp-add ls1 lp1
5772 ovn-nbctl lsp-set-addresses lp1 unknown
5773
5774 net_add n1
5775 sim_add hv1
5776 as hv1 ovs-vsctl add-br br-phys
5777 as hv1 ovn_attach n1 br-phys 192.168.0.1
5778
5779 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5780 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5781
5782 as hv1 ovs-vsctl del-port br-int vif1
5783 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5784
5785 OVN_CLEANUP([hv1])
5786
5787 AT_CLEANUP
5788
5789 # 1 hypervisor, 1 port
5790 # make sure that the OF rules created to support a datapath are added/cleared
5791 # when logical switch is created and removed.
5792 AT_SETUP([ovn -- datapath rules added/removed])
5793 AT_KEYWORDS([cleanup])
5794 ovn_start
5795
5796 net_add n1
5797 sim_add hv1
5798 as hv1 ovs-vsctl add-br br-phys
5799 as hv1 ovn_attach n1 br-phys 192.168.0.1
5800
5801 # This shell function checks if OF rules in br-int have clauses
5802 # related to OVN datapaths. The caller determines if it should find
5803 # a match in the output, or not.
5804 #
5805 # EXPECT_DATAPATH param determines whether flows that refer to
5806 # datapath to should be present or not. 0 means
5807 # they should not be.
5808 # STAGE_INFO param is a simple string to help identify the stage
5809 # in the test when this function was invoked.
5810 test_datapath_in_of_rules() {
5811 local expect_datapath=$1 stage_info=$2
5812 echo "------ ovn-nbctl show ${stage_info} ------"
5813 ovn-nbctl show
5814 echo "------ ovn-sbctl show ${stage_info} ------"
5815 ovn-sbctl show
5816 echo "------ OF rules ${stage_info} ------"
5817 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
5818 # if there is a datapath mentioned in the output, check for the
5819 # magic keyword that represents one, based on the exit status of
5820 # a quiet grep
5821 if test $expect_datapath != 0; then
5822 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
5823 else
5824 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
5825 fi
5826 }
5827
5828 test_datapath_in_of_rules 0 "before ls+port create"
5829
5830 ovn-nbctl ls-add ls1
5831 ovn-nbctl lsp-add ls1 lp1
5832 ovn-nbctl lsp-set-addresses lp1 unknown
5833
5834 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5835 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5836
5837 test_datapath_in_of_rules 1 "after port is bound"
5838
5839 as hv1 ovs-vsctl del-port br-int vif1
5840 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5841
5842 ovn-nbctl lsp-set-addresses lp1
5843 ovn-nbctl lsp-del lp1
5844 ovn-nbctl ls-del ls1
5845
5846 # wait for earlier changes to take effect
5847 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
5848
5849 # ensure OF rules are no longer present. There used to be a bug here.
5850 test_datapath_in_of_rules 0 "after lport+ls removal"
5851
5852 OVN_CLEANUP([hv1])
5853
5854 AT_CLEANUP
5855
5856 AT_SETUP([ovn -- nd_na ])
5857 AT_SKIP_IF([test $HAVE_PYTHON = no])
5858 ovn_start
5859
5860 #TODO: since patch port for IPv6 logical router port is not ready not,
5861 # so we are not going to test vifs on different lswitches cases. Try
5862 # to update for that once relevant stuff implemented.
5863
5864 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
5865 # with. NS packet we test, from one VIF for another VIF, will be replied
5866 # by local ovn-controller, but not by target VIF.
5867
5868 # Create hypervisors and logical switch lsw0.
5869 ovn-nbctl ls-add lsw0
5870 net_add n1
5871 sim_add hv1
5872 as hv1
5873 ovs-vsctl add-br br-phys
5874 ovn_attach n1 br-phys 192.168.0.2
5875
5876 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5877 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
5878 ovn-nbctl lsp-add lsw0 lp1
5879 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5880 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"
5881
5882 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5883 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
5884 ovn-nbctl lsp-add lsw0 lp2
5885 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5886 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"
5887
5888 # Add ACL rule for ICMPv6 on lsw0
5889 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5890 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5891 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5892
5893 # Allow some time for ovn-northd and ovn-controller to catch up.
5894 # XXX This should be more systematic.
5895 sleep 1
5896
5897 # Given the name of a logical port, prints the name of the hypervisor
5898 # on which it is located.
5899 vif_to_hv() {
5900 echo hv1${1%?}
5901 }
5902 for i in 1 2; do
5903 : > $i.expected
5904 done
5905
5906 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5907 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5908 # vif2 will not receive NS packet, since ovn-controller will reply for it.
5909 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5910 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5911
5912 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
5913 echo $na_packet >> 1.expected
5914
5915 echo "------ hv1 dump ------"
5916 as hv1 ovs-vsctl show
5917 as hv1 ovs-ofctl -O OpenFlow13 show br-int
5918 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5919
5920 for i in 1 2; do
5921 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
5922 done
5923
5924 OVN_CLEANUP([hv1])
5925
5926 AT_CLEANUP
5927
5928 AT_SETUP([ovn -- address sets modification/removal smoke test])
5929 ovn_start
5930
5931 net_add n1
5932
5933 sim_add hv1
5934 as hv1
5935 ovs-vsctl add-br br-phys
5936 ovn_attach n1 br-phys 192.168.0.1
5937
5938 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5939 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5940 ovn-nbctl destroy Address_Set $row
5941
5942 sleep 1
5943
5944 # A bug previously existed in the address set support code
5945 # that caused ovn-controller to crash after an address set
5946 # was updated and then removed. This test case ensures
5947 # that ovn-controller is at least still running after
5948 # creating, updating, and deleting an address set.
5949 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5950
5951 OVN_CLEANUP([hv1])
5952
5953 AT_CLEANUP
5954
5955 AT_SETUP([ovn -- ipam])
5956 AT_SKIP_IF([test $HAVE_PYTHON = no])
5957 ovn_start
5958
5959 # Add a port to a switch that does not have a subnet set, then set the
5960 # subnet which should result in an address being allocated for the port.
5961 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
5962 ovn-nbctl ls-add sw0
5963 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
5964 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
5965 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5966 ["0a:00:00:a8:01:03 192.168.1.2"
5967 ])
5968
5969 # Add 9 more ports to sw0, addresses should all be unique.
5970 for n in `seq 1 9`; do
5971 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
5972 done
5973 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5974 ["0a:00:00:a8:01:04 192.168.1.3"
5975 ])
5976 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5977 ["0a:00:00:a8:01:05 192.168.1.4"
5978 ])
5979 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5980 ["0a:00:00:a8:01:06 192.168.1.5"
5981 ])
5982 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5983 ["0a:00:00:a8:01:07 192.168.1.6"
5984 ])
5985 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5986 ["0a:00:00:a8:01:08 192.168.1.7"
5987 ])
5988 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5989 ["0a:00:00:a8:01:09 192.168.1.8"
5990 ])
5991 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5992 ["0a:00:00:a8:01:0a 192.168.1.9"
5993 ])
5994 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5995 ["0a:00:00:a8:01:0b 192.168.1.10"
5996 ])
5997 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5998 ["0a:00:00:a8:01:0c 192.168.1.11"
5999 ])
6000
6001 # Trying similar tests with a second switch. MAC addresses should be unique
6002 # across both switches but IP's only need to be unique within the same switch.
6003 ovn-nbctl ls-add sw1
6004 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
6005 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
6006 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
6007 ["0a:00:00:a8:01:0d 192.168.1.2"
6008 ])
6009
6010 for n in `seq 11 19`; do
6011 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
6012 done
6013 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
6014 ["0a:00:00:a8:01:0e 192.168.1.3"
6015 ])
6016 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
6017 ["0a:00:00:a8:01:0f 192.168.1.4"
6018 ])
6019 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
6020 ["0a:00:00:a8:01:10 192.168.1.5"
6021 ])
6022 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
6023 ["0a:00:00:a8:01:11 192.168.1.6"
6024 ])
6025 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
6026 ["0a:00:00:a8:01:12 192.168.1.7"
6027 ])
6028 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
6029 ["0a:00:00:a8:01:13 192.168.1.8"
6030 ])
6031 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
6032 ["0a:00:00:a8:01:14 192.168.1.9"
6033 ])
6034 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
6035 ["0a:00:00:a8:01:15 192.168.1.10"
6036 ])
6037 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
6038 ["0a:00:00:a8:01:16 192.168.1.11"
6039 ])
6040
6041 # Change a port's address to test for multiple ip's for a single address entry
6042 # and addresses set by the user.
6043 ovn-nbctl lsp-set-addresses p0 "0a:00:00:a8:01:17 192.168.1.2 192.168.1.12 192.168.1.14"
6044 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
6045 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
6046 ["0a:00:00:a8:01:18 192.168.1.13"
6047 ])
6048
6049 # Test for logical router port address management.
6050 ovn-nbctl create Logical_Router name=R1
6051 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
6052 network="192.168.1.1/24" mac=\"0a:00:00:a8:01:19\" \
6053 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
6054 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
6055 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
6056 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
6057 ["0a:00:00:a8:01:1a 192.168.1.15"
6058 ])
6059
6060 # Test for address reuse after logical port is deleted.
6061 ovn-nbctl lsp-del p0
6062 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
6063 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
6064 ["0a:00:00:a8:01:03 192.168.1.2"
6065 ])
6066
6067 # Test for multiple addresses to one logical port.
6068 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
6069 "0a:00:00:a8:01:1b 192.168.1.12" "0a:00:00:a8:01:1c 192.168.1.14"
6070 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
6071 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
6072 ["0a:00:00:a8:01:17 192.168.1.16"
6073 ])
6074
6075 # Test for exhausting subnet address space.
6076 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
6077 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
6078 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
6079 ["0a:00:00:10:01:03 172.16.1.2"
6080 ])
6081
6082 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
6083 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
6084 ["0a:00:00:00:00:01"
6085 ])
6086
6087 # Test that address management does not add duplicate MAC for lsp/lrp peers.
6088 ovn-nbctl create Logical_Router name=R2
6089 ovn-nbctl ls-add sw3
6090 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
6091 "0a:00:00:a8:01:18"
6092 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
6093 network="192.168.2.1/24" mac=\"0a:00:00:a8:01:18\" \
6094 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
6095 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
6096 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
6097 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
6098 ["0a:00:00:a8:01:1d 192.168.1.17"
6099 ])
6100
6101 # Test static MAC address with dynamically allocated IP
6102 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
6103 "fe:dc:ba:98:76:54 dynamic"
6104 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6105 ["fe:dc:ba:98:76:54 192.168.1.18"
6106 ])
6107
6108 # Update the static MAC address with dynamically allocated IP and check
6109 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
6110 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
6111
6112 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6113 ["fe:dc:ba:98:76:55 192.168.1.18"
6114 ])
6115
6116 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
6117 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6118 ["0a:00:00:a8:01:1e 192.168.1.18"
6119 ])
6120
6121 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
6122 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6123 ["fe:dc:ba:98:76:56 192.168.1.18"
6124 ])
6125
6126
6127 # Test the exclude_ips from the IPAM list
6128 ovn-nbctl --wait=sb set logical_switch sw0 \
6129 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
6130
6131 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
6132 "dynamic"
6133 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
6134 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
6135 ["0a:00:00:a8:01:1e 192.168.1.20"
6136 ])
6137
6138 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
6139 "dynamic"
6140 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
6141 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
6142 ["0a:00:00:a8:01:1f 192.168.1.22"
6143 ])
6144
6145 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
6146 "dynamic"
6147 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
6148 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
6149 ["0a:00:00:a8:01:34 192.168.1.51"
6150 ])
6151
6152 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
6153 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
6154 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
6155 "dynamic"
6156 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
6157 ["0a:00:00:a8:01:20 192.168.1.19"
6158 ])
6159
6160 # Set invalid data in exclude_ips list. It should be ignored.
6161 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
6162 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
6163 "dynamic"
6164 # 192.168.1.21 should be assigned as that's the next free one.
6165 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
6166 ["0a:00:00:a8:01:21 192.168.1.21"
6167 ])
6168
6169 # Clear the dynamic addresses assignment request.
6170 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
6171 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
6172 [[[]]
6173 ])
6174
6175 # Set IPv6 prefix
6176 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
6177 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
6178 "dynamic"
6179
6180 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
6181 # - aef0::800:ff:fe00:26 (EUI64)
6182 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
6183 ["0a:00:00:a8:01:21 192.168.1.21 aef0::800:ff:fea8:121"
6184 ])
6185
6186 ovn-nbctl --wait=sb ls-add sw4
6187 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
6188 -- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
6189 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
6190 "dynamic"
6191
6192 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
6193 ["0a:00:00:a8:02:03 192.168.2.2 bef0::800:ff:fea8:203"
6194 ])
6195
6196 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
6197 "f0:00:00:00:10:12 dynamic"
6198
6199 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
6200 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
6201 ])
6202
6203 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
6204 # p40 should not have an IPv4 address since the pool is exhausted
6205 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
6206 "dynamic"
6207 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
6208 ["0a:00:00:00:00:02 bef0::800:ff:fe00:2"
6209 ])
6210
6211 # Test dynamic changes on switch ports.
6212 #
6213 ovn-nbctl --wait=sb ls-add sw5
6214 ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
6215 "dynamic"
6216 # p41 will start with nothing
6217 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6218 [[[]]
6219 ])
6220
6221 # Set a subnet. Now p41 should have an ipv4 address, too
6222 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
6223 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6224 ["0a:00:00:a8:01:22 192.168.1.2"
6225 ])
6226
6227 # Clear the other_config. The IPv4 address should be gone
6228 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
6229 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6230 [[[]]
6231 ])
6232
6233 # Set an IPv6 prefix. Now p41 should have an IPv6 address.
6234 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
6235 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6236 ["0a:00:00:00:00:03 aef0::800:ff:fe00:3"
6237 ])
6238
6239 # Change the MAC address to a static one. The IPv6 address should update.
6240 ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
6241 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6242 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
6243 ])
6244
6245 # Change the IPv6 prefix. The IPv6 address should update.
6246 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
6247 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6248 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
6249 ])
6250
6251 # Clear the other_config. The IPv6 address should be gone
6252 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
6253 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6254 [[[]]
6255 ])
6256
6257 # Set the subnet again. Now p41 should get the IPv4 address again.
6258 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
6259 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6260 ["f0:00:00:00:10:2b 192.168.1.2"
6261 ])
6262
6263 # Add an excluded IP address that conflicts with p41. p41 should update.
6264 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
6265 exclude_ips="192.168.1.2"
6266 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6267 ["f0:00:00:00:10:2b 192.168.1.3"
6268 ])
6269
6270 # Add static ip address
6271 ovn-nbctl --wait=sb lsp-set-addresses p41 "dynamic 192.168.1.100"
6272 ovn-nbctl list Logical-Switch-Port p41
6273 ovn-nbctl --wait=sb lsp-add sw5 p42 -- lsp-set-addresses p42 \
6274 "dynamic 192.168.1.101"
6275 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6276 ["0a:00:00:a8:01:65 192.168.1.100"
6277 ])
6278 AT_CHECK([ovn-nbctl get Logical-Switch-Port p42 dynamic_addresses], [0],
6279 ["0a:00:00:a8:01:66 192.168.1.101"
6280 ])
6281
6282 # define a mac address prefix
6283 ovn-nbctl ls-add sw6
6284 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22:33:44:55"
6285 ovn-nbctl --wait=sb set Logical-Switch sw6 other_config:subnet=192.168.100.0/24
6286 for n in $(seq 1 3); do
6287 ovn-nbctl --wait=sb lsp-add sw6 "p5$n" -- lsp-set-addresses "p5$n" dynamic
6288 done
6289 AT_CHECK([ovn-nbctl get Logical-Switch-Port p51 dynamic_addresses], [0],
6290 ["00:11:22:a8:64:03 192.168.100.2"
6291 ])
6292 AT_CHECK([ovn-nbctl get Logical-Switch-Port p52 dynamic_addresses], [0],
6293 ["00:11:22:a8:64:04 192.168.100.3"
6294 ])
6295 AT_CHECK([ovn-nbctl get Logical-Switch-Port p53 dynamic_addresses], [0],
6296 ["00:11:22:a8:64:05 192.168.100.4"
6297 ])
6298
6299 # verify configuration order does not break IPAM/MACAM
6300 ovn-nbctl ls-add sw7
6301 for n in $(seq 1 3); do
6302 ovn-nbctl --wait=sb lsp-add sw7 "p7$n" -- lsp-set-addresses "p7$n" dynamic
6303 done
6304 ovn-nbctl --wait=sb set Logical-Switch sw7 other_config:ipv6_prefix="bef0::"
6305 p71_addr=$(ovn-nbctl get Logical-Switch-Port p71 dynamic_addresses)
6306 p72_addr=$(ovn-nbctl get Logical-Switch-Port p72 dynamic_addresses)
6307 p73_addr=$(ovn-nbctl get Logical-Switch-Port p73 dynamic_addresses)
6308 AT_CHECK([test "$p71_addr" != "$p72_addr"], [0], [])
6309 AT_CHECK([test "$p71_addr" != "$p73_addr"], [0], [])
6310 AT_CHECK([test "$p72_addr" != "$p73_addr"], [0], [])
6311
6312 # request to assign mac only
6313 #
6314 ovn-nbctl ls-add sw8
6315 ovn-nbctl --wait=sb set Logical-Switch sw8 other_config:mac_only=true
6316 for n in $(seq 1 3); do
6317 ovn-nbctl --wait=sb lsp-add sw8 "p8$n" -- lsp-set-addresses "p8$n" dynamic
6318 done
6319 AT_CHECK([ovn-nbctl get Logical-Switch-Port p81 dynamic_addresses], [0],
6320 ["00:11:22:00:00:06"
6321 ])
6322 AT_CHECK([ovn-nbctl get Logical-Switch-Port p82 dynamic_addresses], [0],
6323 ["00:11:22:00:00:07"
6324 ])
6325 AT_CHECK([ovn-nbctl get Logical-Switch-Port p83 dynamic_addresses], [0],
6326 ["00:11:22:00:00:08"
6327 ])
6328
6329 # clear mac_prefix and check it is allocated in a random manner
6330 ovn-nbctl --wait=hv remove NB_Global . options mac_prefix
6331 ovn-nbctl ls-add sw9
6332 ovn-nbctl --wait=sb set Logical-Switch sw9 other_config:mac_only=true
6333 ovn-nbctl --wait=sb lsp-add sw9 p91 -- lsp-set-addresses p91 dynamic
6334
6335 mac_prefix=$(ovn-nbctl --wait=sb get NB_Global . options:mac_prefix | tr -d \")
6336 port_addr=$(ovn-nbctl get Logical-Switch-Port p91 dynamic_addresses | tr -d \")
6337 AT_CHECK([test "$port_addr" = "${mac_prefix}:00:00:09"], [0], [])
6338
6339 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22"
6340 ovn-nbctl ls-add sw10
6341 ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:ipv6_prefix="ae01::"
6342 ovn-nbctl --wait=sb lsp-add sw10 p101 -- lsp-set-addresses p101 "dynamic ae01::1"
6343 AT_CHECK([ovn-nbctl get Logical-Switch-Port p101 dynamic_addresses], [0],
6344 ["00:11:22:00:00:0a ae01::1"
6345 ])
6346
6347 ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:subnet=192.168.110.0/24
6348 ovn-nbctl --wait=sb lsp-add sw10 p102 -- lsp-set-addresses p102 "dynamic 192.168.110.10 ae01::2"
6349 AT_CHECK([ovn-nbctl get Logical-Switch-Port p102 dynamic_addresses], [0],
6350 ["00:11:22:a8:6e:0b 192.168.110.10 ae01::2"
6351 ])
6352
6353 as ovn-sb
6354 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6355
6356 as ovn-nb
6357 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6358
6359 as northd
6360 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6361
6362 as northd-backup
6363 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6364
6365 AT_CLEANUP
6366
6367 AT_SETUP([ovn -- ipam connectivity])
6368 AT_SKIP_IF([test $HAVE_PYTHON = no])
6369 ovn_start
6370
6371 ovn-nbctl lr-add R1
6372
6373 # Test for a ping using dynamically allocated addresses.
6374 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
6375 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
6376 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
6377
6378 # Connect foo to R1
6379 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6380 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6381 options:router-port=foo \
6382 -- lsp-set-addresses rp-foo router
6383
6384 # Connect alice to R1
6385 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
6386 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
6387 options:router-port=alice addresses=\"00:00:00:01:02:04\"
6388
6389 # Create logical port foo1 in foo
6390 ovn-nbctl --wait=sb lsp-add foo foo1 \
6391 -- lsp-set-addresses foo1 "dynamic"
6392 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:a8:01:03 192.168.1.2"'], [0])
6393
6394 # Create logical port alice1 in alice
6395 ovn-nbctl --wait=sb lsp-add alice alice1 \
6396 -- lsp-set-addresses alice1 "dynamic"
6397 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:a8:02:03 192.168.2.2"'])
6398
6399 # Create logical port foo2 in foo
6400 ovn-nbctl --wait=sb lsp-add foo foo2 \
6401 -- lsp-set-addresses foo2 "dynamic"
6402 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:a8:01:04 192.168.1.3"'])
6403
6404 # Create a hypervisor and create OVS ports corresponding to logical ports.
6405 net_add n1
6406
6407 sim_add hv1
6408 as hv1
6409 ovs-vsctl add-br br-phys
6410 ovn_attach n1 br-phys 192.168.0.1
6411 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6412 set interface hv1-vif1 external-ids:iface-id=foo1 \
6413 options:tx_pcap=hv1/vif1-tx.pcap \
6414 options:rxq_pcap=hv1/vif1-rx.pcap \
6415 ofport-request=1
6416
6417 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6418 set interface hv1-vif2 external-ids:iface-id=foo2 \
6419 options:tx_pcap=hv1/vif2-tx.pcap \
6420 options:rxq_pcap=hv1/vif2-rx.pcap \
6421 ofport-request=2
6422
6423 ovs-vsctl -- add-port br-int hv1-vif3 -- \
6424 set interface hv1-vif3 external-ids:iface-id=alice1 \
6425 options:tx_pcap=hv1/vif3-tx.pcap \
6426 options:rxq_pcap=hv1/vif3-rx.pcap \
6427 ofport-request=3
6428
6429 # Allow some time for ovn-northd and ovn-controller to catch up.
6430 # XXX This should be more systematic.
6431 sleep 1
6432
6433 ip_to_hex() {
6434 printf "%02x%02x%02x%02x" "$@"
6435 }
6436
6437 # Send ip packets between foo1 and foo2
6438 src_mac="0a0000a80103"
6439 dst_mac="0a0000a80104"
6440 src_ip=`ip_to_hex 192 168 1 2`
6441 dst_ip=`ip_to_hex 192 168 1 3`
6442 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6443 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6444
6445 # Send ip packets between foo1 and alice1
6446 src_mac="0a0000a80103"
6447 dst_mac="000000010203"
6448 src_ip=`ip_to_hex 192 168 1 2`
6449 dst_ip=`ip_to_hex 192 168 2 2`
6450 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6451 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6452
6453 echo "---------NB dump-----"
6454 ovn-nbctl show
6455 echo "---------------------"
6456 ovn-nbctl list logical_router
6457 echo "---------------------"
6458 ovn-nbctl list logical_router_port
6459 echo "---------------------"
6460
6461 echo "---------SB dump-----"
6462 ovn-sbctl list datapath_binding
6463 echo "---------------------"
6464 ovn-sbctl list port_binding
6465 echo "---------------------"
6466
6467 echo "------ hv1 dump ----------"
6468 as hv1 ovs-ofctl dump-flows br-int
6469
6470 # Packet to Expect at foo2
6471 src_mac="0a0000a80103"
6472 dst_mac="0a0000a80104"
6473 src_ip=`ip_to_hex 192 168 1 2`
6474 dst_ip=`ip_to_hex 192 168 1 3`
6475 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6476
6477 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
6478 echo $expected > expout
6479 AT_CHECK([cat received1.packets], [0], [expout])
6480
6481 # Packet to Expect at alice1
6482 src_mac="000000010204"
6483 dst_mac="0a0000a80203"
6484 src_ip=`ip_to_hex 192 168 1 2`
6485 dst_ip=`ip_to_hex 192 168 2 2`
6486 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6487
6488 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
6489 echo $expected > expout
6490 AT_CHECK([cat received2.packets], [0], [expout])
6491
6492 OVN_CLEANUP([hv1])
6493
6494 AT_CLEANUP
6495
6496 AT_SETUP([ovn -- ovs-vswitchd restart])
6497 AT_KEYWORDS([vswitchd])
6498 AT_SKIP_IF([test $HAVE_PYTHON = no])
6499 ovn_start
6500
6501 ovn-nbctl ls-add ls1
6502
6503 ovn-nbctl lsp-add ls1 ls1-lp1 \
6504 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
6505
6506 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
6507
6508 net_add n1
6509 sim_add hv1
6510
6511 as hv1
6512 ovs-vsctl add-br br-phys
6513 ovn_attach n1 br-phys 192.168.0.1
6514 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6515 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6516 options:tx_pcap=hv1/vif1-tx.pcap \
6517 options:rxq_pcap=hv1/vif1-rx.pcap \
6518 ofport-request=1
6519
6520 OVN_POPULATE_ARP
6521 sleep 2
6522
6523 as hv1 ovs-vsctl show
6524
6525 echo "---------------------"
6526 ovn-sbctl dump-flows
6527 echo "---------------------"
6528
6529 echo "------ hv1 dump ----------"
6530 as hv1 ovs-ofctl dump-flows br-int
6531 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6532
6533 echo "Total flows before vswitchd restart = " $total_flows
6534
6535 # Code taken from ovs-save utility
6536 save_flows () {
6537 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
6538 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
6539 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
6540 echo "EOF" >> restore_flows.sh
6541 }
6542
6543 restart_vswitchd () {
6544 restore_flows=$1
6545
6546 if test $restore_flows = true; then
6547 save_flows
6548 fi
6549
6550 as hv1
6551 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6552
6553 if test $restore_flows = true; then
6554 as hv1
6555 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
6556 fi
6557
6558 as hv1
6559 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
6560 ovs-ofctl dump-flows br-int
6561
6562 if test $restore_flows = true; then
6563 sh ./restore_flows.sh
6564 echo "Flows after restore"
6565 as hv1
6566 ovs-ofctl dump-flows br-int
6567 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
6568 flow-restore-wait="true"
6569 fi
6570 }
6571
6572 # Save the flows, restart vswitchd and restore the flows
6573 restart_vswitchd true
6574 OVS_WAIT_UNTIL([
6575 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6576 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6577 test "${total_flows}" = "${total_flows_after_restart}"
6578 ])
6579
6580 # Restart vswitchd without restoring
6581 restart_vswitchd false
6582 OVS_WAIT_UNTIL([
6583 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6584 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6585 test "${total_flows}" = "${total_flows_after_restart}"
6586 ])
6587
6588 OVN_CLEANUP([hv1])
6589 AT_CLEANUP
6590
6591 AT_SETUP([ovn -- send arp for nexthop])
6592 AT_SKIP_IF([test $HAVE_PYTHON = no])
6593 ovn_start
6594
6595 # Topology: Two LSs - ls1 and ls2 are connected via router r0
6596
6597 # Create logical switches
6598 ovn-nbctl ls-add ls1
6599 ovn-nbctl ls-add ls2
6600
6601 # Create router
6602 ovn-nbctl create Logical_Router name=lr0
6603
6604 # Add router ls1p1 port to gateway router
6605 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
6606 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
6607 type=router options:router-port=lrp-ls1lp1 \
6608 addresses='"f0:00:00:00:00:01 192.168.0.1"'
6609
6610 # Add router ls2p2 port to gateway router
6611 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
6612 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
6613 type=router options:router-port=lrp-ls2lp1 \
6614 addresses='"f0:00:00:00:00:02 192.168.1.1"'
6615
6616 # Set default gateway (nexthop) to 192.168.1.254
6617 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
6618
6619 # Create logical port ls1lp2 in ls1
6620 ovn-nbctl lsp-add ls1 ls1lp2 \
6621 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
6622
6623 # Create logical port ls2lp2 in ls2
6624 ovn-nbctl lsp-add ls2 ls2lp2 \
6625 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
6626
6627 net_add n1
6628 sim_add hv1
6629 as hv1
6630 ovs-vsctl add-br br-phys
6631 ovn_attach n1 br-phys 192.168.0.1
6632 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
6633 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
6634 options:tx_pcap=hv1/ls1lp2-tx.pcap \
6635 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
6636 ofport-request=1
6637 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
6638 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
6639 options:tx_pcap=hv1/ls2lp2-tx.pcap \
6640 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
6641 ofport-request=2
6642
6643 # Allow some time for ovn-northd and ovn-controller to catch up.
6644 # XXX This should be more systematic.
6645 sleep 1
6646
6647 echo "---------NB dump-----"
6648 ovn-nbctl show
6649 echo "---------------------"
6650 ovn-nbctl list logical_router
6651 echo "---------------------"
6652 ovn-nbctl list logical_router_port
6653 echo "---------------------"
6654
6655 echo "---------SB dump-----"
6656 ovn-sbctl list datapath_binding
6657 echo "---------------------"
6658 ovn-sbctl list port_binding
6659 echo "---------------------"
6660 ovn-sbctl dump-flows
6661 echo "---------------------"
6662 ovn-sbctl list chassis
6663 ovn-sbctl list encap
6664 echo "---------------------"
6665
6666 echo "------Flows dump-----"
6667 as hv1
6668 ovs-ofctl dump-flows
6669 echo "---------------------"
6670
6671 ip_to_hex() {
6672 printf "%02x%02x%02x%02x" "$@"
6673 }
6674
6675 src_mac="f00000000003"
6676 dst_mac="f00000000001"
6677 src_ip=`ip_to_hex 192 168 0 2`
6678 dst_ip=`ip_to_hex 8 8 8 8`
6679 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6680
6681 # Send IP packet destined to 8.8.8.8 from lsp1lp2
6682 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
6683
6684 trim_zeros() {
6685 sed 's/\(00\)\{1,\}$//'
6686 }
6687
6688 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
6689 # not 8.8.8.8
6690
6691 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
6692 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
6693 echo $expected > expout
6694 AT_CHECK([cat packets], [0], [expout])
6695 cat packets
6696
6697 OVN_CLEANUP([hv1])
6698
6699 AT_CLEANUP
6700
6701 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
6702 AT_SKIP_IF([test $HAVE_PYTHON = no])
6703 ovn_start
6704 # Create logical switch
6705 ovn-nbctl ls-add ls0
6706 # Create gateway router
6707 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6708 # Add router port to gateway router
6709 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6710 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
6711 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
6712 # Add nat-address option
6713 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
6714
6715 net_add n1
6716 sim_add hv1
6717 as hv1
6718 ovs-vsctl \
6719 -- add-br br-phys \
6720 -- add-br br-eth0
6721
6722 ovn_attach n1 br-phys 192.168.0.1
6723
6724 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6725 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])
6726
6727 # Create a localnet port.
6728 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6729 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6730 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6731 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6732
6733 # Wait until the patch ports are created in hv1 to connect br-int to br-eth0
6734 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-vsctl show | \
6735 grep "Port patch-br-int-to-ln_port" | wc -l`])
6736
6737 # Wait for packet to be received.
6738 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6739 trim_zeros() {
6740 sed 's/\(00\)\{1,\}$//'
6741 }
6742 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6743 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6744 echo $expected > expout
6745 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6746 echo $expected >> expout
6747 AT_CHECK([sort packets], [0], [expout])
6748
6749 OVN_CLEANUP([hv1])
6750
6751 AT_CLEANUP
6752
6753 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6754 AT_SKIP_IF([test $HAVE_PYTHON = no])
6755 ovn_start
6756 # Create logical switch
6757 ovn-nbctl ls-add ls0
6758 # Create gateway router
6759 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6760 # Add router port to gateway router
6761 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6762 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
6763 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
6764 # Add nat-address option
6765 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6766 # Add NAT rules
6767 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6768 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6769 # Add load balancers
6770 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6771 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6772 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6773 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6774
6775 net_add n1
6776 sim_add hv1
6777 as hv1
6778 ovs-vsctl \
6779 -- add-br br-phys \
6780 -- add-br br-eth0
6781
6782 ovn_attach n1 br-phys 192.168.0.1
6783
6784 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6785 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])
6786
6787 # Create a localnet port.
6788 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6789 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6790 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6791 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6792
6793 # Wait until the patch ports are created to connect br-int to br-eth0
6794 OVS_WAIT_UNTIL([test 1 = `ovs-vsctl show | \
6795 grep "Port patch-br-int-to-ln_port" | wc -l`])
6796
6797 ovn-sbctl list port_binding lrp0-rp
6798 echo "*****"
6799 ovn-nbctl list logical_switch_port lrp0-rp
6800 ovn-nbctl list logical_router_port lrp0
6801 ovn-nbctl show
6802 # Wait for packet to be received.
6803 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6804 trim_zeros() {
6805 sed 's/\(00\)\{1,\}$//'
6806 }
6807 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6808 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6809 echo $expected > expout
6810 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6811 echo $expected >> expout
6812 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6813 echo $expected >> expout
6814 AT_CHECK([sort packets], [0], [expout])
6815
6816 OVN_CLEANUP([hv1])
6817
6818 AT_CLEANUP
6819
6820 AT_SETUP([ovn -- delete mac bindings])
6821 ovn_start
6822 net_add n1
6823 sim_add hv1
6824 as hv1
6825 ovs-vsctl -- add-br br-phys
6826 ovn_attach n1 br-phys 192.168.0.1
6827 # Create logical switch ls0
6828 ovn-nbctl ls-add ls0
6829 # Create ports lp0, lp1 in ls0
6830 ovn-nbctl lsp-add ls0 lp0
6831 ovn-nbctl lsp-add ls0 lp1
6832 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6833 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6834 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6835 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6836 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6837 ovn-sbctl find MAC_Binding
6838 # Delete port lp0 and check that its MAC_Binding is deleted.
6839 ovn-nbctl lsp-del lp0
6840 ovn-sbctl find MAC_Binding
6841 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6842 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
6843 ovn-nbctl ls-del ls0
6844 ovn-sbctl find MAC_Binding
6845 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6846
6847 OVN_CLEANUP([hv1])
6848
6849 AT_CLEANUP
6850
6851 AT_SETUP([ovn -- conntrack zone allocation])
6852 AT_SKIP_IF([test $HAVE_PYTHON = no])
6853 ovn_start
6854
6855 # Logical network:
6856 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6857 # connected to a router R1.
6858 # foo has foo1 to act as a client.
6859 # bar has bar1, bar2, bar3 to act as servers.
6860
6861 net_add n1
6862
6863 sim_add hv1
6864 as hv1
6865 ovs-vsctl add-br br-phys
6866 ovn_attach n1 br-phys 192.168.0.1
6867 for i in foo1 bar1 bar2 bar3; do
6868 ovs-vsctl -- add-port br-int $i -- \
6869 set interface $i external-ids:iface-id=$i \
6870 options:tx_pcap=hv1/$i-tx.pcap \
6871 options:rxq_pcap=hv1/$i-rx.pcap
6872 done
6873
6874 ovn-nbctl create Logical_Router name=R1
6875 ovn-nbctl ls-add foo
6876 ovn-nbctl ls-add bar
6877
6878 # Connect foo to R1
6879 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6880 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6881 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6882
6883 # Connect bar to R1
6884 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6885 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6886 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6887
6888 # Create logical port foo1 in foo
6889 ovn-nbctl lsp-add foo foo1 \
6890 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6891
6892 # Create logical port bar1, bar2 and bar3 in bar
6893 for i in `seq 1 3`; do
6894 ip=`expr $i + 1`
6895 ovn-nbctl lsp-add bar bar$i \
6896 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6897 done
6898
6899 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6900
6901 OVN_CLEANUP([hv1])
6902
6903 AT_CLEANUP
6904
6905 AT_SETUP([ovn -- tag allocation])
6906 ovn_start
6907
6908 AT_CHECK([ovn-nbctl ls-add ls0])
6909 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6910 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6911 AT_CHECK([ovn-nbctl ls-add ls1])
6912
6913 dnl When a tag is provided, no allocation is done
6914 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6915 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6916 ])
6917 dnl The same 'tag' gets created in southbound database.
6918 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6919 logical_port="c0"], [0], [3
6920 ])
6921
6922 dnl Allocate tags and see it getting created in both NB and SB
6923 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6924 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6925 ])
6926 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6927 logical_port="c1"], [0], [1
6928 ])
6929
6930 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6931 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6932 ])
6933 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6934 logical_port="c2"], [0], [2
6935 ])
6936 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6937 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6938 ])
6939 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6940 logical_port="c3"], [0], [4
6941 ])
6942
6943 dnl A different parent.
6944 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6945 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6946 ])
6947 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6948 logical_port="c4"], [0], [1
6949 ])
6950
6951 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6952 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6953 ])
6954 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6955 logical_port="c5"], [0], [2
6956 ])
6957
6958 dnl Delete a logical port and create a new one.
6959 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6960 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6961 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6962 ])
6963 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6964 logical_port="c6"], [0], [1
6965 ])
6966
6967 dnl Restart northd to see that the same allocation remains.
6968 as northd
6969 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6970 start_daemon ovn-northd \
6971 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6972 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6973
6974 dnl Create a switch to make sure that ovn-northd has run through the main loop.
6975 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6976 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6977 ])
6978 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6979 ])
6980 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6981 ])
6982 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6983 ])
6984 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6985 ])
6986 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6987 ])
6988
6989 dnl Create a switch port with a tag that has already been allocated.
6990 dnl It should go through fine with a duplicate tag.
6991 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6992 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6993 ])
6994 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6995 logical_port="c7"], [0], [2
6996 ])
6997 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6998 ])
6999
7000 AT_CHECK([ovn-nbctl ls-add ls2])
7001 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
7002 dnl gets copied to 'tag'
7003 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
7004 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
7005 ])
7006 dnl The same 'tag' gets created in southbound database.
7007 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
7008 logical_port="local0"], [0], [25
7009 ])
7010 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
7011 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
7012 AT_CHECK([ovn-nbctl lsp-get-tag local1])
7013 dnl change the tag_request.
7014 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
7015 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
7016 ])
7017
7018 AT_CLEANUP
7019
7020 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
7021 ovn_start
7022 ovn-nbctl ls-add lsw0
7023 net_add n1
7024 for i in 1 2; do
7025 sim_add hv$i
7026 as hv$i
7027 ovs-vsctl add-br br-phys
7028 ovn_attach n1 br-phys 192.168.0.$i
7029 ovs-vsctl add-br br-eth0
7030 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
7031 done
7032
7033 # Create a localnet port.
7034 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
7035 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7036 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7037 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7038
7039
7040 # Create 3 vifs.
7041 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
7042 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
7043 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
7044 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
7045 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
7046 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
7047 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
7048 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
7049 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
7050
7051 # Bind the localvif1 to hv1.
7052 as hv1
7053 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
7054
7055 # On hv1, check that there are no flows outputting bcast to tunnel
7056 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7057
7058 # On hv2, check that no flow outputs bcast to tunnel to hv1.
7059 as hv2
7060 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7061
7062 # Now bind vif2 on hv2.
7063 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
7064
7065 # At this point, the broadcast flow on vif2 should be deleted.
7066 # because, there is now a localnet vif bound (table=32 programming logic)
7067 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7068
7069 # Verify that the local net patch port exists on hv2.
7070 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7071
7072 # Now bind vif3 on hv2.
7073 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
7074
7075 # Verify that the local net patch port still exists on hv2
7076 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7077
7078 # Delete localvif2
7079 AT_CHECK([ovn-nbctl lsp-del localvif2])
7080
7081 # Verify that the local net patch port still exists on hv2,
7082 # because, localvif3 is still bound.
7083 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7084
7085 OVN_CLEANUP([hv1],[hv2])
7086
7087 AT_CLEANUP
7088
7089
7090 AT_SETUP([ovn -- ACL logging])
7091 AT_KEYWORDS([ovn])
7092 ovn_start
7093
7094 net_add n1
7095
7096 sim_add hv
7097 as hv
7098 ovs-vsctl add-br br-phys
7099 ovn_attach n1 br-phys 192.168.0.1
7100 for i in lp1 lp2; do
7101 ovs-vsctl -- add-port br-int $i -- \
7102 set interface $i external-ids:iface-id=$i \
7103 options:tx_pcap=hv/$i-tx.pcap \
7104 options:rxq_pcap=hv/$i-rx.pcap
7105 done
7106
7107 lp1_mac="f0:00:00:00:00:01"
7108 lp1_ip="192.168.1.2"
7109
7110 lp2_mac="f0:00:00:00:00:02"
7111 lp2_ip="192.168.1.3"
7112
7113 ovn-nbctl ls-add lsw0
7114 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7115 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7116 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
7117 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
7118 ovn-nbctl --wait=sb sync
7119
7120 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
7121 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
7122
7123 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
7124 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
7125
7126 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
7127 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
7128
7129 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
7130 ovn-nbctl --wait=hv --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
7131
7132 ovn-sbctl dump-flows
7133
7134
7135 # Send packet that should be dropped without logging.
7136 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7137 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7138 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
7139 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7140
7141 # Send packet that should be dropped with logging.
7142 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7143 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7144 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
7145 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7146
7147 # Send packet that should be allowed without logging.
7148 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7149 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7150 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
7151 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7152
7153 # Send packet that should be allowed with logging.
7154 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7155 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7156 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
7157 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7158
7159 # Send packet that should allow related flows without logging.
7160 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7161 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7162 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
7163 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7164
7165 # Send packet that should allow related flows with logging.
7166 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7167 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7168 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
7169 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7170
7171 # Send packet that should be rejected without logging.
7172 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7173 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7174 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
7175 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7176
7177 # Send packet that should be rejected with logging.
7178 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7179 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7180 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
7181 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7182
7183 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
7184
7185 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
7186 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
7187 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
7188 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
7189 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
7190 ])
7191
7192 OVN_CLEANUP([hv])
7193 AT_CLEANUP
7194
7195
7196 AT_SETUP([ovn -- ACL rate-limited logging])
7197 AT_KEYWORDS([ovn])
7198 ovn_start
7199
7200 net_add n1
7201
7202 sim_add hv
7203 as hv
7204 ovs-vsctl add-br br-phys
7205 ovn_attach n1 br-phys 192.168.0.1
7206 for i in lp1 lp2; do
7207 ovs-vsctl -- add-port br-int $i -- \
7208 set interface $i external-ids:iface-id=$i \
7209 options:tx_pcap=hv/$i-tx.pcap \
7210 options:rxq_pcap=hv/$i-rx.pcap
7211 done
7212
7213 lp1_mac="f0:00:00:00:00:01"
7214 lp1_ip="192.168.1.2"
7215
7216 lp2_mac="f0:00:00:00:00:02"
7217 lp2_ip="192.168.1.3"
7218
7219 ovn-nbctl ls-add lsw0
7220 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7221 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7222 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
7223 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
7224 ovn-nbctl --wait=sb sync
7225
7226
7227 # Add an ACL that rate-limits logs at 10 per second.
7228 ovn-nbctl meter-add http-rl1 drop 10 pktps
7229 ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
7230
7231 # Add an ACL that rate-limits logs at 5 per second.
7232 ovn-nbctl meter-add http-rl2 drop 5 pktps
7233 ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
7234
7235 # Add an ACL that doesn't rate-limit logs.
7236 ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
7237 ovn-nbctl --wait=hv sync
7238
7239 # For each ACL, send 100 packets.
7240 for i in `seq 1 100`; do
7241 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)'
7242
7243 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)'
7244
7245 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)'
7246 done
7247
7248 # The rate at which packets are sent is highly system-dependent, so we
7249 # can't count on precise drop counts. To work around that, we just
7250 # check that exactly 100 "http-acl3" actions were logged and that there
7251 # were more "http-acl1" actions than "http-acl2" ones.
7252 OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
7253
7254 # On particularly slow or overloaded systems, the transmission rate may
7255 # be lower than the configured meter rate. To prevent false test
7256 # failures, we check the duration count of the meter, and if it's
7257 # greater than nine seconds, just skip the test.
7258 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/')
7259
7260 echo "Meter duration: $d_secs"
7261 AT_SKIP_IF([test $d_secs -gt 9])
7262
7263 # Print some information that may help debugging.
7264 as hv ovs-appctl -t ovn-controller meter-table-list
7265 as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
7266
7267 n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
7268 n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
7269 n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
7270
7271 AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
7272 AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
7273
7274 OVN_CLEANUP([hv])
7275 AT_CLEANUP
7276
7277
7278 AT_SETUP([ovn -- DSCP marking and meter check])
7279 AT_KEYWORDS([ovn])
7280 ovn_start
7281
7282 ovn-nbctl ls-add lsw0
7283 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7284 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7285 ovn-nbctl --wait=sb lsp-add lsw0 lp3
7286 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
7287 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
7288 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
7289 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
7290 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
7291 ovn-nbctl --wait=sb sync
7292 net_add n1
7293 sim_add hv
7294 as hv
7295 ovs-vsctl add-br br-phys
7296 ovn_attach n1 br-phys 192.168.0.1
7297 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
7298 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
7299
7300 AT_CAPTURE_FILE([trace])
7301 ovn_trace () {
7302 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7303 }
7304
7305 # Extracts nw_tos from the final flow from ofproto/trace output and prints
7306 # it on stdout. Prints "none" if no nw_tos was included.
7307 get_final_nw_tos() {
7308 if flow=$(grep '^Final flow:' stdout); then :; else
7309 # The output didn't have a final flow.
7310 return 99
7311 fi
7312
7313 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
7314 case $tos in
7315 '') echo none ;;
7316 *) echo $tos ;;
7317 esac
7318 }
7319
7320 # check_tos TOS
7321 #
7322 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
7323 check_tos() {
7324 # First check with ovn-trace for logical flows.
7325 echo "checking for tos $1"
7326 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
7327 echo 'output("lp2");') > expout
7328 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])
7329
7330 # Then re-check with ofproto/trace for a physical packet.
7331 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])
7332 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
7333 ])
7334 }
7335
7336 # check at L2
7337 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");
7338 ])
7339 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])
7340 AT_CHECK([get_final_nw_tos], [0], [none
7341 ])
7342
7343 # check at L3 without dscp marking
7344 check_tos 0
7345
7346 # Mark DSCP with a valid value
7347 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)
7348 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
7349 ])
7350 check_tos 48
7351
7352 # check at hv without qos meter
7353 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7354 ])
7355
7356 # Update the meter rate
7357 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
7358
7359 # check at hv with a qos meter table
7360 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
7361 ])
7362 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
7363 ])
7364
7365 # Update the DSCP marking
7366 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
7367 check_tos 63
7368
7369 # Update the meter rate
7370 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
7371
7372 # check at hv with a qos meter table
7373 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
7374 ])
7375 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
7376 ])
7377
7378 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
7379 check_tos 63
7380
7381 # Disable DSCP marking
7382 ovn-nbctl --wait=hv qos-del lsw0
7383 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
7384 ])
7385 check_tos 0
7386
7387 # check at hv without qos meter
7388 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7389 ])
7390
7391 # check meter with chassis not resident
7392 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
7393 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
7394 ])
7395
7396 # check no meter table
7397 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7398 ])
7399 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
7400 ])
7401
7402 OVN_CLEANUP([hv])
7403 AT_CLEANUP
7404
7405 AT_SETUP([ovn -- read-only sb db:ptcp access])
7406 AT_SKIP_IF([test $HAVE_PYTHON = no])
7407
7408 : > .$1.db.~lock~
7409 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7410
7411 # Add read-only remote to sb ovsdb-server
7412 AT_CHECK(
7413 [ovsdb-tool transact ovn-sb.db \
7414 ['["OVN_Southbound",
7415 {"op": "insert",
7416 "table": "SB_Global",
7417 "row": {
7418 "connections": ["set", [["named-uuid", "xyz"]]]}},
7419 {"op": "insert",
7420 "table": "Connection",
7421 "uuid-name": "xyz",
7422 "row": {"target": "ptcp:0:127.0.0.1",
7423 "read_only": true}}]']], [0], [ignore], [ignore])
7424
7425 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
7426
7427 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7428
7429 # read-only accesses should succeed
7430 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
7431 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
7432
7433 # write access should fail
7434 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
7435 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
7436 ])
7437
7438 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7439 AT_CLEANUP
7440
7441 AT_SETUP([ovn -- read-only sb db:pssl access])
7442 AT_SKIP_IF([test $HAVE_PYTHON = no])
7443 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7444 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7445 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7446 \\]"])
7447
7448 : > .$1.db.~lock~
7449 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7450
7451 # Add read-only remote to sb ovsdb-server
7452 AT_CHECK(
7453 [ovsdb-tool transact ovn-sb.db \
7454 ['["OVN_Southbound",
7455 {"op": "insert",
7456 "table": "SB_Global",
7457 "row": {
7458 "connections": ["set", [["named-uuid", "xyz"]]]}},
7459 {"op": "insert",
7460 "table": "Connection",
7461 "uuid-name": "xyz",
7462 "row": {"target": "pssl:0:127.0.0.1",
7463 "read_only": true}}]']], [0], [ignore], [ignore])
7464
7465 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
7466 --remote=db:OVN_Southbound,SB_Global,connections \
7467 --private-key="$PKIDIR/testpki-privkey2.pem" \
7468 --certificate="$PKIDIR/testpki-cert2.pem" \
7469 --ca-cert="$PKIDIR/testpki-cacert.pem" \
7470 ovn-sb.db
7471
7472 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7473
7474 # read-only accesses should succeed
7475 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7476 --private-key=$PKIDIR/testpki-privkey.pem \
7477 --certificate=$PKIDIR/testpki-cert.pem \
7478 --ca-cert=$PKIDIR/testpki-cacert.pem \
7479 list SB_Global], [0], [stdout], [ignore])
7480 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7481 --private-key=$PKIDIR/testpki-privkey.pem \
7482 --certificate=$PKIDIR/testpki-cert.pem \
7483 --ca-cert=$PKIDIR/testpki-cacert.pem \
7484 list Connection], [0], [stdout], [ignore])
7485
7486 # write access should fail
7487 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7488 --private-key=$PKIDIR/testpki-privkey.pem \
7489 --certificate=$PKIDIR/testpki-cert.pem \
7490 --ca-cert=$PKIDIR/testpki-cacert.pem \
7491 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
7492 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
7493 ])
7494
7495 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7496 AT_CLEANUP
7497
7498 AT_SETUP([ovn -- nb connection/ssl commands])
7499 AT_SKIP_IF([test $HAVE_PYTHON = no])
7500 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7501 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7502 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7503 \\]"])
7504
7505 : > .$1.db.~lock~
7506 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
7507
7508 # Start nb db server using db connection/ssl entries (unpopulated initially)
7509 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
7510 --remote=db:OVN_Northbound,NB_Global,connections \
7511 --private-key=db:OVN_Northbound,SSL,private_key \
7512 --certificate=db:OVN_Northbound,SSL,certificate \
7513 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
7514 ovn-nb.db
7515
7516 # Populate SSL configuration entries in nb db
7517 AT_CHECK(
7518 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
7519 $PKIDIR/testpki-cert.pem \
7520 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
7521
7522 # Populate a passive SSL connection in nb db
7523 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
7524
7525 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7526
7527 # Verify SSL connetivity to nb db server
7528 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7529 --private-key=$PKIDIR/testpki-privkey.pem \
7530 --certificate=$PKIDIR/testpki-cert.pem \
7531 --ca-cert=$PKIDIR/testpki-cacert.pem \
7532 list NB_Global],
7533 [0], [stdout], [ignore])
7534 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7535 --private-key=$PKIDIR/testpki-privkey.pem \
7536 --certificate=$PKIDIR/testpki-cert.pem \
7537 --ca-cert=$PKIDIR/testpki-cacert.pem \
7538 list Connection],
7539 [0], [stdout], [ignore])
7540 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7541 --private-key=$PKIDIR/testpki-privkey.pem \
7542 --certificate=$PKIDIR/testpki-cert.pem \
7543 --ca-cert=$PKIDIR/testpki-cacert.pem \
7544 get-connection],
7545 [0], [stdout], [ignore])
7546
7547 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7548 AT_CLEANUP
7549
7550 AT_SETUP([ovn -- sb connection/ssl commands])
7551 AT_SKIP_IF([test $HAVE_PYTHON = no])
7552 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7553 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7554 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7555 \\]"])
7556
7557 : > .$1.db.~lock~
7558 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7559
7560 # Start sb db server using db connection/ssl entries (unpopulated initially)
7561 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
7562 --remote=db:OVN_Southbound,SB_Global,connections \
7563 --private-key=db:OVN_Southbound,SSL,private_key \
7564 --certificate=db:OVN_Southbound,SSL,certificate \
7565 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
7566 ovn-sb.db
7567
7568 # Populate SSL configuration entries in sb db
7569 AT_CHECK(
7570 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
7571 $PKIDIR/testpki-cert.pem \
7572 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
7573
7574 # Populate a passive SSL connection in sb db
7575 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
7576
7577 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7578
7579 # Verify SSL connetivity to sb db server
7580 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7581 --private-key=$PKIDIR/testpki-privkey.pem \
7582 --certificate=$PKIDIR/testpki-cert.pem \
7583 --ca-cert=$PKIDIR/testpki-cacert.pem \
7584 list SB_Global],
7585 [0], [stdout], [ignore])
7586 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7587 --private-key=$PKIDIR/testpki-privkey.pem \
7588 --certificate=$PKIDIR/testpki-cert.pem \
7589 --ca-cert=$PKIDIR/testpki-cacert.pem \
7590 list Connection],
7591 [0], [stdout], [ignore])
7592 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7593 --private-key=$PKIDIR/testpki-privkey.pem \
7594 --certificate=$PKIDIR/testpki-cert.pem \
7595 --ca-cert=$PKIDIR/testpki-cacert.pem \
7596 get-connection],
7597 [0], [stdout], [ignore])
7598
7599 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7600 AT_CLEANUP
7601
7602 AT_SETUP([ovn -- nested containers])
7603 ovn_start
7604
7605 # Physical network:
7606 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
7607
7608 # Logical network:
7609 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
7610 # and "bar" (192.168.2.0/24). They are all connected to router R1.
7611
7612 ovn-nbctl lr-add R1
7613 ovn-nbctl ls-add mgmt
7614 ovn-nbctl ls-add foo
7615 ovn-nbctl ls-add bar
7616
7617 # Connect mgmt to R1
7618 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
7619 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
7620 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
7621
7622 # Connect foo to R1
7623 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
7624 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7625 options:router-port=foo addresses=\"00:00:00:01:02:03\"
7626
7627 # Connect bar to R1
7628 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
7629 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7630 options:router-port=bar addresses=\"00:00:00:01:02:04\"
7631
7632 # "mgmt" has VM1 and VM2 connected
7633 ovn-nbctl lsp-add mgmt vm1 \
7634 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
7635
7636 ovn-nbctl lsp-add mgmt vm2 \
7637 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
7638
7639 # "foo1" and "foo2" are containers belonging to switch "foo"
7640 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
7641 ovn-nbctl lsp-add foo foo1 vm1 1 \
7642 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
7643
7644 ovn-nbctl lsp-add foo foo2 vm2 2 \
7645 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7646
7647 # "bar1" and "bar2" are containers belonging to switch "bar"
7648 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
7649 ovn-nbctl lsp-add bar bar1 vm1 2 \
7650 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
7651
7652 ovn-nbctl lsp-add bar bar2 vm2 1 \
7653 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
7654
7655 # bar3 is a standalone VM belonging to switch "bar"
7656 ovn-nbctl lsp-add bar bar3 \
7657 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
7658
7659 # Create two hypervisor and create OVS ports corresponding to logical ports.
7660 net_add n1
7661
7662 sim_add hv1
7663 as hv1
7664 ovs-vsctl add-br br-phys
7665 ovn_attach n1 br-phys 192.168.0.1
7666 ovs-vsctl -- add-port br-int vm1 -- \
7667 set interface vm1 external-ids:iface-id=vm1 \
7668 options:tx_pcap=hv1/vm1-tx.pcap \
7669 options:rxq_pcap=hv1/vm1-rx.pcap \
7670 ofport-request=1
7671
7672 ovs-vsctl -- add-port br-int bar3 -- \
7673 set interface bar3 external-ids:iface-id=bar3 \
7674 options:tx_pcap=hv1/bar3-tx.pcap \
7675 options:rxq_pcap=hv1/bar3-rx.pcap \
7676 ofport-request=2
7677
7678 sim_add hv2
7679 as hv2
7680 ovs-vsctl add-br br-phys
7681 ovn_attach n1 br-phys 192.168.0.2
7682 ovs-vsctl -- add-port br-int vm2 -- \
7683 set interface vm2 external-ids:iface-id=vm2 \
7684 options:tx_pcap=hv2/vm2-tx.pcap \
7685 options:rxq_pcap=hv2/vm2-rx.pcap \
7686 ofport-request=1
7687
7688 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7689 # packets for ARP resolution (native tunneling doesn't queue packets
7690 # for ARP resolution).
7691 OVN_POPULATE_ARP
7692
7693 # Allow some time for ovn-northd and ovn-controller to catch up.
7694 # XXX This should be more systematic.
7695 sleep 1
7696
7697 ip_to_hex() {
7698 printf "%02x%02x%02x%02x" "$@"
7699 }
7700
7701 # Send ip packets between foo1 and foo2 (same switch, different HVs and
7702 # different VLAN tags).
7703 src_mac="f00000010205"
7704 dst_mac="f00000010206"
7705 src_ip=`ip_to_hex 192 168 1 2`
7706 dst_ip=`ip_to_hex 192 168 1 3`
7707 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7708 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7709
7710 # expected packet at foo2
7711 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7712 echo $packet > expected
7713 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7714
7715 # Send ip packets between foo1 and bar2 (different switch, different HV)
7716 src_mac="f00000010205"
7717 dst_mac="000000010203"
7718 src_ip=`ip_to_hex 192 168 1 2`
7719 dst_ip=`ip_to_hex 192 168 2 3`
7720 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7721 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7722
7723 # expected packet at bar2
7724 src_mac="000000010204"
7725 dst_mac="f00000010208"
7726 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7727 echo $packet >> expected
7728 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7729
7730 # Send ip packets between foo1 and bar1
7731 # (different switch, loopback to same vm but different tag)
7732 src_mac="f00000010205"
7733 dst_mac="000000010203"
7734 src_ip=`ip_to_hex 192 168 1 2`
7735 dst_ip=`ip_to_hex 192 168 2 2`
7736 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7737 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7738
7739 # expected packet at bar1
7740 src_mac="000000010204"
7741 dst_mac="f00000010207"
7742 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7743 echo $packet > expected1
7744 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7745
7746 # Send ip packets between bar1 and bar3
7747 # (same switch. But one is container and another is a standalone VM)
7748 src_mac="f00000010207"
7749 dst_mac="f00000010209"
7750 src_ip=`ip_to_hex 192 168 2 2`
7751 dst_ip=`ip_to_hex 192 168 2 3`
7752 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7753 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7754
7755 # expected packet at bar3
7756 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7757 echo $packet > expected
7758 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7759
7760 # Send ip packets between foo1 and vm1.
7761 (different switch, container to the VM hosting it.)
7762 src_mac="f00000010205"
7763 dst_mac="000000010203"
7764 src_ip=`ip_to_hex 192 168 1 2`
7765 dst_ip=`ip_to_hex 172 16 1 2`
7766 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7767 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7768
7769 # expected packet at vm1
7770 src_mac="000000010202"
7771 dst_mac="f00000010203"
7772 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7773 echo $packet >> expected1
7774 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7775
7776 # Send packets from vm1 to bar1.
7777 (different switch, A hosting VM to a container inside it)
7778 src_mac="f00000010203"
7779 dst_mac="000000010202"
7780 src_ip=`ip_to_hex 172 16 1 2`
7781 dst_ip=`ip_to_hex 192 168 2 2`
7782 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7783 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7784
7785 # expected packet at vm1
7786 src_mac="000000010204"
7787 dst_mac="f00000010207"
7788 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7789 echo $packet >> expected1
7790 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7791
7792 # Send broadcast packet from foo1. foo1 should not receive the same packet.
7793 src_mac="f00000010205"
7794 dst_mac="ffffffffffff"
7795 src_ip=`ip_to_hex 192 168 1 2`
7796 dst_ip=`ip_to_hex 255 255 255 255`
7797 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7798 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7799
7800 # expected packet at VM1
7801 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7802
7803 OVN_CLEANUP([hv1],[hv2])
7804
7805 AT_CLEANUP
7806
7807 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7808 AT_SKIP_IF([test $HAVE_PYTHON = no])
7809 ovn_start
7810
7811 # Logical network:
7812 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7813 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7814 # (192.168.2.0/24) connected to it.
7815 #
7816 # R2 and R3 are gateway routers.
7817 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7818 # connected to it. Note how both alice and bob have the same subnet behind it.
7819 # We are trying to simulate external network via those 2 switches. In real
7820 # world the switch ports of these switches will have addresses set as "unknown"
7821 # to make them learning switches. Or those switches will be "localnet" ones.
7822
7823 # Create three hypervisors and create OVS ports corresponding to logical ports.
7824 net_add n1
7825
7826 sim_add hv1
7827 as hv1
7828 ovs-vsctl add-br br-phys
7829 ovn_attach n1 br-phys 192.168.0.1
7830 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7831 set interface hv1-vif1 external-ids:iface-id=foo1 \
7832 options:tx_pcap=hv1/vif1-tx.pcap \
7833 options:rxq_pcap=hv1/vif1-rx.pcap \
7834 ofport-request=1
7835
7836 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7837 set interface hv1-vif2 external-ids:iface-id=bar1 \
7838 options:tx_pcap=hv1/vif2-tx.pcap \
7839 options:rxq_pcap=hv1/vif2-rx.pcap \
7840 ofport-request=2
7841
7842 sim_add hv2
7843 as hv2
7844 ovs-vsctl add-br br-phys
7845 ovn_attach n1 br-phys 192.168.0.2
7846 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7847 set interface hv2-vif1 external-ids:iface-id=alice1 \
7848 options:tx_pcap=hv2/vif1-tx.pcap \
7849 options:rxq_pcap=hv2/vif1-rx.pcap \
7850 ofport-request=1
7851
7852 sim_add hv3
7853 as hv3
7854 ovs-vsctl add-br br-phys
7855 ovn_attach n1 br-phys 192.168.0.3
7856 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7857 set interface hv3-vif1 external-ids:iface-id=bob1 \
7858 options:tx_pcap=hv3/vif1-tx.pcap \
7859 options:rxq_pcap=hv3/vif1-rx.pcap \
7860 ofport-request=1
7861
7862
7863 ovn-nbctl create Logical_Router name=R1
7864 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7865 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7866
7867 ovn-nbctl ls-add foo
7868 ovn-nbctl ls-add bar
7869 ovn-nbctl ls-add alice
7870 ovn-nbctl ls-add bob
7871 ovn-nbctl ls-add join
7872
7873 # Connect foo to R1
7874 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7875 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7876 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7877
7878 # Connect bar to R1
7879 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7880 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7881 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7882
7883 # Connect alice to R2
7884 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7885 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7886 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7887
7888 # Connect bob to R3
7889 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7890 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7891 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7892
7893 # Connect R1 to join
7894 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7895 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7896 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7897
7898 # Connect R2 to join
7899 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7900 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7901 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7902
7903 # Connect R3 to join
7904 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7905 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7906 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7907
7908 # Install static routes with source ip address as the policy for routing.
7909 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7910 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7911 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7912
7913 # Install static routes with destination ip address as the policy for routing.
7914 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7915
7916 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7917
7918 # Create logical port foo1 in foo
7919 ovn-nbctl lsp-add foo foo1 \
7920 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7921
7922 # Create logical port bar1 in bar
7923 ovn-nbctl lsp-add bar bar1 \
7924 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7925
7926 # Create logical port alice1 in alice
7927 ovn-nbctl lsp-add alice alice1 \
7928 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7929
7930 # Create logical port bob1 in bob
7931 ovn-nbctl lsp-add bob bob1 \
7932 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7933
7934 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7935 # packets for ARP resolution (native tunneling doesn't queue packets
7936 # for ARP resolution).
7937 OVN_POPULATE_ARP
7938
7939 # Allow some time for ovn-northd and ovn-controller to catch up.
7940 # XXX This should be more systematic.
7941 sleep 1
7942
7943 ip_to_hex() {
7944 printf "%02x%02x%02x%02x" "$@"
7945 }
7946 trim_zeros() {
7947 sed 's/\(00\)\{1,\}$//'
7948 }
7949
7950 # Send ip packets between foo1 and bar1
7951 # (East-west traffic should flow normally)
7952 src_mac="f00000010203"
7953 dst_mac="000001010203"
7954 src_ip=`ip_to_hex 192 168 1 2`
7955 dst_ip=`ip_to_hex 192 168 2 2`
7956 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7957 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7958
7959 # Send ip packets between foo1 and alice1
7960 src_mac="f00000010203"
7961 dst_mac="000001010203"
7962 src_ip=`ip_to_hex 192 168 1 2`
7963 dst_ip=`ip_to_hex 172 16 1 3`
7964 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7965 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7966 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
7967
7968 # Send ip packets between bar1 and bob1
7969 src_mac="f00000010204"
7970 dst_mac="000001010204"
7971 src_ip=`ip_to_hex 192 168 2 2`
7972 dst_ip=`ip_to_hex 172 16 1 4`
7973 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7974 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7975 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7976
7977 # Packet to expect at bar1
7978 src_mac="000001010204"
7979 dst_mac="f00000010204"
7980 src_ip=`ip_to_hex 192 168 1 2`
7981 dst_ip=`ip_to_hex 192 168 2 2`
7982 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7983 echo $expected > expected
7984 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7985
7986 # Packet to Expect at alice1
7987 src_mac="000002010203"
7988 dst_mac="f00000010205"
7989 src_ip=`ip_to_hex 192 168 1 2`
7990 dst_ip=`ip_to_hex 172 16 1 3`
7991 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7992 echo $expected > expected
7993 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7994
7995 # Packet to Expect at bob1
7996 src_mac="000003010203"
7997 dst_mac="f00000010206"
7998 src_ip=`ip_to_hex 192 168 2 2`
7999 dst_ip=`ip_to_hex 172 16 1 4`
8000 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8001 echo $expected > expected
8002 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
8003
8004 OVN_CLEANUP([hv1],[hv2],[hv3])
8005
8006 AT_CLEANUP
8007
8008 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
8009 AT_SKIP_IF([test $HAVE_PYTHON = no])
8010 ovn_start
8011
8012 ovn-nbctl ls-add ls1
8013
8014 ovn-nbctl lsp-add ls1 ls1-lp1 \
8015 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
8016
8017 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
8018
8019 ovn-nbctl lsp-add ls1 ls1-lp2 \
8020 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
8021
8022 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
8023
8024 DNS1=`ovn-nbctl create DNS records={}`
8025 DNS2=`ovn-nbctl create DNS records={}`
8026
8027 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
8028 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
8029 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
8030
8031 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
8032
8033 net_add n1
8034 sim_add hv1
8035
8036 as hv1
8037 ovs-vsctl add-br br-phys
8038 ovn_attach n1 br-phys 192.168.0.1
8039 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8040 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
8041 options:tx_pcap=hv1/vif1-tx.pcap \
8042 options:rxq_pcap=hv1/vif1-rx.pcap \
8043 ofport-request=1
8044
8045 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8046 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
8047 options:tx_pcap=hv1/vif2-tx.pcap \
8048 options:rxq_pcap=hv1/vif2-rx.pcap \
8049 ofport-request=2
8050
8051 OVN_POPULATE_ARP
8052 sleep 2
8053 as hv1 ovs-vsctl show
8054
8055 echo "*************************"
8056 ovn-sbctl list DNS
8057 echo "*************************"
8058
8059 ip_to_hex() {
8060 printf "%02x%02x%02x%02x" "$@"
8061 }
8062
8063 reset_pcap_file() {
8064 local iface=$1
8065 local pcap_file=$2
8066 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8067 options:rxq_pcap=dummy-rx.pcap
8068 rm -f ${pcap_file}*.pcap
8069 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8070 options:rxq_pcap=${pcap_file}-rx.pcap
8071 }
8072
8073 # set_dns_params host_name
8074 # Sets the dns_req_data and dns_resp_data
8075 set_dns_params() {
8076 local hname=$1
8077 local ttl=00000e10
8078 an_count=0001
8079 type=0001
8080 case $hname in
8081 vm1)
8082 # vm1.ovn.org
8083 query_name=03766d31036f766e036f726700
8084 # IPv4 address - 10.0.0.4
8085 expected_dns_answer=${query_name}00010001${ttl}00040a000004
8086 ;;
8087 vm2)
8088 # vm2.ovn.org
8089 query_name=03766d32036f766e036f726700
8090 # IPv4 address - 10.0.0.6
8091 expected_dns_answer=${query_name}00010001${ttl}00040a000006
8092 # IPv4 address - 20.0.0.4
8093 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
8094 an_count=0002
8095 ;;
8096 vm3)
8097 # vm3.ovn.org
8098 query_name=03766d33036f766e036f726700
8099 # IPv4 address - 40.0.0.4
8100 expected_dns_answer=${query_name}00010001${ttl}000428000004
8101 ;;
8102 vm1_ipv6_only)
8103 # vm1.ovn.org
8104 query_name=03766d31036f766e036f726700
8105 # IPv6 address - aef0::4
8106 type=001c
8107 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
8108 ;;
8109 vm1_ipv4_v6)
8110 # vm1.ovn.org
8111 query_name=03766d31036f766e036f726700
8112 type=00ff
8113 an_count=0002
8114 # IPv4 address - 10.0.0.4
8115 # IPv6 address - aef0::4
8116 expected_dns_answer=${query_name}00010001${ttl}00040a000004
8117 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
8118 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
8119 ;;
8120 vm1_invalid_type)
8121 # vm1.ovn.org
8122 query_name=03766d31036f766e036f726700
8123 # IPv6 address - aef0::4
8124 type=0002
8125 ;;
8126 vm1_incomplete)
8127 # set type to none
8128 type=''
8129 esac
8130 # TTL - 3600
8131 local dns_req_header=010201200001000000000000
8132 local dns_resp_header=010281200001${an_count}00000000
8133 dns_req_data=${dns_req_header}${query_name}${type}0001
8134 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
8135 }
8136
8137 # This shell function sends a DNS request packet
8138 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
8139 test_dns() {
8140 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
8141 local dns_query_data=$7
8142 shift; shift; shift; shift; shift; shift; shift;
8143 # Packet size => IPv4 header (20) + UDP header (8) +
8144 # DNS data (header + query)
8145 ip_len=`expr 28 + ${#dns_query_data} / 2`
8146 udp_len=`expr $ip_len - 20`
8147 ip_len=$(printf "%x" $ip_len)
8148 udp_len=$(printf "%x" $udp_len)
8149 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
8150 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
8151 # dns data
8152 request=${request}${dns_query_data}
8153
8154 if test $dns_reply != 0; then
8155 local dns_reply=$1
8156 ip_len=`expr 28 + ${#dns_reply} / 2`
8157 udp_len=`expr $ip_len - 20`
8158 ip_len=$(printf "%x" $ip_len)
8159 udp_len=$(printf "%x" $udp_len)
8160 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
8161 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
8162 echo $reply >> $inport.expected
8163 else
8164 for outport; do
8165 echo $request >> $outport.expected
8166 done
8167 fi
8168 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
8169 }
8170
8171 test_dns6() {
8172 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
8173 local dns_query_data=$7
8174 shift; shift; shift; shift; shift; shift; shift;
8175 # Packet size => UDP header (8) +
8176 # DNS data (header + query)
8177 ip_len=`expr 8 + ${#dns_query_data} / 2`
8178 udp_len=$ip_len
8179 ip_len=$(printf "%x" $ip_len)
8180 udp_len=$(printf "%x" $udp_len)
8181 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
8182 request=${request}9234003500${udp_len}0000
8183 #dns data
8184 request=${request}${dns_query_data}
8185
8186 if test $dns_reply != 0; then
8187 local dns_reply=$1
8188 ip_len=`expr 8 + ${#dns_reply} / 2`
8189 udp_len=$ip_len
8190 ip_len=$(printf "%x" $ip_len)
8191 udp_len=$(printf "%x" $udp_len)
8192 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
8193 reply=${reply}0035923400${udp_len}0000${dns_reply}
8194 echo $reply >> $inport.expected
8195 else
8196 for outport; do
8197 echo $request >> $outport.expected
8198 done
8199 fi
8200 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
8201 }
8202
8203 AT_CAPTURE_FILE([ofctl_monitor0.log])
8204 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8205 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8206
8207 set_dns_params vm2
8208 src_ip=`ip_to_hex 10 0 0 4`
8209 dst_ip=`ip_to_hex 10 0 0 1`
8210 dns_reply=1
8211 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8212
8213 # NXT_RESUMEs should be 1.
8214 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8215
8216 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8217 cat 1.expected | cut -c -48 > expout
8218 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
8219 # Skipping the IPv4 checksum.
8220 cat 1.expected | cut -c 53- > expout
8221 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
8222
8223 reset_pcap_file hv1-vif1 hv1/vif1
8224 reset_pcap_file hv1-vif2 hv1/vif2
8225 rm -f 1.expected
8226 rm -f 2.expected
8227
8228 set_dns_params vm1
8229 src_ip=`ip_to_hex 10 0 0 6`
8230 dst_ip=`ip_to_hex 10 0 0 1`
8231 dns_reply=1
8232 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8233
8234 # NXT_RESUMEs should be 2.
8235 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8236
8237 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8238 cat 2.expected | cut -c -48 > expout
8239 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8240 # Skipping the IPv4 checksum.
8241 cat 2.expected | cut -c 53- > expout
8242 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8243
8244 reset_pcap_file hv1-vif1 hv1/vif1
8245 reset_pcap_file hv1-vif2 hv1/vif2
8246 rm -f 1.expected
8247 rm -f 2.expected
8248
8249 # Clear the query name options for ls1-lp2
8250 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
8251
8252 set_dns_params vm2
8253 src_ip=`ip_to_hex 10 0 0 4`
8254 dst_ip=`ip_to_hex 10 0 0 1`
8255 dns_reply=0
8256 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
8257
8258 # NXT_RESUMEs should be 3.
8259 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8260
8261 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8262 AT_CHECK([cat 1.packets], [0], [])
8263
8264 reset_pcap_file hv1-vif1 hv1/vif1
8265 reset_pcap_file hv1-vif2 hv1/vif2
8266 rm -f 1.expected
8267 rm -f 2.expected
8268
8269 # Clear the query name for ls1-lp1
8270 # Since ls1 has no query names configued,
8271 # ovn-northd should not add the DNS flows.
8272 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
8273
8274 set_dns_params vm1
8275 src_ip=`ip_to_hex 10 0 0 6`
8276 dst_ip=`ip_to_hex 10 0 0 1`
8277 dns_reply=0
8278 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8279
8280 # NXT_RESUMEs should be 3 only.
8281 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8282
8283 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8284 AT_CHECK([cat 2.packets], [0], [])
8285
8286 reset_pcap_file hv1-vif1 hv1/vif1
8287 reset_pcap_file hv1-vif2 hv1/vif2
8288 rm -f 1.expected
8289 rm -f 2.expected
8290
8291 # Test IPv6 (AAAA records) using IPv4 packet.
8292 # Add back the DNS options for ls1-lp1.
8293 ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
8294
8295 set_dns_params vm1_ipv6_only
8296 src_ip=`ip_to_hex 10 0 0 6`
8297 dst_ip=`ip_to_hex 10 0 0 1`
8298 dns_reply=1
8299 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8300
8301 # NXT_RESUMEs should be 4.
8302 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8303
8304 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8305 cat 2.expected | cut -c -48 > expout
8306 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8307 # Skipping the IPv4 checksum.
8308 cat 2.expected | cut -c 53- > expout
8309 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8310
8311 reset_pcap_file hv1-vif1 hv1/vif1
8312 reset_pcap_file hv1-vif2 hv1/vif2
8313 rm -f 1.expected
8314 rm -f 2.expected
8315
8316 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
8317 set_dns_params vm1_ipv4_v6
8318 src_ip=`ip_to_hex 10 0 0 6`
8319 dst_ip=`ip_to_hex 10 0 0 1`
8320 dns_reply=1
8321 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8322
8323 # NXT_RESUMEs should be 5.
8324 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8325
8326 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8327 cat 2.expected | cut -c -48 > expout
8328 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8329 # Skipping the IPv4 checksum.
8330 cat 2.expected | cut -c 53- > expout
8331 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8332
8333 reset_pcap_file hv1-vif1 hv1/vif1
8334 reset_pcap_file hv1-vif2 hv1/vif2
8335 rm -f 1.expected
8336 rm -f 2.expected
8337
8338 # Invalid type.
8339 set_dns_params vm1_invalid_type
8340 src_ip=`ip_to_hex 10 0 0 6`
8341 dst_ip=`ip_to_hex 10 0 0 1`
8342 dns_reply=0
8343 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8344
8345 # NXT_RESUMEs should be 6.
8346 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8347
8348 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8349 AT_CHECK([cat 2.packets], [0], [])
8350
8351 reset_pcap_file hv1-vif1 hv1/vif1
8352 reset_pcap_file hv1-vif2 hv1/vif2
8353 rm -f 1.expected
8354 rm -f 2.expected
8355
8356 # Incomplete DNS packet.
8357 set_dns_params vm1_incomplete
8358 src_ip=`ip_to_hex 10 0 0 6`
8359 dst_ip=`ip_to_hex 10 0 0 1`
8360 dns_reply=0
8361 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8362
8363 # NXT_RESUMEs should be 7.
8364 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8365
8366 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8367 AT_CHECK([cat 2.packets], [0], [])
8368
8369 reset_pcap_file hv1-vif1 hv1/vif1
8370 reset_pcap_file hv1-vif2 hv1/vif2
8371 rm -f 1.expected
8372 rm -f 2.expected
8373
8374 # Add one more DNS record to the ls1.
8375 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
8376
8377 set_dns_params vm3
8378 src_ip=`ip_to_hex 10 0 0 4`
8379 dst_ip=`ip_to_hex 10 0 0 1`
8380 dns_reply=1
8381 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8382
8383 # NXT_RESUMEs should be 8.
8384 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8385
8386 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8387 cat 1.expected | cut -c -48 > expout
8388 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
8389 # Skipping the IPv4 checksum.
8390 cat 1.expected | cut -c 53- > expout
8391 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
8392
8393 reset_pcap_file hv1-vif1 hv1/vif1
8394 reset_pcap_file hv1-vif2 hv1/vif2
8395 rm -f 1.expected
8396 rm -f 2.expected
8397
8398 # Try DNS query over IPv6
8399 set_dns_params vm1
8400 src_ip=aef00000000000000000000000000004
8401 dst_ip=aef00000000000000000000000000001
8402 dns_reply=1
8403 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8404
8405 # NXT_RESUMEs should be 9.
8406 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8407
8408 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8409 # Skipping the UDP checksum.
8410 cat 1.expected | cut -c 1-120,125- > expout
8411 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
8412
8413 reset_pcap_file hv1-vif1 hv1/vif1
8414 reset_pcap_file hv1-vif2 hv1/vif2
8415 rm -f 1.expected
8416 rm -f 2.expected
8417
8418 OVN_CLEANUP([hv1])
8419
8420 AT_CLEANUP
8421
8422 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
8423 AT_SKIP_IF([test $HAVE_PYTHON = no])
8424 ovn_start
8425
8426 net_add n1
8427
8428 sim_add hv1
8429 as hv1
8430 ovs-vsctl add-br br-phys
8431 ovn_attach n1 br-phys 192.168.0.1
8432 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8433 set interface hv1-vif1 external-ids:iface-id=foo1 \
8434 options:tx_pcap=hv1/vif1-tx.pcap \
8435 options:rxq_pcap=hv1/vif1-rx.pcap \
8436 ofport-request=1
8437
8438 sim_add gw1
8439 as gw1
8440 ovs-vsctl add-br br-phys
8441 ovn_attach n1 br-phys 192.168.0.2
8442
8443 sim_add gw2
8444 as gw2
8445 ovs-vsctl add-br br-phys
8446 ovn_attach n1 br-phys 192.168.0.4
8447
8448 sim_add ext1
8449 as ext1
8450 ovs-vsctl add-br br-phys
8451 ovn_attach n1 br-phys 192.168.0.3
8452 ovs-vsctl -- add-port br-int ext1-vif1 -- \
8453 set interface ext1-vif1 external-ids:iface-id=outside1 \
8454 options:tx_pcap=ext1/vif1-tx.pcap \
8455 options:rxq_pcap=ext1/vif1-rx.pcap \
8456 ofport-request=1
8457
8458 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8459 # packets for ARP resolution (native tunneling doesn't queue packets
8460 # for ARP resolution).
8461 OVN_POPULATE_ARP
8462
8463 ovn-nbctl create Logical_Router name=R1
8464
8465 ovn-nbctl ls-add foo
8466 ovn-nbctl ls-add alice
8467 ovn-nbctl ls-add outside
8468
8469 # Connect foo to R1
8470 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8471 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8472 type=router options:router-port=foo \
8473 -- lsp-set-addresses rp-foo router
8474
8475 # Connect alice to R1 as distributed router gateway port on gw1
8476 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8477
8478 ovn-nbctl \
8479 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8480 chassis_name=gw1 \
8481 priority=20 -- \
8482 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8483 chassis_name=gw2 \
8484 priority=10 -- \
8485 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8486
8487 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8488 type=router options:router-port=alice \
8489 -- lsp-set-addresses rp-alice router
8490
8491 # Create logical port foo1 in foo
8492 ovn-nbctl lsp-add foo foo1 \
8493 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8494
8495 # Create logical port outside1 in outside
8496 ovn-nbctl lsp-add outside outside1 \
8497 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8498
8499 # Create localnet port in alice
8500 ovn-nbctl lsp-add alice ln-alice
8501 ovn-nbctl lsp-set-addresses ln-alice unknown
8502 ovn-nbctl lsp-set-type ln-alice localnet
8503 ovn-nbctl lsp-set-options ln-alice network_name=phys
8504
8505 # Create localnet port in outside
8506 ovn-nbctl lsp-add outside ln-outside
8507 ovn-nbctl lsp-set-addresses ln-outside unknown
8508 ovn-nbctl lsp-set-type ln-outside localnet
8509 ovn-nbctl lsp-set-options ln-outside network_name=phys
8510
8511 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8512 # mapping to the external network, is the one generating packets
8513 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8514 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8515 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8516
8517 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8518
8519 # Allow some time for ovn-northd and ovn-controller to catch up.
8520 # XXX This should be more systematic.
8521 sleep 2
8522
8523 ip_to_hex() {
8524 printf "%02x%02x%02x%02x" "$@"
8525 }
8526
8527 reset_pcap_file() {
8528 local iface=$1
8529 local pcap_file=$2
8530 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8531 options:rxq_pcap=dummy-rx.pcap
8532 rm -f ${pcap_file}*.pcap
8533 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8534 options:rxq_pcap=${pcap_file}-rx.pcap
8535 }
8536
8537 test_ip_packet()
8538 {
8539 local active_gw=$1
8540 local backup_gw=$2
8541 local backup_vswitchd_dead=$3
8542
8543 # Send ip packet between foo1 and outside1
8544 src_mac="f00000010203" # foo1 mac
8545 dst_mac="000001010203" # rp-foo mac (internal router leg)
8546 src_ip=`ip_to_hex 192 168 1 2`
8547 dst_ip=`ip_to_hex 172 16 1 3`
8548 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8549
8550 # ARP request packet to expect at outside1
8551 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8552
8553 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8554
8555 # Send ARP reply from outside1 back to the router
8556 # XXX: note, we could avoid this if we plug this port into a netns
8557 # and setup the IP address into the port, so the kernel would simply reply
8558 src_mac="000002010203"
8559 reply_mac="f00000010204"
8560 dst_ip=`ip_to_hex 172 16 1 3`
8561 src_ip=`ip_to_hex 172 16 1 1`
8562 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8563
8564 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8565
8566 OVS_WAIT_UNTIL([
8567 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8568 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8569 ])
8570
8571 # Packet to Expect at ext1 chassis, outside1 port
8572 src_mac="000002010203"
8573 dst_mac="f00000010204"
8574 src_ip=`ip_to_hex 192 168 1 2`
8575 dst_ip=`ip_to_hex 172 16 1 3`
8576 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8577 echo $expected > ext1-vif1.expected
8578 exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
8579 echo $exp_gw_ip_garp >> ext1-vif1.expected
8580 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8581
8582 if test $backup_vswitchd_dead != 1; then
8583 # Reset the file only if vswitchd in backup gw is alive
8584 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8585 fi
8586 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8587
8588 # Resend packet from foo1 to outside1
8589 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8590
8591 sleep 1
8592
8593 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8594 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8595 cat packets | grep $expected > exp
8596 # Its possible that $active_gw/br-phys_n1-tx.pcap may have received multiple
8597 # garp packets. So consider only the first packet.
8598 cat packets | grep $exp_gw_ip_garp | head -1 >> exp
8599 AT_CHECK([cat exp], [0], [expout])
8600 rm -f expout
8601 if test $backup_vswitchd_dead != 1; then
8602 # Check for backup gw only if vswitchd is alive
8603 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8604 AT_CHECK([grep $expected packets | sort], [0], [])
8605 fi
8606 }
8607
8608 test_ip_packet gw1 gw2 0
8609
8610 ovn-nbctl --timeout=3 --wait=hv \
8611 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8612 chassis_name=gw1 \
8613 priority=10 -- \
8614 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8615 chassis_name=gw2 \
8616 priority=20 -- \
8617 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8618
8619 test_ip_packet gw2 gw1 0
8620
8621 # Get the claim count of both gw1 and gw2.
8622 gw1_claim_ct=`grep "cr-alice: Claiming" gw1/ovn-controller.log | wc -l`
8623 gw2_claim_ct=`grep "cr-alice: Claiming" gw2/ovn-controller.log | wc -l`
8624
8625 # Stop ovs-vswitchd in gw2. gw1 should claim the gateway port.
8626 as gw2
8627 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
8628
8629 # gw1 should claim the cr-alice and the claim count of gw1 should be
8630 # incremented by 1.
8631 gw1_claim_ct=$((gw1_claim_ct+1))
8632
8633 OVS_WAIT_UNTIL([test $gw1_claim_ct = `cat gw1/ovn-controller.log \
8634 | grep -c "cr-alice: Claiming"`])
8635
8636 AT_CHECK([test $gw2_claim_ct = `cat gw2/ovn-controller.log | \
8637 grep -c "cr-alice: Claiming"`])
8638
8639 test_ip_packet gw1 gw2 1
8640
8641 as gw2
8642 OVS_APP_EXIT_AND_WAIT([ovn-controller])
8643 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
8644
8645 OVN_CLEANUP([hv1],[gw1],[ext1])
8646
8647 AT_CLEANUP
8648
8649 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
8650 AT_SKIP_IF([test $HAVE_PYTHON = no])
8651 ovn_start
8652
8653 net_add n1
8654
8655 sim_add hv1
8656 as hv1
8657 ovs-vsctl add-br br-phys
8658 ovn_attach n1 br-phys 192.168.0.1
8659 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8660 set interface hv1-vif1 external-ids:iface-id=foo1 \
8661 options:tx_pcap=hv1/vif1-tx.pcap \
8662 options:rxq_pcap=hv1/vif1-rx.pcap \
8663 ofport-request=1
8664
8665 sim_add gw1
8666 as gw1
8667 ovs-vsctl add-br br-phys
8668 ovn_attach n1 br-phys 192.168.0.2
8669
8670 sim_add gw2
8671 as gw2
8672 ovs-vsctl add-br br-phys
8673 ovn_attach n1 br-phys 192.168.0.4
8674
8675 sim_add ext1
8676 as ext1
8677 ovs-vsctl add-br br-phys
8678 ovn_attach n1 br-phys 192.168.0.3
8679 ovs-vsctl -- add-port br-int ext1-vif1 -- \
8680 set interface ext1-vif1 external-ids:iface-id=outside1 \
8681 options:tx_pcap=ext1/vif1-tx.pcap \
8682 options:rxq_pcap=ext1/vif1-rx.pcap \
8683 ofport-request=1
8684
8685 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8686 # packets for ARP resolution (native tunneling doesn't queue packets
8687 # for ARP resolution).
8688 OVN_POPULATE_ARP
8689
8690 ovn-nbctl create Logical_Router name=R0
8691 ovn-nbctl create Logical_Router name=R1
8692
8693 ovn-nbctl ls-add foo
8694 ovn-nbctl ls-add join
8695 ovn-nbctl ls-add alice
8696 ovn-nbctl ls-add outside
8697
8698 #Connect foo to R0
8699 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
8700 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
8701 type=router options:router-port=R0-foo \
8702 -- lsp-set-addresses foo-R0 router
8703
8704 #Connect R0 to join
8705 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
8706 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
8707 type=router options:router-port=R0-join \
8708 -- lsp-set-addresses join-R0 router
8709
8710 #Connect join to R1
8711 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
8712 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
8713 type=router options:router-port=R1-join \
8714 -- lsp-set-addresses join-R1 router
8715
8716 #add route rules
8717 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
8718 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
8719
8720 # Connect alice to R1 as distributed router gateway port on gw1
8721 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8722
8723 ovn-nbctl \
8724 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8725 chassis_name=gw1 \
8726 priority=20 -- \
8727 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8728 chassis_name=gw2 \
8729 priority=10 -- \
8730 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8731
8732 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8733 type=router options:router-port=alice \
8734 -- lsp-set-addresses rp-alice router
8735
8736 # Create logical port foo1 in foo
8737 ovn-nbctl lsp-add foo foo1 \
8738 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8739
8740 # Create logical port outside1 in outside
8741 ovn-nbctl lsp-add outside outside1 \
8742 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8743
8744 # Create localnet port in alice
8745 ovn-nbctl lsp-add alice ln-alice
8746 ovn-nbctl lsp-set-addresses ln-alice unknown
8747 ovn-nbctl lsp-set-type ln-alice localnet
8748 ovn-nbctl lsp-set-options ln-alice network_name=phys
8749
8750 # Create localnet port in outside
8751 ovn-nbctl lsp-add outside ln-outside
8752 ovn-nbctl lsp-set-addresses ln-outside unknown
8753 ovn-nbctl lsp-set-type ln-outside localnet
8754 ovn-nbctl lsp-set-options ln-outside network_name=phys
8755
8756 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8757 # mapping to the external network, is the one generating packets
8758 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8759 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8760 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8761
8762 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8763
8764 # hv1 should be in 'ref_chassis' of the ha_chasssi_group as logical
8765 # switch 'foo' can reach the router 'R1' (which has gw router port)
8766 # via foo1 -> foo -> R0 -> join -> R1
8767 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
8768 OVS_WAIT_UNTIL(
8769 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
8770 # Trim the spaces.
8771 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
8772 test "$hv1_ch_uuid" = "$ref_ch_list"])
8773
8774 # Allow some time for ovn-northd and ovn-controller to catch up.
8775 # XXX This should be more systematic.
8776 sleep 2
8777
8778 ip_to_hex() {
8779 printf "%02x%02x%02x%02x" "$@"
8780 }
8781
8782 reset_pcap_file() {
8783 local iface=$1
8784 local pcap_file=$2
8785 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8786 options:rxq_pcap=dummy-rx.pcap
8787 rm -f ${pcap_file}*.pcap
8788 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8789 options:rxq_pcap=${pcap_file}-rx.pcap
8790 }
8791
8792 test_ip_packet()
8793 {
8794 local active_gw=$1
8795 local backup_gw=$2
8796
8797 # Send ip packet between foo1 and outside1
8798 src_mac="f00000010203" # foo1 mac
8799 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8800 src_ip=`ip_to_hex 192 168 1 2`
8801 dst_ip=`ip_to_hex 172 16 1 3`
8802 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8803
8804 # ARP request packet to expect at outside1
8805 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8806
8807 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8808
8809 # Send ARP reply from outside1 back to the router
8810 # XXX: note, we could avoid this if we plug this port into a netns
8811 # and setup the IP address into the port, so the kernel would simply reply
8812 src_mac="000002010203"
8813 reply_mac="f00000010204"
8814 dst_ip=`ip_to_hex 172 16 1 3`
8815 src_ip=`ip_to_hex 172 16 1 1`
8816 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8817
8818 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8819
8820 OVS_WAIT_UNTIL([
8821 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8822 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8823 ])
8824
8825 # Packet to Expect at ext1 chassis, outside1 port
8826 src_mac="000002010203"
8827 dst_mac="f00000010204"
8828 src_ip=`ip_to_hex 192 168 1 2`
8829 dst_ip=`ip_to_hex 172 16 1 3`
8830 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8831 echo $expected > ext1-vif1.expected
8832 exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
8833 echo $exp_gw_ip_garp >> ext1-vif1.expected
8834
8835 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8836 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8837 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8838
8839 # Resend packet from foo1 to outside1
8840 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8841
8842 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8843 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8844 cat packets | grep $expected > exp
8845 cat packets | grep $exp_gw_ip_garp | head -1 >> exp
8846 AT_CHECK([cat exp], [0], [expout])
8847
8848 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8849 AT_CHECK([grep $expected packets | sort], [0], [])
8850 }
8851
8852 test_ip_packet gw1 gw2
8853
8854 ovn-nbctl --timeout=3 --wait=hv \
8855 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8856 chassis_name=gw1 \
8857 priority=10 -- \
8858 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8859 chassis_name=gw2 \
8860 priority=20 -- \
8861 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8862
8863 test_ip_packet gw2 gw1
8864
8865 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8866 AT_CLEANUP
8867
8868 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8869 AT_SKIP_IF([test $HAVE_PYTHON = no])
8870 ovn_start
8871
8872 # Logical network:
8873 # One LR R1 that has switches foo (192.168.1.0/24) and
8874 # alice (172.16.1.0/24) connected to it. The logical port
8875 # between R1 and alice has a "redirect-chassis" specified,
8876 # i.e. it is the distributed router gateway port.
8877 # Switch alice also has a localnet port defined.
8878 # An additional switch outside has a localnet port and the
8879 # same subnet as alice (172.16.1.0/24).
8880
8881 # Physical network:
8882 # Three hypervisors hv[123].
8883 # hv1 hosts vif foo1.
8884 # hv2 is the "redirect-chassis" that hosts the distributed
8885 # router gateway port.
8886 # hv3 hosts vif outside1.
8887 # In order to show that connectivity works only through hv2,
8888 # an initial round of tests is run without any bridge-mapping
8889 # defined for the localnet on hv2. These tests are expected
8890 # to fail.
8891 # Subsequent tests are run after defining the bridge-mapping
8892 # for the localnet on hv2. These tests are expected to succeed.
8893
8894 # Create three hypervisors and create OVS ports corresponding
8895 # to logical ports.
8896 net_add n1
8897
8898 sim_add hv1
8899 as hv1
8900 ovs-vsctl add-br br-phys
8901 ovn_attach n1 br-phys 192.168.0.1
8902 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8903 set interface hv1-vif1 external-ids:iface-id=foo1 \
8904 options:tx_pcap=hv1/vif1-tx.pcap \
8905 options:rxq_pcap=hv1/vif1-rx.pcap \
8906 ofport-request=1
8907
8908 sim_add hv2
8909 as hv2
8910 ovs-vsctl add-br br-phys
8911 ovn_attach n1 br-phys 192.168.0.2
8912
8913 sim_add hv3
8914 as hv3
8915 ovs-vsctl add-br br-phys
8916 ovn_attach n1 br-phys 192.168.0.3
8917 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8918 set interface hv3-vif1 external-ids:iface-id=outside1 \
8919 options:tx_pcap=hv3/vif1-tx.pcap \
8920 options:rxq_pcap=hv3/vif1-rx.pcap \
8921 ofport-request=1
8922
8923 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8924 # packets for ARP resolution (native tunneling doesn't queue packets
8925 # for ARP resolution).
8926 OVN_POPULATE_ARP
8927
8928 ovn-nbctl create Logical_Router name=R1
8929
8930 ovn-nbctl ls-add foo
8931 ovn-nbctl ls-add alice
8932 ovn-nbctl ls-add outside
8933
8934 # Connect foo to R1
8935 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8936 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8937 type=router options:router-port=foo \
8938 -- lsp-set-addresses rp-foo router
8939
8940 # Connect alice to R1 as distributed router gateway port on hv2
8941 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8942 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8943 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8944 type=router options:router-port=alice \
8945 -- lsp-set-addresses rp-alice router
8946
8947 # Create logical port foo1 in foo
8948 ovn-nbctl lsp-add foo foo1 \
8949 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8950
8951 # Create logical port outside1 in outside
8952 ovn-nbctl lsp-add outside outside1 \
8953 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8954
8955 # Create localnet port in alice
8956 ovn-nbctl lsp-add alice ln-alice
8957 ovn-nbctl lsp-set-addresses ln-alice unknown
8958 ovn-nbctl lsp-set-type ln-alice localnet
8959 ovn-nbctl lsp-set-options ln-alice network_name=phys
8960
8961 # Create localnet port in outside
8962 ovn-nbctl lsp-add outside ln-outside
8963 ovn-nbctl lsp-set-addresses ln-outside unknown
8964 ovn-nbctl lsp-set-type ln-outside localnet
8965 ovn-nbctl lsp-set-options ln-outside network_name=phys
8966
8967 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8968 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8969 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8970
8971
8972 # Allow some time for ovn-northd and ovn-controller to catch up.
8973 # XXX This should be more systematic.
8974 sleep 2
8975
8976 echo "---------NB dump-----"
8977 ovn-nbctl show
8978 echo "---------------------"
8979 ovn-nbctl list logical_router
8980 echo "---------------------"
8981 ovn-nbctl list logical_router_port
8982 echo "---------------------"
8983
8984 echo "---------SB dump-----"
8985 ovn-sbctl list datapath_binding
8986 echo "---------------------"
8987 ovn-sbctl list port_binding
8988 echo "---------------------"
8989 ovn-sbctl dump-flows
8990 echo "---------------------"
8991 ovn-sbctl list chassis
8992 ovn-sbctl list encap
8993 echo "------ Gateway_Chassis dump (SBDB) -------"
8994 ovn-sbctl list Gateway_Chassis
8995 echo "------ Port_Binding chassisredirect -------"
8996 ovn-sbctl find Port_Binding type=chassisredirect
8997 echo "-------------------------------------------"
8998
8999 echo "------ hv1 dump ----------"
9000 as hv1 ovs-ofctl show br-int
9001 as hv1 ovs-ofctl dump-flows br-int
9002 echo "------ hv2 dump ----------"
9003 as hv2 ovs-ofctl show br-int
9004 as hv2 ovs-ofctl dump-flows br-int
9005 echo "------ hv3 dump ----------"
9006 as hv3 ovs-ofctl show br-int
9007 as hv3 ovs-ofctl dump-flows br-int
9008 echo "--------------------------"
9009
9010
9011 # Check that redirect mapping is programmed only on hv2
9012 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
9013 ])
9014 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
9015 ])
9016 # Check that hv1 sends chassisredirect port traffic to hv2
9017 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
9018 ])
9019 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
9020 ])
9021 # Check that arp reply on distributed gateway port is only programmed on hv2
9022 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
9023 ])
9024 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
9025 ])
9026
9027
9028 ip_to_hex() {
9029 printf "%02x%02x%02x%02x" "$@"
9030 }
9031
9032
9033 : > hv2-vif1.expected
9034 : > hv3-vif1.expected
9035
9036 # test_arp INPORT SHA SPA TPA [REPLY_HA]
9037 #
9038 # Causes a packet to be received on INPORT. The packet is an ARP
9039 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
9040 # it should be the hardware address of the target to expect to receive in an
9041 # ARP reply; otherwise no reply is expected.
9042 #
9043 # INPORT is an logical switch port number, e.g. 11 for vif11.
9044 # SHA and REPLY_HA are each 12 hex digits.
9045 # SPA and TPA are each 8 hex digits.
9046 test_arp() {
9047 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
9048 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
9049 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
9050
9051 if test X$reply_ha != X; then
9052 # Expect to receive the reply, if any.
9053 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
9054 echo $reply >> hv${hv}-vif$inport.expected
9055 fi
9056 }
9057
9058 rtr_ip=$(ip_to_hex 172 16 1 1)
9059 foo_ip=$(ip_to_hex 192 168 1 2)
9060 outside_ip=$(ip_to_hex 172 16 1 3)
9061
9062 echo $rtr_ip
9063 echo $foo_ip
9064 echo $outside_ip
9065
9066 # ARP for router IP address from outside1, no response expected
9067 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
9068
9069 # Now check the packets actually received against the ones expected.
9070 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9071
9072 # Send ip packet between foo1 and outside1
9073 src_mac="f00000010203"
9074 dst_mac="000001010203"
9075 src_ip=`ip_to_hex 192 168 1 2`
9076 dst_ip=`ip_to_hex 172 16 1 3`
9077 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9078
9079 # Now check the packets actually received against the ones expected.
9080 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9081
9082 # Now add bridge-mappings on hv2, which should make everything work
9083 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9084
9085 # Wait until the patch ports are created in hv2 to connect br-int to br-phys
9086 OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
9087 grep "Port patch-br-int-to-ln-alice" | wc -l`])
9088
9089 # ARP for router IP address from outside1
9090 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
9091
9092 # hv3-vif1.expected should also have the gw router port garp packet.
9093 exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
9094 echo $exp_gw_ip_garp >> hv3-vif1.expected
9095
9096 # Now check the packets actually received against the ones expected.
9097 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9098
9099 # Send ip packet between foo1 and outside1
9100 src_mac="f00000010203"
9101 dst_mac="000001010203"
9102 src_ip=`ip_to_hex 192 168 1 2`
9103 dst_ip=`ip_to_hex 172 16 1 3`
9104 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9105
9106 # Packet to Expect at outside1
9107 src_mac="000002010203"
9108 dst_mac="f00000010204"
9109 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
9110
9111 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9112
9113 echo "------ hv1 dump ----------"
9114 as hv1 ovs-ofctl show br-int
9115 as hv1 ovs-ofctl dump-flows br-int
9116 echo "------ hv2 dump ----------"
9117 as hv2 ovs-ofctl show br-int
9118 as hv2 ovs-ofctl dump-flows br-int
9119 echo "------ hv3 dump ----------"
9120 as hv3 ovs-ofctl show br-int
9121 as hv3 ovs-ofctl dump-flows br-int
9122 echo "----------------------------"
9123
9124 echo $expected >> hv3-vif1.expected
9125 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9126
9127 #Check ovn-trace over "chassisredirect" port
9128 AT_CAPTURE_FILE([trace])
9129 ovn_trace () {
9130 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
9131 }
9132
9133 echo 'ip.ttl--;' > expout
9134 echo 'eth.src = 00:00:02:01:02:03;' >> expout
9135 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
9136 echo 'output("ln-alice");' >> expout
9137 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])
9138
9139 # Create logical port alice1 in alice on hv1
9140 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
9141 set interface hv1-vif2 external-ids:iface-id=alice1 \
9142 options:tx_pcap=hv1/vif2-tx.pcap \
9143 options:rxq_pcap=hv1/vif2-rx.pcap \
9144 ofport-request=1
9145
9146 ovn-nbctl lsp-add alice alice1 \
9147 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
9148
9149 # Create logical port foo2 in foo on hv2
9150 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
9151 set interface hv2-vif1 external-ids:iface-id=foo2 \
9152 options:tx_pcap=hv2/vif1-tx.pcap \
9153 options:rxq_pcap=hv2/vif1-rx.pcap \
9154 ofport-request=1
9155
9156 ovn-nbctl lsp-add foo foo2 \
9157 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
9158
9159 # Allow some time for ovn-northd and ovn-controller to catch up.
9160 # XXX This should be more systematic.
9161 sleep 1
9162
9163 : > hv1-vif2.expected
9164
9165 # Send ip packet between alice1 and foo2
9166 src_mac="f00000010205"
9167 dst_mac="000002010203"
9168 src_ip=`ip_to_hex 172 16 1 4`
9169 dst_ip=`ip_to_hex 192 168 1 3`
9170 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9171
9172 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
9173
9174 # Packet to Expect at foo2
9175 src_mac="000001010203"
9176 dst_mac="f00000010206"
9177 src_ip=`ip_to_hex 172 16 1 4`
9178 dst_ip=`ip_to_hex 192 168 1 3`
9179 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
9180
9181 echo $expected >> hv2-vif1.expected
9182 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
9183
9184 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
9185 ])
9186
9187 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
9188
9189 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
9190 ])
9191
9192 OVN_CLEANUP([hv1],[hv2],[hv3])
9193
9194 AT_CLEANUP
9195
9196 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
9197 AT_SKIP_IF([test $HAVE_PYTHON = no])
9198 ovn_start
9199 # Create logical switches
9200 ovn-nbctl ls-add ls0
9201 ovn-nbctl ls-add ls1
9202 # Create distributed router
9203 ovn-nbctl create Logical_Router name=lr0
9204 # Add distributed gateway port to distributed router
9205 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
9206 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
9207 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9208 type=router options:router-port=lrp0 addresses="router"
9209 # Add router port to ls1
9210 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9211 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9212 type=router options:router-port=lrp1 addresses="router"
9213 # Add logical ports for NAT rules
9214 ovn-nbctl lsp-add ls1 foo1 \
9215 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
9216 ovn-nbctl lsp-add ls1 foo2 \
9217 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
9218 # Add nat-addresses option
9219 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9220 # Add NAT rules
9221 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
9222 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
9223 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])
9224 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])
9225
9226 net_add n1
9227 sim_add hv1
9228 as hv1
9229 ovs-vsctl add-br br-phys
9230 ovn_attach n1 br-phys 192.168.0.1
9231
9232 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9233 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])
9234
9235 sim_add hv2
9236 as hv2
9237 ovs-vsctl add-br br-phys
9238 ovn_attach n1 br-phys 192.168.0.2
9239 # Initially test with no bridge-mapping on hv2, expect to receive no packets
9240
9241 sim_add hv3
9242 as hv3
9243 ovs-vsctl add-br br-phys
9244 ovn_attach n1 br-phys 192.168.0.3
9245 # Initially test with no bridge-mapping on hv3
9246
9247 # Create a localnet port.
9248 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9249 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9250 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9251 AT_CHECK([ovn-nbctl --wait=hv lsp-set-options ln_port network_name=physnet1])
9252
9253 # Allow some time for ovn-northd and ovn-controller to catch up.
9254 # XXX This should be more systematic.
9255 sleep 2
9256
9257 # Expect no packets when hv2 bridge-mapping is not present
9258 : > packets
9259 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
9260
9261 # Add bridge-mapping on hv2
9262 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9263
9264 # Wait until the patch ports are created in hv2 to connect br-int to br-phys
9265 OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
9266 grep "Port patch-br-int-to-ln_port" | wc -l`])
9267
9268 # Wait for packets to be received.
9269 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9270 trim_zeros() {
9271 sed 's/\(00\)\{1,\}$//'
9272 }
9273 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
9274 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
9275 echo $expected > expout
9276 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
9277 echo $expected >> expout
9278 AT_CHECK([sort packets], [0], [expout])
9279 sort packets | cat
9280
9281 # Temporarily remove nat-addresses option to avoid race conditions
9282 # due to GARP backoff
9283 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
9284
9285 reset_pcap_file() {
9286 local iface=$1
9287 local pcap_file=$2
9288 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9289 options:rxq_pcap=dummy-rx.pcap
9290 rm -f ${pcap_file}*.pcap
9291 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9292 options:rxq_pcap=${pcap_file}-rx.pcap
9293 }
9294
9295 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9296
9297 # Add OVS ports for foo1 and foo2 on hv3
9298 ovs-vsctl -- add-port br-int hv3-vif1 -- \
9299 set interface hv3-vif1 external-ids:iface-id=foo1 \
9300 ofport-request=1
9301 ovs-vsctl -- add-port br-int hv3-vif2 -- \
9302 set interface hv3-vif2 external-ids:iface-id=foo2 \
9303 ofport-request=2
9304
9305 # Add bridge-mapping on hv3
9306 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9307
9308 # Wait until the patch ports are created in hv3 to connect br-int to br-phys
9309 OVS_WAIT_UNTIL([test 1 = `as hv3 ovs-vsctl show | \
9310 grep "Port patch-br-int-to-ln_port" | wc -l`])
9311
9312 # Re-add nat-addresses option
9313 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9314
9315 # Wait for packets to be received.
9316 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
9317 trim_zeros() {
9318 sed 's/\(00\)\{1,\}$//'
9319 }
9320
9321 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
9322 garp_1="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
9323 echo $garp_1 > expout
9324 garp_2="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
9325 echo $garp_2 >> expout
9326
9327 cat packets | grep $garp_1 | head -1 > exp
9328 cat packets | grep $garp_2 | head -1 >> exp
9329 AT_CHECK([cat exp], [0], [expout])
9330
9331 OVN_CLEANUP([hv1],[hv2],[hv3])
9332
9333 AT_CLEANUP
9334
9335 # VLAN traffic for external network redirected through distributed router
9336 # gateway port should use vlans(i.e input network vlan tag) across hypervisors
9337 # instead of tunneling.
9338 AT_SETUP([ovn -- vlan traffic for external network with distributed router gateway port])
9339 AT_SKIP_IF([test $HAVE_PYTHON = no])
9340 ovn_start
9341
9342 # Logical network:
9343 # # One LR R1 that has switches foo (192.168.1.0/24) and
9344 # # alice (172.16.1.0/24) connected to it. The logical port
9345 # # between R1 and alice has a "redirect-chassis" specified,
9346 # # i.e. it is the distributed router gateway port(172.16.1.6).
9347 # # Switch alice also has a localnet port defined.
9348 # # An additional switch outside has the same subnet as alice
9349 # # (172.16.1.0/24), a localnet port and nexthop port(172.16.1.1)
9350 # # which will receive the packet destined for external network
9351 # # (i.e 8.8.8.8 as destination ip).
9352
9353 # Physical network:
9354 # # Four hypervisors hv[1234].
9355 # # hv1 hosts vif foo1.
9356 # # hv2 is the "redirect-chassis" that hosts the distributed router gateway port.
9357 # # Later to test GARPs for the router port - foo, hv2 and hv4 are added to the ha_chassis_group
9358 # # hv3 hosts nexthop port vif outside1.
9359 # # All other tests connect hypervisors to network n1 through br-phys for tunneling.
9360 # # But in this test, hv1 won't connect to n1(and no br-phys in hv1), and
9361 # # in order to show vlans(instead of tunneling) used between hv1 and hv2,
9362 # # a new network n2 created and hv1 and hv2 connected to this network through br-ex.
9363 # # hv2 and hv3 are still connected to n1 network through br-phys.
9364 net_add n1
9365
9366 # We are not calling ovn_attach for hv1, to avoid adding br-phys.
9367 # Tunneling won't work in hv1 as ovn-encap-ip is not added to any bridge in hv1
9368 sim_add hv1
9369 as hv1
9370 ovs-vsctl \
9371 -- set Open_vSwitch . external-ids:system-id=hv1 \
9372 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
9373 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
9374 -- set Open_vSwitch . external-ids:ovn-encap-ip=192.168.0.1 \
9375 -- add-br br-int \
9376 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
9377 -- set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-ex
9378
9379 start_daemon ovn-controller
9380 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9381 set interface hv1-vif1 external-ids:iface-id=foo1 \
9382 options:tx_pcap=hv1/vif1-tx.pcap \
9383 options:rxq_pcap=hv1/vif1-rx.pcap \
9384 ofport-request=1
9385
9386 sim_add hv2
9387 as hv2
9388 ovs-vsctl add-br br-phys
9389 ovn_attach n1 br-phys 192.168.0.2
9390 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
9391
9392 sim_add hv3
9393 as hv3
9394 ovs-vsctl add-br br-phys
9395 ovn_attach n1 br-phys 192.168.0.3
9396 ovs-vsctl -- add-port br-int hv3-vif1 -- \
9397 set interface hv3-vif1 external-ids:iface-id=outside1 \
9398 options:tx_pcap=hv3/vif1-tx.pcap \
9399 options:rxq_pcap=hv3/vif1-rx.pcap \
9400 ofport-request=1
9401 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="phys:br-phys"
9402
9403 sim_add hv4
9404 as hv4
9405 ovs-vsctl add-br br-phys
9406 ovn_attach n1 br-phys 192.168.0.4
9407 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
9408
9409 # Create network n2 for vlan connectivity between hv1 and hv2
9410 net_add n2
9411
9412 as hv1
9413 ovs-vsctl add-br br-ex
9414 net_attach n2 br-ex
9415
9416 as hv2
9417 ovs-vsctl add-br br-ex
9418 net_attach n2 br-ex
9419
9420 as hv4
9421 ovs-vsctl add-br br-ex
9422 net_attach n2 br-ex
9423
9424 OVN_POPULATE_ARP
9425
9426 ovn-nbctl create Logical_Router name=R1
9427
9428 ovn-nbctl ls-add foo
9429 ovn-nbctl ls-add alice
9430 ovn-nbctl ls-add outside
9431
9432 # Connect foo to R1
9433 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
9434 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
9435 type=router options:router-port=foo \
9436 -- lsp-set-addresses rp-foo router
9437
9438 # Connect alice to R1 as distributed router gateway port (172.16.1.6) on hv2
9439 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.6/24 \
9440 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
9441 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9442 type=router options:router-port=alice \
9443 -- lsp-set-addresses rp-alice router \
9444
9445 # Create logical port foo1 in foo
9446 ovn-nbctl lsp-add foo foo1 \
9447 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9448
9449 # Create logical port outside1 in outside, which is a nexthop address
9450 # for 172.16.1.0/24
9451 ovn-nbctl lsp-add outside outside1 \
9452 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.1"
9453
9454 # Set default gateway (nexthop) to 172.16.1.1
9455 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 172.16.1.1 alice
9456 AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.6 192.168.1.1/24])
9457 ovn-nbctl set Logical_Switch_Port rp-alice options:nat-addresses=router
9458
9459 ovn-nbctl lsp-add foo ln-foo
9460 ovn-nbctl lsp-set-addresses ln-foo unknown
9461 ovn-nbctl lsp-set-options ln-foo network_name=public
9462 ovn-nbctl lsp-set-type ln-foo localnet
9463 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln-foo tag=2])
9464
9465 # Create localnet port in alice
9466 ovn-nbctl lsp-add alice ln-alice
9467 ovn-nbctl lsp-set-addresses ln-alice unknown
9468 ovn-nbctl lsp-set-type ln-alice localnet
9469 ovn-nbctl lsp-set-options ln-alice network_name=phys
9470
9471 # Create localnet port in outside
9472 ovn-nbctl lsp-add outside ln-outside
9473 ovn-nbctl lsp-set-addresses ln-outside unknown
9474 ovn-nbctl lsp-set-type ln-outside localnet
9475 ovn-nbctl lsp-set-options ln-outside network_name=phys
9476
9477 # Allow some time for ovn-northd and ovn-controller to catch up.
9478 # XXX This should be more systematic.
9479 ovn-nbctl --wait=hv --timeout=3 sync
9480
9481 # Check that there is a logical flow in logical switch foo's pipeline
9482 # to set the outport to rp-foo (which is expected).
9483 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
9484 grep rp-foo | grep -v is_chassis_resident | wc -l`])
9485
9486 # Set the option 'reside-on-redirect-chassis' for foo
9487 ovn-nbctl set logical_router_port foo options:reside-on-redirect-chassis=true
9488 # Check that there is a logical flow in logical switch foo's pipeline
9489 # to set the outport to rp-foo with the condition is_chassis_redirect.
9490 ovn-sbctl dump-flows foo
9491 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
9492 grep rp-foo | grep is_chassis_resident | wc -l`])
9493
9494 echo "---------NB dump-----"
9495 ovn-nbctl show
9496 echo "---------------------"
9497 ovn-nbctl list logical_router
9498 echo "---------------------"
9499 ovn-nbctl list nat
9500 echo "---------------------"
9501 ovn-nbctl list logical_router_port
9502 echo "---------------------"
9503
9504 echo "---------SB dump-----"
9505 ovn-sbctl list datapath_binding
9506 echo "---------------------"
9507 ovn-sbctl list port_binding
9508 echo "---------------------"
9509 ovn-sbctl dump-flows
9510 echo "---------------------"
9511 ovn-sbctl list chassis
9512 echo "---------------------"
9513
9514 for chassis in hv1 hv2 hv3; do
9515 as $chassis
9516 echo "------ $chassis dump ----------"
9517 ovs-vsctl show br-int
9518 ovs-ofctl show br-int
9519 ovs-ofctl dump-flows br-int
9520 echo "--------------------------"
9521 done
9522
9523 ip_to_hex() {
9524 printf "%02x%02x%02x%02x" "$@"
9525 }
9526
9527 foo1_ip=$(ip_to_hex 192 168 1 2)
9528 gw_ip=$(ip_to_hex 172 16 1 6)
9529 dst_ip=$(ip_to_hex 8 8 8 8)
9530 nexthop_ip=$(ip_to_hex 172 16 1 1)
9531
9532 foo1_mac="f00000010203"
9533 foo_mac="000001010203"
9534 gw_mac="000002010203"
9535 nexthop_mac="f00000010204"
9536
9537 # Send ip packet from foo1 to 8.8.8.8
9538 src_mac="f00000010203"
9539 dst_mac="000001010203"
9540 packet=${foo_mac}${foo1_mac}08004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
9541
9542 # Wait for GARPs announcing gw IP to arrive
9543 OVS_WAIT_UNTIL([
9544 test `as hv2 ovs-ofctl dump-flows br-int | grep table=66 | \
9545 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
9546 ])
9547
9548 # VLAN tagged packet with router port(192.168.1.1) MAC as destination MAC
9549 # is expected on bridge connecting hv1 and hv2
9550 expected=${foo_mac}${foo1_mac}8100000208004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
9551 echo $expected > hv1-br-ex_n2.expected
9552
9553 # Packet to Expect at outside1 i.e nexthop(172.16.1.1) port.
9554 # As connection tracking not enabled for this test, snat can't be done on the packet.
9555 # We still see foo1 as the source ip address. But source mac(gateway MAC) and
9556 # dest mac(nexthop mac) are properly configured.
9557 expected=${nexthop_mac}${gw_mac}08004500001c000000003f110100${foo1_ip}${dst_ip}0035111100080000
9558 echo $expected > hv3-vif1.expected
9559
9560 reset_pcap_file() {
9561 local iface=$1
9562 local pcap_file=$2
9563 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9564 options:rxq_pcap=dummy-rx.pcap
9565 rm -f ${pcap_file}*.pcap
9566 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9567 options:rxq_pcap=${pcap_file}-rx.pcap
9568 }
9569
9570 as hv1 reset_pcap_file br-ex_n2 hv1/br-ex_n2
9571 as hv3 reset_pcap_file hv3-vif1 hv3/vif1
9572 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9573 sleep 2
9574
9575 # On hv1, table 32 check that no packet goes via the tunnel port
9576 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 \
9577 | grep "NXM_NX_TUN_ID" | grep -v n_packets=0 | wc -l], [0], [[0
9578 ]])
9579
9580 ip_packet() {
9581 grep "1010203f00000010203"
9582 }
9583
9584 # Check vlan tagged packet on the bridge connecting hv1 and hv2 with the
9585 # foo1's mac.
9586 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-ex_n2-tx.pcap | ip_packet | uniq > hv1-br-ex_n2
9587 cat hv1-br-ex_n2.expected > expout
9588 AT_CHECK([sort hv1-br-ex_n2], [0], [expout])
9589
9590 # Check expected packet on nexthop interface
9591 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/vif1-tx.pcap | grep ${foo1_ip}${dst_ip} | uniq > hv3-vif1
9592 cat hv3-vif1.expected > expout
9593 AT_CHECK([sort hv3-vif1], [0], [expout])
9594
9595 # Test the GARP for the router port ip - 192.168.1.1
9596 ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
9597
9598 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
9599 as hv2 reset_pcap_file br-ex_n2 hv2/br-ex_n2
9600 as hv4 reset_pcap_file br-ex_n2 hv4/br-ex_n2
9601
9602 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv2 30
9603 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv4 20
9604
9605 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
9606 ovn-nbctl remove logical_router_port alice options redirect-chassis
9607 ovn-nbctl --wait=sb set logical_router_port alice ha_chassis_group=$hagrp1_uuid
9608
9609 # When hv2 claims the gw router port cr-alice, it should send out
9610 # GARP for 192.168.1.1 and it should be received by foo1 on hv1.
9611
9612 # foo1 (on hv1) should receive GARP without VLAN tag
9613 exp_garp_on_foo1="ffffffffffff00000101020308060001080006040001000001010203c0a80101000000000000c0a80101"
9614 echo $exp_garp_on_foo1 > foo1.expout
9615
9616 # ovn-controller on hv2 should send garp with VLAN tag
9617 sent_garp="ffffffffffff0000010102038100000208060001080006040001000001010203c0a80101000000000000c0a80101"
9618
9619 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [foo1.expout])
9620 # Wait until we receive atleast 1 packet
9621 OVS_WAIT_UNTIL([test 1=`$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap | wc -l`])
9622 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap | head -1 > packets
9623 echo $sent_garp > expout
9624 AT_CHECK([cat packets], [0], [expout])
9625 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv4/br-ex_n2-tx.pcap > empty
9626 AT_CHECK([cat empty], [0], [])
9627
9628 # Make hv4 master
9629 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
9630 as hv4 reset_pcap_file br-ex_n2 hv4/br-ex_n2
9631 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv4 40
9632
9633 # Wait till cr-alice is claimed by hv4
9634 hv4_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=hv4)
9635 # check that the chassis redirect port has been claimed by the gw1 chassis
9636 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
9637 logical_port=cr-alice | grep $hv4_chassis | wc -l], [0],[[1
9638 ]])
9639
9640 # Reset the pcap file for hv2/br-ex_n2. From now on ovn-controller in hv2
9641 # should not send GARPs for the router ports.
9642 as hv2 reset_pcap_file br-ex_n2 hv2/br-ex_n2
9643
9644 echo $sent_garp > br-ex_n2.expout
9645 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [foo1.expout])
9646 OVN_CHECK_PACKETS([hv4/br-ex_n2-tx.pcap], [br-ex_n2.expout])
9647
9648 sleep 2
9649
9650 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap > empty
9651 AT_CHECK([cat empty], [0], [])
9652
9653 OVN_CLEANUP([hv1],[hv2],[hv3], [hv4])
9654 AT_CLEANUP
9655
9656 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
9657 AT_KEYWORDS([ovn-nd_ra])
9658 AT_SKIP_IF([test $HAVE_PYTHON = no])
9659 ovn_start
9660
9661 # In this test case we create 1 lswitch with 3 VIF ports attached,
9662 # and a lrouter connected to the lswitch.
9663 # We generate the Router solicitation packet and verify the Router Advertisement
9664 # reply packet from the ovn-controller.
9665
9666 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
9667 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
9668 # 'slaac' to allow lrp0 send RA for SLAAC mode.
9669 ovn-nbctl ls-add lsw0
9670 ovn-nbctl lr-add lr0
9671 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
9672 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
9673 ovn-nbctl \
9674 -- lsp-add lsw0 lsp0 \
9675 -- set Logical_Switch_Port lsp0 type=router \
9676 options:router-port=lrp0 \
9677 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
9678 net_add n1
9679 sim_add hv1
9680 as hv1
9681 ovs-vsctl add-br br-phys
9682 ovn_attach n1 br-phys 192.168.0.2
9683
9684 ovn-nbctl lsp-add lsw0 lp1
9685 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
9686 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"
9687
9688 ovn-nbctl lsp-add lsw0 lp2
9689 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
9690 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"
9691
9692 ovn-nbctl lsp-add lsw0 lp3
9693 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
9694 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"
9695
9696 # Add ACL rule for ICMPv6 on lsw0
9697 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
9698 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
9699 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
9700 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
9701
9702 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9703 set interface hv1-vif1 external-ids:iface-id=lp1 \
9704 options:tx_pcap=hv1/vif1-tx.pcap \
9705 options:rxq_pcap=hv1/vif1-rx.pcap \
9706 ofport-request=1
9707
9708 ovs-vsctl -- add-port br-int hv1-vif2 -- \
9709 set interface hv1-vif2 external-ids:iface-id=lp2 \
9710 options:tx_pcap=hv1/vif2-tx.pcap \
9711 options:rxq_pcap=hv1/vif2-rx.pcap \
9712 ofport-request=2
9713
9714 ovs-vsctl -- add-port br-int hv1-vif3 -- \
9715 set interface hv1-vif3 external-ids:iface-id=lp3 \
9716 options:tx_pcap=hv1/vif3-tx.pcap \
9717 options:rxq_pcap=hv1/vif3-rx.pcap \
9718 ofport-request=3
9719
9720 # Allow some time for ovn-northd and ovn-controller to catch up.
9721 # XXX This should be more systematic.
9722 sleep 1
9723
9724 reset_pcap_file() {
9725 local iface=$1
9726 local pcap_file=$2
9727 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9728 options:rxq_pcap=dummy-rx.pcap
9729 rm -f ${pcap_file}*.pcap
9730 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9731 options:rxq_pcap=${pcap_file}-rx.pcap
9732 }
9733
9734 # Make sure that ovn-controller has installed the corresponding OF Flow.
9735 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"`])
9736
9737 # This shell function sends a Router Solicitation packet.
9738 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
9739 test_ipv6_ra() {
9740 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
9741 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
9742
9743 local len=24
9744 local mtu_opt=""
9745 if test $mtu != 0; then
9746 len=`expr $len + 8`
9747 mtu_opt=05010000${mtu}
9748 fi
9749
9750 if test ${#prefix_opt} != 0; then
9751 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
9752 len=`expr $len + ${#prefix_opt} / 2`
9753 fi
9754
9755 len=$(printf "%x" $len)
9756 local lrp_mac=fa163e000001
9757 local lrp_lla=fe80000000000000f8163efffe000001
9758 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
9759 echo $reply >> $inport.expected
9760
9761 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
9762 }
9763
9764 AT_CAPTURE_FILE([ofctl_monitor0.log])
9765 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
9766 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
9767
9768 # MTU is not set and the address mode is set to slaac
9769 addr_mode=00
9770 default_prefix_option_config=030440c0ffffffffffffffff00000000
9771 src_mac=fa163e000002
9772 src_lla=fe80000000000000f8163efffe000002
9773 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
9774
9775 # NXT_RESUME should be 1.
9776 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9777
9778 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9779
9780 cat 1.expected | cut -c -112 > expout
9781 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9782
9783 # Skipping the ICMPv6 checksum.
9784 cat 1.expected | cut -c 117- > expout
9785 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9786
9787 rm -f *.expected
9788 reset_pcap_file hv1-vif1 hv1/vif1
9789 reset_pcap_file hv1-vif2 hv1/vif2
9790 reset_pcap_file hv1-vif3 hv1/vif3
9791
9792 # Set the MTU to 1500
9793 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
9794
9795 # Make sure that ovn-controller has installed the corresponding OF Flow.
9796 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"`])
9797
9798 addr_mode=00
9799 default_prefix_option_config=030440c0ffffffffffffffff00000000
9800 src_mac=fa163e000003
9801 src_lla=fe80000000000000f8163efffe000003
9802 mtu=000005dc
9803
9804 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9805
9806 # NXT_RESUME should be 2.
9807 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9808
9809 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
9810
9811 cat 2.expected | cut -c -112 > expout
9812 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9813
9814 # Skipping the ICMPv6 checksum.
9815 cat 2.expected | cut -c 117- > expout
9816 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9817
9818 rm -f *.expected
9819 reset_pcap_file hv1-vif1 hv1/vif1
9820 reset_pcap_file hv1-vif2 hv1/vif2
9821 reset_pcap_file hv1-vif3 hv1/vif3
9822
9823 # Set the address mode to dhcpv6_stateful
9824 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
9825 # Make sure that ovn-controller has installed the corresponding OF Flow.
9826 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"`])
9827
9828 addr_mode=80
9829 default_prefix_option_config=03044080ffffffffffffffff00000000
9830 src_mac=fa163e000004
9831 src_lla=fe80000000000000f8163efffe000004
9832 mtu=000005dc
9833
9834 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9835
9836 # NXT_RESUME should be 3.
9837 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9838
9839 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
9840
9841 cat 3.expected | cut -c -112 > expout
9842 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
9843
9844 # Skipping the ICMPv6 checksum.
9845 cat 3.expected | cut -c 117- > expout
9846 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
9847
9848 rm -f *.expected
9849 reset_pcap_file hv1-vif1 hv1/vif1
9850 reset_pcap_file hv1-vif2 hv1/vif2
9851 reset_pcap_file hv1-vif3 hv1/vif3
9852
9853 # Set the address mode to dhcpv6_stateless
9854 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
9855 # Make sure that ovn-controller has installed the corresponding OF Flow.
9856 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"`])
9857
9858 addr_mode=40
9859 default_prefix_option_config=030440c0ffffffffffffffff00000000
9860 src_mac=fa163e000002
9861 src_lla=fe80000000000000f8163efffe000002
9862 mtu=000005dc
9863
9864 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9865
9866 # NXT_RESUME should be 4.
9867 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9868
9869 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9870
9871 cat 1.expected | cut -c -112 > expout
9872 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9873
9874 # Skipping the ICMPv6 checksum.
9875 cat 1.expected | cut -c 117- > expout
9876 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9877
9878 rm -f *.expected
9879 reset_pcap_file hv1-vif1 hv1/vif1
9880 reset_pcap_file hv1-vif2 hv1/vif2
9881 reset_pcap_file hv1-vif3 hv1/vif3
9882
9883 # Set the address mode to invalid.
9884 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
9885 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
9886 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"`])
9887
9888 addr_mode=40
9889 default_prefix_option_config=""
9890 src_mac=fa163e000002
9891 src_lla=fe80000000000000f8163efffe000002
9892 mtu=000005dc
9893
9894 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9895
9896 # NXT_RESUME should be 4 only.
9897 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9898
9899 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9900 AT_CHECK([cat 1.packets], [0], [])
9901
9902 OVN_CLEANUP([hv1])
9903 AT_CLEANUP
9904
9905 AT_SETUP([ovn -- /32 router IP address])
9906 AT_SKIP_IF([test $HAVE_PYTHON = no])
9907 ovn_start
9908
9909 # Logical network:
9910 # 2 LS 'foo' and 'alice' connected via router R1.
9911 # R1 connects to 'alice' with a /32 IP address. We use static routes and
9912 # nexthop to push traffic to a logical port in switch 'alice'
9913
9914 ovn-nbctl lr-add R1
9915
9916 ovn-nbctl ls-add foo
9917 ovn-nbctl ls-add alice
9918
9919 # Connect foo to R1
9920 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
9921 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
9922 options:router-port=foo addresses=\"00:00:00:01:02:03\"
9923
9924 # Connect alice to R1.
9925 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
9926 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9927 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
9928
9929 # Create logical port foo1 in foo
9930 ovn-nbctl lsp-add foo foo1 \
9931 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9932
9933 # Create logical port alice1 in alice
9934 ovn-nbctl lsp-add alice alice1 \
9935 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
9936
9937 #install default route in R1 to use alice1's IP address as nexthop
9938 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
9939
9940 # Create two hypervisor and create OVS ports corresponding to logical ports.
9941 net_add n1
9942
9943 sim_add hv1
9944 as hv1
9945 ovs-vsctl add-br br-phys
9946 ovn_attach n1 br-phys 192.168.0.1
9947 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9948 set interface hv1-vif1 external-ids:iface-id=foo1 \
9949 options:tx_pcap=hv1/vif1-tx.pcap \
9950 options:rxq_pcap=hv1/vif1-rx.pcap \
9951 ofport-request=1
9952
9953 sim_add hv2
9954 as hv2
9955 ovs-vsctl add-br br-phys
9956 ovn_attach n1 br-phys 192.168.0.2
9957 ovs-vsctl -- add-port br-int hv2-vif1 -- \
9958 set interface hv2-vif1 external-ids:iface-id=alice1 \
9959 options:tx_pcap=hv2/vif1-tx.pcap \
9960 options:rxq_pcap=hv2/vif1-rx.pcap \
9961 ofport-request=1
9962
9963
9964 # Pre-populate the hypervisors' ARP tables so that we don't lose any
9965 # packets for ARP resolution (native tunneling doesn't queue packets
9966 # for ARP resolution).
9967 OVN_POPULATE_ARP
9968
9969 # Allow some time for ovn-northd and ovn-controller to catch up.
9970 # XXX This should be more systematic.
9971 sleep 1
9972
9973 ip_to_hex() {
9974 printf "%02x%02x%02x%02x" "$@"
9975 }
9976
9977 # Send ip packets between foo1 and alice1
9978 src_mac="f00000010203"
9979 dst_mac="000000010203"
9980 src_ip=`ip_to_hex 192 168 1 2`
9981 dst_ip=`ip_to_hex 10 0 0 2`
9982 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9983
9984 # Send the first packet to trigger a ARP response and population of
9985 # mac_bindings table.
9986 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9987 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
9988 ovn-nbctl --wait=hv sync
9989
9990 # Packet to Expect at 'alice1'
9991 src_mac="000000010204"
9992 dst_mac="f00000010204"
9993 src_ip=`ip_to_hex 192 168 1 2`
9994 dst_ip=`ip_to_hex 10 0 0 2`
9995 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
9996
9997 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
9998
9999 OVN_CLEANUP([hv1],[hv2])
10000
10001 AT_CLEANUP
10002
10003 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
10004 AT_SKIP_IF([test $HAVE_PYTHON = no])
10005 ovn_start
10006
10007 ovn-nbctl ls-add ls1
10008
10009 # Add localport to the switch
10010 ovn-nbctl lsp-add ls1 lp01
10011 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
10012 ovn-nbctl lsp-set-type lp01 localport
10013
10014 net_add n1
10015
10016 for i in 1 2; do
10017 sim_add hv$i
10018 as hv$i
10019 ovs-vsctl add-br br-phys
10020 ovn_attach n1 br-phys 192.168.0.$i
10021 ovs-vsctl add-port br-int vif01 -- \
10022 set Interface vif01 external-ids:iface-id=lp01 \
10023 options:tx_pcap=hv${i}/vif01-tx.pcap \
10024 options:rxq_pcap=hv${i}/vif01-rx.pcap \
10025 ofport-request=${i}0
10026
10027 ovs-vsctl add-port br-int vif${i}1 -- \
10028 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
10029 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
10030 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
10031 ofport-request=${i}1
10032
10033 ovn-nbctl lsp-add ls1 lp${i}1
10034 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
10035 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
10036
10037 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
10038 done
10039
10040 ovn-nbctl --wait=sb sync
10041 ovn-sbctl dump-flows
10042
10043 OVN_POPULATE_ARP
10044
10045 # Given the name of a logical port, prints the name of the hypervisor
10046 # on which it is located.
10047 vif_to_hv() {
10048 echo hv${1%?}
10049 }
10050 #
10051 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
10052 #
10053 # This shell function causes a packet to be received on INPORT. The packet's
10054 # content has Ethernet destination DST and source SRC (each exactly 12 hex
10055 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
10056 # logical switch port numbers, e.g. 11 for vif11.
10057 #
10058 # EOUT is the end-to-end output port, that is, where the packet will end up
10059 # after possibly bouncing through one or more localnet ports. LOUT is the
10060 # logical output port, which might be a localnet port, as seen by ovn-trace
10061 # (which doesn't know what localnet ports are connected to and therefore can't
10062 # figure out the end-to-end answer).
10063 #
10064 # DEFHV is the default hypervisor from where the packet is going to be sent
10065 # if the source port is a localport.
10066 for i in 1 2; do
10067 for j in 0 1; do
10068 : > $i$j.expected
10069 done
10070 done
10071 test_packet() {
10072 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
10073 echo "$@"
10074
10075 # First try tracing the packet.
10076 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
10077 if test $lout != drop; then
10078 echo "output(\"$lout\");"
10079 fi > expout
10080 AT_CAPTURE_FILE([trace])
10081 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
10082
10083 # Then actually send a packet, for an end-to-end test.
10084 local packet=$(echo $dst$src | sed 's/://g')${eth}
10085 hv=`vif_to_hv $inport`
10086 # If hypervisor 0 (localport) use the defhv parameter
10087 if test $hv = hv0; then
10088 hv=$defhv
10089 fi
10090 vif=vif$inport
10091 as $hv ovs-appctl netdev-dummy/receive $vif $packet
10092 if test $eout != drop; then
10093 echo $packet >> ${eout#lp}.expected
10094 fi
10095 }
10096
10097
10098 # lp11 and lp21 are on different hypervisors
10099 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
10100 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
10101
10102 # Both VIFs should be able to reach the localport on their own HV
10103 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
10104 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
10105
10106 # Packet sent from localport on same hv should reach the vif
10107 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
10108 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
10109
10110 # Packet sent from localport on different hv should be dropped
10111 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
10112 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
10113
10114 # Now check the packets actually received against the ones expected.
10115 for i in 1 2; do
10116 for j in 0 1; do
10117 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
10118 done
10119 done
10120
10121 OVN_CLEANUP([hv1],[hv2])
10122
10123 AT_CLEANUP
10124
10125 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
10126 AT_SKIP_IF([test $HAVE_PYTHON = no])
10127 ovn_start
10128
10129 net_add n1
10130
10131 # create gateways with external network connectivity
10132
10133 for i in 1 2; do
10134 sim_add gw$i
10135 as gw$i
10136 ovs-vsctl add-br br-phys
10137 ovn_attach n1 br-phys 192.168.0.$i
10138 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10139 done
10140
10141 ovn-nbctl ls-add inside
10142 ovn-nbctl ls-add outside
10143
10144 # create hypervisors with a vif port each to an internal network
10145
10146 for i in 1 2; do
10147 sim_add hv$i
10148 as hv$i
10149 ovs-vsctl add-br br-phys
10150 ovn_attach n1 br-phys 192.168.0.1$i
10151 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10152 set interface hv$i-vif1 external-ids:iface-id=inside$i \
10153 options:tx_pcap=hv$i/vif1-tx.pcap \
10154 options:rxq_pcap=hv$i/vif1-rx.pcap \
10155 ofport-request=1
10156
10157 ovn-nbctl lsp-add inside inside$i \
10158 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
10159
10160 done
10161
10162 OVN_POPULATE_ARP
10163
10164 ovn-nbctl create Logical_Router name=R1
10165
10166 # Connect inside to R1
10167 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
10168 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
10169 type=router options:router-port=inside \
10170 -- lsp-set-addresses rp-inside router
10171
10172 # Connect outside to R1 as distributed router gateway port on gw1+gw2
10173 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
10174
10175 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10176 name=outside_gw1 chassis_name=gw1 priority=20 -- \
10177 --id=@gc1 create Gateway_Chassis \
10178 name=outside_gw2 chassis_name=gw2 priority=10 -- \
10179 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10180
10181 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
10182 type=router options:router-port=outside \
10183 -- lsp-set-addresses rp-outside router
10184
10185 # Create localnet port in outside
10186 ovn-nbctl lsp-add outside ln-outside
10187 ovn-nbctl lsp-set-addresses ln-outside unknown
10188 ovn-nbctl lsp-set-type ln-outside localnet
10189 ovn-nbctl lsp-set-options ln-outside network_name=phys
10190
10191 # Allow some time for ovn-northd and ovn-controller to catch up.
10192 # XXX This should be more systematic.
10193 ovn-nbctl --wait=hv --timeout=3 sync
10194
10195 echo "---------NB dump-----"
10196 ovn-nbctl show
10197 echo "---------------------"
10198 ovn-nbctl list logical_router
10199 echo "---------------------"
10200 ovn-nbctl list logical_router_port
10201 echo "---------------------"
10202
10203 echo "---------SB dump-----"
10204 ovn-sbctl list datapath_binding
10205 echo "---------------------"
10206 ovn-sbctl list port_binding
10207 echo "---------------------"
10208 ovn-sbctl dump-flows
10209 echo "---------------------"
10210 ovn-sbctl list chassis
10211 ovn-sbctl list encap
10212 echo "---------------------"
10213 echo "------ Gateway_Chassis dump (SBDB) -------"
10214 ovn-sbctl list Gateway_Chassis
10215 echo "------ Port_Binding chassisredirect -------"
10216 ovn-sbctl find Port_Binding type=chassisredirect
10217 echo "-------------------------------------------"
10218
10219 # There should be one ha_chassis_group with the name "outside"
10220 ha_chassi_grp_name=`ovn-sbctl --bare --columns name find \
10221 ha_chassis_group name="outside"`
10222
10223 AT_CHECK([test $ha_chassi_grp_name = outside])
10224
10225 # There should be 2 ha_chassis rows in SB DB.
10226 AT_CHECK([ovn-sbctl list ha_chassis | grep chassis | \
10227 grep -v chassis-name | awk '{print $3}' \
10228 | grep '-' | wc -l ], [0], [2
10229 ])
10230
10231 ha_ch=`ovn-sbctl --bare --columns ha_chassis find ha_chassis_group`
10232 # Trim the spaces.
10233 ha_ch=`echo $ha_ch | sed 's/ //g'`
10234
10235 ha_ch_list=''
10236 for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
10237 do
10238 ha_ch_list="$ha_ch_list $i"
10239 done
10240
10241 # Trim the spaces.
10242 ha_ch_list=`echo $ha_ch_list | sed 's/ //g'`
10243
10244 AT_CHECK([test "$ha_ch_list" = "$ha_ch"])
10245
10246 for chassis in gw1 gw2 hv1 hv2; do
10247 as $chassis
10248 echo "------ $chassis dump ----------"
10249 ovs-ofctl show br-int
10250 ovs-ofctl dump-flows br-int
10251 echo "--------------------------"
10252 done
10253 bfd_dump() {
10254 for chassis in gw1 gw2 hv1 hv2; do
10255 as $chassis
10256 echo "------ $chassis dump (BFD)----"
10257 echo "BFD (from $chassis):"
10258 # dump BFD config and status to the other chassis
10259 for chassis2 in gw1 gw2 hv1 hv2; do
10260 if [[ "$chassis" != "$chassis2" ]]; then
10261 echo " -> $chassis2:"
10262 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
10263 fi
10264 done
10265 echo "--------------------------"
10266 done
10267 }
10268
10269 bfd_dump
10270
10271 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
10272 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
10273 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
10274 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
10275
10276 echo $hv1_gw1_ofport
10277 echo $hv1_gw2_ofport
10278 echo $hv2_gw1_ofport
10279 echo $hv2_gw2_ofport
10280
10281 echo "--- hv1 ---"
10282 as hv1 ovs-ofctl dump-flows br-int table=32
10283
10284 echo "--- hv2 ---"
10285 as hv2 ovs-ofctl dump-flows br-int table=32
10286
10287 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
10288 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
10289
10290 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10291 grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
10292 | wc -l], [0], [1
10293 ])
10294
10295 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10296 grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
10297 | wc -l], [0], [1
10298 ])
10299
10300 # make sure that flows for handling the outside router port reside on gw1
10301 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10302 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10303 ]])
10304 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10305 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10306 ]])
10307
10308 # make sure ARP responder flows for outside router port reside on gw1 too
10309 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
10310 grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
10311 ]])
10312 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
10313 ]])
10314
10315 # check that the chassis redirect port has been claimed by the gw1 chassis
10316 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10317 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10318 ]])
10319
10320 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
10321 hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
10322
10323 exp_ref_ch_list=''
10324 for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
10325 do
10326 if test $i = $hv1_ch_uuid; then
10327 exp_ref_ch_list="${exp_ref_ch_list}$i"
10328 elif test $i = $hv2_ch_uuid; then
10329 exp_ref_ch_list="${exp_ref_ch_list}$i"
10330 fi
10331 done
10332
10333 OVS_WAIT_UNTIL(
10334 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10335 # Trim the spaces.
10336 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10337 test "$exp_ref_ch_list" = "$ref_ch_list"])
10338
10339
10340 # at this point, we invert the priority of the gw chassis between gw1 and gw2
10341
10342 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10343 name=outside_gw1 chassis_name=gw1 priority=10 -- \
10344 --id=@gc1 create Gateway_Chassis \
10345 name=outside_gw2 chassis_name=gw2 priority=20 -- \
10346 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10347
10348
10349 # XXX: Let the change propagate down to the ovn-controllers
10350 ovn-nbctl --wait=hv --timeout=3 sync
10351
10352 # we make sure that the hypervisors noticed, and inverted the slave ports
10353 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10354 grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
10355 | wc -l], [0], [1
10356 ])
10357
10358 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10359 grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
10360 | wc -l], [0], [1
10361 ])
10362
10363 # check that the chassis redirect port has been reclaimed by the gw2 chassis
10364 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10365 logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
10366 ]])
10367
10368 # check BFD enablement on tunnel ports from gw1 #########
10369 as gw1
10370 for chassis in gw2 hv1 hv2; do
10371 echo "checking gw1 -> $chassis"
10372 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10373 [[enable=true
10374 ]])
10375 done
10376
10377
10378 # check BFD enablement on tunnel ports from gw2 ##########
10379 as gw2
10380 for chassis in gw1 hv1 hv2; do
10381 echo "checking gw2 -> $chassis"
10382 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10383 [[enable=true
10384 ]])
10385 done
10386
10387 # check BFD enablement on tunnel ports from hv1 ###########
10388 as hv1
10389 for chassis in gw1 gw2; do
10390 echo "checking hv1 -> $chassis"
10391 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10392 [[enable=true
10393 ]])
10394 done
10395 # make sure BFD is not enabled to hv2, we don't need it
10396 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
10397 [[
10398 ]])
10399
10400
10401 # check BFD enablement on tunnel ports from hv2 ##########
10402 as hv2
10403 for chassis in gw1 gw2; do
10404 echo "checking hv2 -> $chassis"
10405 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10406 [[enable=true
10407 ]])
10408 done
10409 # make sure BFD is not enabled to hv1, we don't need it
10410 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
10411 [[
10412 ]])
10413
10414 # make sure that flows for handling the outside router port reside on gw2 now
10415 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10416 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10417 ]])
10418 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10419 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10420 ]])
10421
10422 # disconnect GW2 from the network, GW1 should take over
10423 as gw2
10424 port=${sandbox}_br-phys
10425 as main ovs-vsctl del-port n1 $port
10426
10427 bfd_dump
10428
10429 # make sure that flows for handling the outside router port reside on gw2 now
10430 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10431 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10432 ]])
10433 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10434 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10435 ]])
10436
10437 # check that the chassis redirect port has been reclaimed by the gw1 chassis
10438 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10439 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10440 ]])
10441
10442 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
10443 as gw2
10444 for chassis in gw1 hv1 hv2; do
10445 echo "checking gw2 -> $chassis"
10446 OVS_WAIT_UNTIL([
10447 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10448 test "$bfd_cfg" = "enable=true min_rx=2000"
10449 ])
10450 done
10451 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
10452 for chassis in gw1 hv1 hv2; do
10453 echo "checking gw2 -> $chassis"
10454 OVS_WAIT_UNTIL([
10455 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10456 test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
10457 ])
10458 done
10459 ovn-nbctl remove NB_Global . options "bfd-min-rx"
10460 ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
10461 for chassis in gw1 hv1 hv2; do
10462 echo "checking gw2 -> $chassis"
10463 OVS_WAIT_UNTIL([
10464 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10465 test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
10466 ])
10467 done
10468
10469 # Delete the inside1 vif. The ref_chassis in ha_chassis_group shouldn't have
10470 # reference to hv1.
10471 as hv1 ovs-vsctl del-port hv1-vif1
10472
10473 OVS_WAIT_UNTIL(
10474 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10475 # Trim the spaces.
10476 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10477 test "$hv2_ch_uuid" = "$ref_ch_list"])
10478
10479 # Delete the inside2 vif.
10480 ovn-sbctl show
10481
10482 echo "Deleting hv2-vif1"
10483 as hv2 ovs-vsctl del-port hv2-vif1
10484
10485 # ref_chassis of ha_chassis_group should be empty
10486 OVS_WAIT_UNTIL(
10487 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10488 # Trim the spaces.
10489 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10490 exp_ref_ch_list=""
10491 test "$exp_ref_ch_list" = "$ref_ch_list"])
10492
10493 # Delete the Gateway_Chassis for lrp - outside
10494 ovn-nbctl clear Logical_Router_Port outside gateway_chassis
10495
10496 # There shoud be no ha_chassis_group rows in SB DB.
10497 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis_group | wc -l`])
10498 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
10499
10500 ovn-nbctl remove NB_Global . options "bfd-min-rx"
10501 ovn-nbctl remove NB_Global . options "bfd-min-tx"
10502 ovn-nbctl remove NB_Global . options "bfd-mult"
10503
10504 # Now test with HA chassis group instead of Gateway chassis in NB DB
10505 ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
10506
10507 ovn-nbctl list ha_chassis_group
10508 ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1
10509 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
10510 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw1 30
10511 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 20
10512
10513 # ovn-northd should not create HA chassis group and HA chassis rows
10514 # unless the HA chassis group in OVN NB DB is associated to
10515 # a logical router port.
10516 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
10517
10518 # Associate hagrp1 to outside logical router port
10519 ovn-nbctl set Logical_Router_Port outside ha_chassis_group=$hagrp1_uuid
10520
10521 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns _uuid \
10522 find ha_chassis_group | wc -l`])
10523
10524 OVS_WAIT_UNTIL([test 2 = `ovn-sbctl list ha_chassis | grep chassis | \
10525 grep -v chassis-name | wc -l`])
10526
10527 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10528 grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
10529 | wc -l], [0], [1
10530 ])
10531
10532 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10533 grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
10534 | wc -l], [0], [1
10535 ])
10536
10537 # make sure that flows for handling the outside router port reside on gw1
10538 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10539 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10540 ]])
10541 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10542 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10543 ]])
10544
10545 # make sure ARP responder flows for outside router port reside on gw1 too
10546 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
10547 grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
10548 ]])
10549 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
10550 ]])
10551
10552 # check that the chassis redirect port has been claimed by the gw1 chassis
10553 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10554 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10555 ]])
10556
10557 # Re add the ovs ports.
10558 for i in 1 2; do
10559 as hv$i
10560 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10561 set interface hv$i-vif1 external-ids:iface-id=inside$i \
10562 options:tx_pcap=hv$i/vif1-tx.pcap \
10563 options:rxq_pcap=hv$i/vif1-rx.pcap \
10564 ofport-request=1
10565 done
10566
10567 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
10568 hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
10569
10570 exp_ref_ch_list=''
10571 for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
10572 do
10573 if test $i = $hv1_ch_uuid; then
10574 exp_ref_ch_list="${exp_ref_ch_list}$i"
10575 elif test $i = $hv2_ch_uuid; then
10576 exp_ref_ch_list="${exp_ref_ch_list}$i"
10577 fi
10578 done
10579
10580 OVS_WAIT_UNTIL(
10581 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10582 # Trim the spaces.
10583 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10584 test "$exp_ref_ch_list" = "$ref_ch_list"])
10585
10586 # Increase the priority of gw2
10587 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 40
10588
10589 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10590 grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
10591 | wc -l], [0], [1
10592 ])
10593
10594 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10595 grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
10596 | wc -l], [0], [1
10597 ])
10598
10599 # check that the chassis redirect port has been reclaimed by the gw2 chassis
10600 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10601 logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
10602 ]])
10603
10604 # check BFD enablement on tunnel ports from gw1 #########
10605 as gw1
10606 for chassis in gw2 hv1 hv2; do
10607 echo "checking gw1 -> $chassis"
10608 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10609 [[enable=true
10610 ]])
10611 done
10612
10613 # check BFD enablement on tunnel ports from gw2 ##########
10614 as gw2
10615 for chassis in gw1 hv1 hv2; do
10616 echo "checking gw2 -> $chassis"
10617 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10618 [[enable=true
10619 ]])
10620 done
10621
10622 # check BFD enablement on tunnel ports from hv1 ###########
10623 as hv1
10624 for chassis in gw1 gw2; do
10625 echo "checking hv1 -> $chassis"
10626 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10627 [[enable=true
10628 ]])
10629 done
10630 # make sure BFD is not enabled to hv2, we don't need it
10631 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
10632 [[
10633 ]])
10634
10635 # check BFD enablement on tunnel ports from hv2 ##########
10636 as hv2
10637 for chassis in gw1 gw2; do
10638 echo "checking hv2 -> $chassis"
10639 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10640 [[enable=true
10641 ]])
10642 done
10643 # make sure BFD is not enabled to hv1, we don't need it
10644 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
10645 [[
10646 ]])
10647
10648 # make sure that flows for handling the outside router port reside on gw2 now
10649 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10650 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10651 ]])
10652 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10653 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10654 ]])
10655
10656 # disconnect GW2 from the network, GW1 should take over
10657 as gw2
10658 port=${sandbox}_br-phys
10659 as main ovs-vsctl del-port n1 $port
10660
10661 bfd_dump
10662
10663 # make sure that flows for handling the outside router port reside on gw2 now
10664 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10665 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10666 ]])
10667 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10668 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10669 ]])
10670
10671 # check that the chassis redirect port has been reclaimed by the gw1 chassis
10672 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10673 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10674 ]])
10675
10676 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
10677
10678 AT_CLEANUP
10679
10680 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
10681 AT_SKIP_IF([test $HAVE_PYTHON = no])
10682 ovn_start
10683 ovn-nbctl ls-add ls0
10684 ovn-nbctl ls-add ls1
10685 ovn-nbctl create Logical_Router name=lr0
10686 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
10687
10688 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10689 name=outside_gw1 chassis_name=hv2 priority=10 -- \
10690 --id=@gc1 create Gateway_Chassis \
10691 name=outside_gw2 chassis_name=hv3 priority=1 -- \
10692 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
10693
10694 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
10695 type=router options:router-port=lrp0 addresses="router"
10696 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
10697 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
10698 type=router options:router-port=lrp1 addresses="router"
10699
10700 # Add NAT rules
10701 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
10702
10703 net_add n1
10704 sim_add hv1
10705 as hv1
10706 ovs-vsctl add-br br-phys
10707 ovn_attach n1 br-phys 192.168.0.1
10708 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10709 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])
10710
10711 sim_add hv2
10712 as hv2
10713 ovs-vsctl add-br br-phys
10714 ovn_attach n1 br-phys 192.168.0.2
10715 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10716
10717 sim_add hv3
10718 as hv3
10719 ovs-vsctl add-br br-phys
10720 ovn_attach n1 br-phys 192.168.0.3
10721 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10722
10723 # Create a localnet port.
10724 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
10725 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
10726 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
10727 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
10728
10729 # wait for earlier changes to take effect
10730 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
10731
10732 reset_pcap_file() {
10733 local iface=$1
10734 local pcap_file=$2
10735 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10736 options:rxq_pcap=dummy-rx.pcap
10737 rm -f ${pcap_file}*.pcap
10738 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10739 options:rxq_pcap=${pcap_file}-rx.pcap
10740 }
10741
10742 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10743 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10744 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10745 # add nat-addresses option
10746 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
10747
10748 # Wait for packets to be received through hv2.
10749 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10750 trim_zeros() {
10751 sed 's/\(00\)\{1,\}$//'
10752 }
10753
10754 only_broadcast_from_lrp1() {
10755 grep "fffffffffffff00000000001"
10756 }
10757
10758 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
10759 echo $garp > expout
10760
10761 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
10762 echo "packets on hv1-snoopvif:"
10763 cat hv1_snoop_tx
10764 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
10765 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10766 echo "packets on hv2 br-phys tx"
10767 cat hv2_br_phys_tx
10768 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
10769 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10770 echo "packets on hv3 br-phys tx"
10771 cat hv3_br_phys_tx
10772 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
10773
10774
10775 # at this point, we invert the priority of the gw chassis between hv2 and hv3
10776
10777 ovn-nbctl --wait=hv \
10778 --id=@gc0 create Gateway_Chassis \
10779 name=outside_gw1 chassis_name=hv2 priority=1 -- \
10780 --id=@gc1 create Gateway_Chassis \
10781 name=outside_gw2 chassis_name=hv3 priority=10 -- \
10782 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
10783
10784
10785 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10786 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10787 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10788
10789 # Wait for packets to be received.
10790 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10791 trim_zeros() {
10792 sed 's/\(00\)\{1,\}$//'
10793 }
10794
10795 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
10796 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
10797 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10798 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
10799 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10800 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
10801
10802 # change localnet port tag.
10803 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
10804
10805 # wait for earlier changes to take effect
10806 OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-ofctl dump-flows br-int table=65 | \
10807 grep "actions=mod_vlan_vid:2014" | wc -l`
10808 ])
10809
10810 OVS_WAIT_UNTIL([test 1 = `as hv3 ovs-ofctl dump-flows br-int table=65 | \
10811 grep "actions=mod_vlan_vid:2014" | wc -l`
10812 ])
10813
10814 # update nat-addresses option
10815 ovn-nbctl --wait=hv clear logical_switch_port lrp0-rp options
10816
10817 #Wait until the Port_Binding.nat_addresses is cleared.
10818 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl --bare --columns nat_addresses find port_binding \
10819 logical_port=lrp0-rp | grep is_chassis | wc -l`])
10820
10821 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10822 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10823 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10824
10825 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
10826
10827 #Wait until the Port_Binding.nat_addresses is set.
10828 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns nat_addresses find port_binding \
10829 logical_port=lrp0-rp | grep is_chassis | wc -l`])
10830
10831 # Wait for packets to be received.
10832 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10833 trim_zeros() {
10834 sed 's/\(00\)\{1,\}$//'
10835 }
10836
10837 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
10838 echo $garp > expout
10839
10840 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
10841 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
10842 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10843 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
10844 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10845 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
10846
10847 OVN_CLEANUP([hv1],[hv2],[hv3])
10848
10849 AT_CLEANUP
10850
10851 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
10852 AT_SKIP_IF([test $HAVE_PYTHON = no])
10853 ovn_start
10854
10855 net_add n1
10856
10857 # create two gateways with external network connectivity
10858 for i in 1 2; do
10859 sim_add gw$i
10860 as gw$i
10861 ovs-vsctl add-br br-phys
10862 ovn_attach n1 br-phys 192.168.0.$i
10863 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10864 done
10865
10866 ovn-nbctl ls-add inside
10867 ovn-nbctl ls-add outside
10868
10869 # create one hypervisors with a vif port the internal network
10870 sim_add hv1
10871 as hv1
10872 ovs-vsctl add-br br-phys
10873 ovn_attach n1 br-phys 192.168.0.11
10874 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10875 set interface hv1-vif1 external-ids:iface-id=inside1 \
10876 options:tx_pcap=hv1/vif1-tx.pcap \
10877 options:rxq_pcap=hv1/vif1-rx.pcap \
10878 ofport-request=1
10879
10880 ovn-nbctl lsp-add inside inside1 \
10881 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
10882
10883
10884 OVN_POPULATE_ARP
10885
10886 ovn-nbctl create Logical_Router name=R1
10887
10888 # Connect inside to R1
10889 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
10890 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
10891 type=router options:router-port=inside \
10892 -- lsp-set-addresses rp-inside router
10893
10894 # Connect outside to R1 as distributed router gateway port on gw1+gw2
10895 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
10896
10897 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10898 name=outside_gw1 chassis_name=gw1 priority=20 -- \
10899 --id=@gc1 create Gateway_Chassis \
10900 name=outside_gw2 chassis_name=gw2 priority=10 -- \
10901 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10902
10903 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
10904 type=router options:router-port=outside \
10905 -- lsp-set-addresses rp-outside router
10906
10907 # Create localnet port in outside
10908 ovn-nbctl lsp-add outside ln-outside
10909 ovn-nbctl lsp-set-addresses ln-outside unknown
10910 ovn-nbctl lsp-set-type ln-outside localnet
10911 ovn-nbctl lsp-set-options ln-outside network_name=phys
10912
10913 # Allow some time for ovn-northd and ovn-controller to catch up.
10914 ovn-nbctl --wait=hv --timeout=3 sync
10915
10916 # currently when ovn-controller is restarted, the old entry is deleted
10917 # and a new one is created, which leaves the Gateway_Chassis with
10918 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
10919 # doesn't have the same effect because "name" is conserved, and the
10920 # Chassis entry is not replaced.
10921
10922 > gw1/ovn-controller.log
10923
10924 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
10925 ovn-sbctl destroy Chassis $gw2_chassis
10926
10927 OVS_WAIT_UNTIL([test 0 = `grep -c "Releasing lport" gw1/ovn-controller.log`])
10928
10929 OVN_CLEANUP([gw1],[gw2],[hv1])
10930
10931 AT_CLEANUP
10932
10933 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
10934 AT_KEYWORDS([ovn-nd_ns for unknown mac])
10935 AT_SKIP_IF([test $HAVE_PYTHON = no])
10936 ovn_start
10937
10938 ovn-nbctl ls-add sw0_ip6
10939 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
10940 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
10941 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
10942
10943 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
10944 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
10945
10946 ovn-nbctl lr-add lr0_ip6
10947 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
10948 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
10949 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
10950 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
10951 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
10952 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
10953
10954 ovn-nbctl ls-add public
10955 ovn-nbctl lsp-add public ln-public
10956 ovn-nbctl lsp-set-addresses ln-public unknown
10957 ovn-nbctl lsp-set-type ln-public localnet
10958 ovn-nbctl lsp-set-options ln-public network_name=phys
10959
10960 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
10961 2001:db8:1:0:200:02ff:fe01:0204/64 \
10962 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
10963
10964 #install static route
10965 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
10966 ip_prefix="\:\:/0" nexthop="2001\:db8\:1\:0\:200\:02ff\:fe01\:1305" \
10967 -- add Logical_Router lr0_ip6 static_routes @lrt
10968
10969 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
10970 rp-ip6_public type=router options:router-port=ip6_public \
10971 -- lsp-set-addresses rp-ip6_public router
10972
10973 net_add n1
10974 sim_add hv1
10975 as hv1
10976 ovs-vsctl add-br br-phys
10977 ovn_attach n1 br-phys 192.168.0.2
10978
10979 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10980 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
10981 options:tx_pcap=hv1/vif1-tx.pcap \
10982 options:rxq_pcap=hv1/vif1-rx.pcap \
10983 ofport-request=1
10984 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10985
10986 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
10987
10988 # There should be 2 Neighbor Advertisement flows for the router port
10989 # aef0:: ip address in logical switch pipeline with action nd_na_router.
10990 AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
10991 grep "nd_na_router" | wc -l], [0], [2
10992 ])
10993
10994 # There should be 4 Neighbor Advertisement flows with action nd_na_router
10995 # in the router pipeline for the router lr0_ip6.
10996 AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
10997 wc -l], [0], [4
10998 ])
10999
11000 cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
11001
11002 # There is only one chassis.
11003 chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
11004 OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
11005
11006 trim_zeros() {
11007 sed 's/\(00\)\{1,\}$//'
11008 }
11009
11010 reset_pcap_file() {
11011 local iface=$1
11012 local pcap_file=$2
11013 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11014 options:rxq_pcap=dummy-rx.pcap
11015 rm -f ${pcap_file}*.pcap
11016 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11017 options:rxq_pcap=${pcap_file}-rx.pcap
11018 }
11019
11020 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
11021 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
11022 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
11023 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11024 # This function sends ipv6 packet
11025 test_ipv6() {
11026 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11027 local dst_mcast_mac=$6 mcast_node_ip=$7 nd_target=$8
11028
11029 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
11030 packet=${packet}8000000000000000
11031
11032 src_mac=000002010204
11033 expected_packet=${dst_mcast_mac}${src_mac}86dd6000000000203aff${src_ip}
11034 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000
11035 expected_packet=${expected_packet}${nd_target}0101${src_mac}
11036
11037 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
11038 rm -f ipv6_ns.expected
11039 echo $expected_packet >> ipv6_ns.expected
11040 }
11041
11042 src_mac=506400000002
11043 dst_mac=00000000af01
11044 src_ip=aef0000000000000526400fffe000002
11045 dst_ip=20010db800010000020002fffe010205
11046 dst_mcast_mac=3333ff010205
11047 mcast_node_ip=ff0200000000000000000001ff010205
11048 nd_target=20010db800010000020002fffe010205
11049 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
11050 # should be received by the ports attached to br-phys.
11051 test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
11052 $mcast_node_ip $nd_target
11053
11054 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
11055 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
11056
11057 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
11058 trim_zeros > 1.packets
11059 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
11060 trim_zeros > 2.packets
11061
11062 cat ipv6_ns.expected | cut -c -112 > expout
11063 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
11064 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
11065
11066 # Skipping the ICMPv6 checksum
11067 cat ipv6_ns.expected | cut -c 117- > expout
11068 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
11069 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
11070
11071 # Now send a packet with destination ip other than
11072 # 2001:db8:1:0:200:02ff:fe01:0204/64 prefix.
11073 reset_pcap_file br-phys_n1 hv1/br-phys_n1
11074 reset_pcap_file br-phys hv1/br-phys
11075
11076 src_mac=506400000002
11077 dst_mac=00000000af01
11078 src_ip=aef0000000000000526400fffe000002
11079 dst_ip=20020ab8000100000200020000020306
11080 # multicast mac of the nexthop IP - 2001:db8:1:0:200:02ff:fe01:1305
11081 dst_mcast_mac=3333ff011305
11082 mcast_node_ip=ff0200000000000000000001ff011305
11083 nd_target=20010db800010000020002fffe011305
11084 test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
11085 $mcast_node_ip $nd_target
11086
11087 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
11088 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
11089
11090 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
11091 trim_zeros > 1.packets
11092 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
11093 trim_zeros > 2.packets
11094
11095 cat ipv6_ns.expected | cut -c -112 > expout
11096 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
11097 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
11098
11099 # Skipping the ICMPv6 checksum
11100 cat ipv6_ns.expected | cut -c 117- > expout
11101 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
11102 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
11103
11104 OVN_CLEANUP([hv1])
11105
11106 AT_CLEANUP
11107
11108 AT_SETUP([ovn -- options:requested-chassis for logical port])
11109 ovn_start
11110
11111 net_add n1
11112
11113 ovn-nbctl ls-add ls0
11114 ovn-nbctl lsp-add ls0 lsp0
11115
11116 # create two hypervisors, each with one vif port
11117 sim_add hv1
11118 as hv1
11119 ovs-vsctl add-br br-phys
11120 ovn_attach n1 br-phys 192.168.0.11
11121 ovs-vsctl -- add-port br-int hv1-vif0 -- \
11122 set Interface hv1-vif0 ofport-request=1
11123
11124 sim_add hv2
11125 as hv2
11126 ovs-vsctl add-br br-phys
11127 ovn_attach n1 br-phys 192.168.0.12
11128 ovs-vsctl -- add-port br-int hv2-vif0 -- \
11129 set Interface hv2-vif0 ofport-request=1
11130
11131 # Allow only chassis hv1 to bind logical port lsp0.
11132 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
11133
11134 # Allow some time for ovn-northd and ovn-controller to catch up.
11135 ovn-nbctl --wait=hv --timeout=3 sync
11136
11137 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
11138 ovn-sbctl wait-until chassis hv1
11139 ovn-sbctl wait-until chassis hv2
11140 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
11141 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
11142
11143 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
11144 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
11145 as hv2
11146 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
11147
11148 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
11149 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
11150
11151 # (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
11152 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11153 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11154
11155 # (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
11156 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
11157 as hv1
11158 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
11159
11160 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
11161 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
11162
11163 # (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
11164 as hv1 ovs-ofctl dump-flows br-int
11165 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11166 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11167
11168 # (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
11169 # the requested chassis for lsp0 is changed from hv1 to hv2.
11170 echo "verifying that lsp0 binding moves when requested-chassis is changed"
11171
11172 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
11173 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
11174 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
11175
11176 # (6) Chassis hv2 should add flows and hv1 should not.
11177 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11178 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11179
11180 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11181 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11182
11183 OVN_CLEANUP([hv1],[hv2])
11184
11185 AT_CLEANUP
11186
11187 AT_SETUP([ovn -- options:requested-chassis with hostname])
11188
11189 ovn_start
11190
11191 ovn-nbctl ls-add ls0
11192 ovn-nbctl lsp-add ls0 lsp0
11193
11194 net_add n1
11195 sim_add hv1
11196 as hv1
11197 ovs-vsctl add-br br-phys
11198 ovn_attach n1 br-phys 192.168.0.11
11199 ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
11200
11201 ovn-sbctl wait-until chassis hv1
11202 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
11203 echo "hv1_hostname=${hv1_hostname}"
11204 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
11205 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
11206
11207 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
11208 echo "hv1_uuid=${hv1_uuid}"
11209 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
11210 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
11211 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11212 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11213
11214 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
11215 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
11216 ovn-nbctl --wait=hv --timeout=3 sync
11217 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
11218 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11219 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11220
11221 OVN_CLEANUP([hv1])
11222
11223 AT_CLEANUP
11224
11225 AT_SETUP([ovn -- IPv6 periodic RA])
11226 ovn_start
11227
11228 # This test sets up two hypervisors.
11229 # hv1 and hv2 run ovn-controllers, and
11230 # each has a VIF connected to the same
11231 # logical switch in OVN. The logical
11232 # switch is connected to a logical
11233 # router port that is configured to send
11234 # periodic router advertisements.
11235 #
11236 # The reason for having two ovn-controller
11237 # hypervisors is to ensure that the
11238 # periodic RAs being sent by each ovn-controller
11239 # are kept to their local hypervisors. If the
11240 # packets are not kept local, then each port
11241 # will receive too many RAs.
11242
11243 net_add n1
11244 sim_add hv1
11245 sim_add hv2
11246 as hv1
11247 ovs-vsctl add-br br-phys
11248 ovn_attach n1 br-phys 192.168.0.2
11249 as hv2
11250 ovs-vsctl add-br br-phys
11251 ovn_attach n1 br-phys 192.168.0.3
11252
11253 ovn-nbctl lr-add ro
11254 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
11255
11256 ovn-nbctl ls-add sw
11257 ovn-nbctl lsp-add sw sw-ro
11258 ovn-nbctl lsp-set-type sw-ro router
11259 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
11260 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
11261 ovn-nbctl lsp-add sw sw-p1
11262 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
11263 ovn-nbctl lsp-add sw sw-p2
11264 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
11265
11266 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
11267 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
11268 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
11269 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
11270
11271 for i in 1 2 ; do
11272 as hv$i
11273 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
11274 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
11275 options:tx_pcap=hv$i/vif1-tx.pcap \
11276 options:rxq_pcap=hv$i/vif1-rx.pcap \
11277 ofport-request=1
11278 done
11279
11280 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
11281 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
11282
11283 reset_pcap_file() {
11284 local iface=$1
11285 local pcap_file=$2
11286 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11287 options:rxq_pcap=dummy-rx.pcap
11288 rm -f ${pcap_file}*.pcap
11289 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11290 options:rxq_pcap=${pcap_file}-rx.pcap
11291
11292 }
11293
11294 construct_expected_ra() {
11295 local src_mac=000000000001
11296 local dst_mac=333300000001
11297 local src_addr=fe80000000000000020000fffe000001
11298 local dst_addr=ff020000000000000000000000000001
11299
11300 local mtu=$1
11301 local ra_mo=$2
11302 local ra_prefix_la=$3
11303
11304 local slla=0101${src_mac}
11305 local mtu_opt=""
11306 if test $mtu != 0; then
11307 mtu_opt=05010000${mtu}
11308 fi
11309 shift 3
11310
11311 local prefix=""
11312 while [[ $# -gt 0 ]] ; do
11313 local size=$1
11314 local net=$2
11315 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
11316 shift 2
11317 done
11318
11319 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
11320 local icmp=8600XXXX${ra}
11321
11322 local ip_len=$(expr ${#icmp} / 2)
11323 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
11324
11325 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
11326 local eth=${dst_mac}${src_mac}86dd${ip}
11327 local packet=${eth}
11328 echo $packet >> expected
11329 }
11330
11331 ra_test() {
11332 construct_expected_ra $@
11333
11334 for i in hv1 hv2 ; do
11335 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
11336
11337 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
11338
11339 cat expected | cut -c -112 > expout
11340 AT_CHECK([cat packets | cut -c -112], [0], [expout])
11341
11342 # Skip ICMPv6 checksum.
11343 cat expected | cut -c 117- > expout
11344 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
11345
11346 rm -f packets
11347 as $i reset_pcap_file $i-vif1 $i/vif1
11348 done
11349
11350 rm -f expected
11351 }
11352
11353 # Baseline test with no MTU
11354 ra_test 0 00 c0 40 aef00000000000000000000000000000
11355
11356 # Now make sure an MTU option makes it
11357 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
11358 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
11359
11360 # Now test for multiple network prefixes
11361 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
11362 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11363
11364 # Test a different address mode now
11365 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
11366 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11367
11368 # And the other address mode
11369 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
11370 ra_test 000005dc 40 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11371
11372 OVN_CLEANUP([hv1],[hv2])
11373 AT_CLEANUP
11374
11375 AT_SETUP([ovn -- ACL reject rule test])
11376 AT_KEYWORDS([acl-reject])
11377 AT_SKIP_IF([test $HAVE_PYTHON = no])
11378 ovn_start
11379
11380 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
11381 #
11382 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
11383 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
11384 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
11385 # unreachable frame generated from ACL rule hit
11386 #
11387 # INPORT is a lport number, e.g. 11 for vif11.
11388 # HV is a hypervisor number
11389 # ETH_SRC and ETH_DST are each 12 hex digits.
11390 # IPV4_SRC and IPV4_DST are each 8 hex digits.
11391 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
11392 test_ip_packet() {
11393 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
11394 local exp_ip_chksum=$8 exp_icmp_chksum=$9
11395 shift 9
11396
11397 local ip_ttl=ff
11398 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
11399
11400 local reply_icmp_ttl=ff
11401 local icmp_type_code_response=0301
11402 local icmp_data=00000000
11403 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
11404 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
11405 echo $reply >> vif$inport.expected
11406
11407 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11408 }
11409
11410 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
11411 #
11412 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
11413 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
11414 # EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
11415 test_ipv6_packet() {
11416 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
11417 shift 7
11418
11419 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
11420 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
11421
11422 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
11423 echo $reply >> vif$inport.expected
11424
11425 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11426 }
11427
11428 # 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
11429 #
11430 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
11431 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
11432 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
11433 #
11434 # INPORT is an lport number, e.g. 11 for vif11.
11435 # HV is an hypervisor number
11436 # ETH_SRC and ETH_DST are each 12 hex digits.
11437 # IPV4_SRC and IPV4_DST are each 8 hex digits.
11438 # TCP_SPORT and TCP_DPORT are 4 hex digits.
11439 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
11440 test_tcp_syn_packet() {
11441 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
11442 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
11443 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
11444 shift 12
11445
11446 local ip_ttl=ff
11447 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
11448
11449 local tcp_rst_ttl=ff
11450 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
11451 echo $reply >> vif$inport.expected
11452
11453 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11454 }
11455
11456 # Create hypervisors hv[123].
11457 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
11458 # Add all of the vifs to a single logical switch sw0.
11459
11460 net_add n1
11461 ovn-nbctl ls-add sw0
11462 for i in 1 2 3; do
11463 sim_add hv$i
11464 as hv$i
11465 ovs-vsctl add-br br-phys
11466 ovn_attach n1 br-phys 192.168.0.$i
11467
11468 for j in 1 2 3; do
11469 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
11470 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
11471
11472 ovs-vsctl -- add-port br-int vif$i$j -- \
11473 set interface vif$i$j \
11474 external-ids:iface-id=sw0-p$i$j \
11475 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
11476 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
11477 ofport-request=$i$j
11478 done
11479 done
11480
11481 OVN_POPULATE_ARP
11482 # allow some time for ovn-northd and ovn-controller to catch up.
11483 sleep 1
11484
11485 ip_to_hex() {
11486 printf "%02x%02x%02x%02x" "$@"
11487 }
11488
11489 for i in 1 2 3; do
11490 : > vif${i}1.expected
11491 done
11492
11493 ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
11494 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
11495 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
11496
11497 # Allow some time for ovn-northd and ovn-controller to catch up.
11498 ovn-nbctl --timeout=3 --wait=hv sync
11499
11500 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
11501 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
11502 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
11503
11504 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
11505
11506 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
11507 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
11508 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
11509
11510 for i in 1 2 3; do
11511 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
11512 done
11513
11514 OVN_CLEANUP([hv1], [hv2], [hv3])
11515 AT_CLEANUP
11516
11517 AT_SETUP([ovn -- Port Groups])
11518 AT_KEYWORDS([ovnpg])
11519 AT_SKIP_IF([test $HAVE_PYTHON = no])
11520 ovn_start
11521
11522 # Logical network:
11523 #
11524 # Three logical switches ls1, ls2, ls3.
11525 # One logical router lr0 connected to ls[123],
11526 # with nine subnets, three per logical switch:
11527 #
11528 # lrp11 on ls1 for subnet 192.168.11.0/24
11529 # lrp12 on ls1 for subnet 192.168.12.0/24
11530 # lrp13 on ls1 for subnet 192.168.13.0/24
11531 # ...
11532 # lrp33 on ls3 for subnet 192.168.33.0/24
11533 #
11534 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
11535 # digits are the subnet and the last digit distinguishes the VIF.
11536 #
11537 # This test will create two port groups and uses them in ACL.
11538
11539 get_lsp_uuid () {
11540 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
11541 }
11542
11543 pg1_ports=
11544 pg2_ports=
11545 for i in 1 2 3; do
11546 ovn-nbctl ls-add ls$i
11547 for j in 1 2 3; do
11548 for k in 1 2 3; do
11549 ovn-nbctl \
11550 -- lsp-add ls$i lp$i$j$k \
11551 -- lsp-set-addresses lp$i$j$k \
11552 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
11553 # logical ports lp[12]?1 belongs to port group pg1
11554 if test $i != 3 && test $k == 1; then
11555 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
11556 fi
11557 # logical ports lp[23]?2 belongs to port group pg2
11558 if test $i != 1 && test $k == 2; then
11559 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
11560 fi
11561 done
11562 done
11563 done
11564
11565 ovn-nbctl lr-add lr0
11566 for i in 1 2 3; do
11567 for j in 1 2 3; do
11568 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
11569 ovn-nbctl \
11570 -- lsp-add ls$i lrp$i$j-attachment \
11571 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
11572 options:router-port=lrp$i$j \
11573 addresses='"00:00:00:00:ff:'$i$j'"'
11574 done
11575 done
11576
11577 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
11578 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
11579
11580 # create ACLs on all lswitches to drop traffic from pg2 to pg1
11581 ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11582 ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11583 ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11584
11585 # Physical network:
11586 #
11587 # Three hypervisors hv[123].
11588 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
11589 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
11590 # lp?3[123] all on hv3.
11591
11592 # Given the name of a logical port, prints the name of the hypervisor
11593 # on which it is located.
11594 vif_to_hv() {
11595 case $1 in dnl (
11596 ?11) echo 1 ;; dnl (
11597 ?12 | ?21 | ?22) echo 2 ;; dnl (
11598 ?13 | ?23 | ?3?) echo 3 ;;
11599 esac
11600 }
11601
11602 # Given the name of a logical port, prints the name of its logical router
11603 # port, e.g. "vif_to_lrp 123" yields 12.
11604 vif_to_lrp() {
11605 echo ${1%?}
11606 }
11607
11608 # Given the name of a logical port, prints the name of its logical
11609 # switch, e.g. "vif_to_ls 123" yields 1.
11610 vif_to_ls() {
11611 echo ${1%??}
11612 }
11613
11614 net_add n1
11615 for i in 1 2 3; do
11616 sim_add hv$i
11617 as hv$i
11618 ovs-vsctl add-br br-phys
11619 ovn_attach n1 br-phys 192.168.0.$i
11620 done
11621 for i in 1 2 3; do
11622 for j in 1 2 3; do
11623 for k in 1 2 3; do
11624 hv=`vif_to_hv $i$j$k`
11625 as hv$hv ovs-vsctl \
11626 -- add-port br-int vif$i$j$k \
11627 -- set Interface vif$i$j$k \
11628 external-ids:iface-id=lp$i$j$k \
11629 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
11630 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
11631 ofport-request=$i$j$k
11632 done
11633 done
11634 done
11635
11636 # Pre-populate the hypervisors' ARP tables so that we don't lose any
11637 # packets for ARP resolution (native tunneling doesn't queue packets
11638 # for ARP resolution).
11639 OVN_POPULATE_ARP
11640
11641 # Allow some time for ovn-northd and ovn-controller to catch up.
11642 # XXX This should be more systematic.
11643 sleep 1
11644
11645 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11646 #
11647 # This shell function causes a packet to be received on INPORT. The packet's
11648 # content has Ethernet destination DST and source SRC (each exactly 12 hex
11649 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
11650 # more) list the VIFs on which the packet should be received. INPORT and the
11651 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
11652 for i in 1 2 3; do
11653 for j in 1 2 3; do
11654 for k in 1 2 3; do
11655 : > $i$j$k.expected
11656 done
11657 done
11658 done
11659 test_ip() {
11660 # This packet has bad checksums but logical L3 routing doesn't check.
11661 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11662 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
11663 shift; shift; shift; shift; shift
11664 hv=hv`vif_to_hv $inport`
11665 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
11666 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
11667 in_ls=`vif_to_ls $inport`
11668 in_lrp=`vif_to_lrp $inport`
11669 for outport; do
11670 out_ls=`vif_to_ls $outport`
11671 if test $in_ls = $out_ls; then
11672 # Ports on the same logical switch receive exactly the same packet.
11673 echo $packet
11674 else
11675 # Routing decrements TTL and updates source and dest MAC
11676 # (and checksum).
11677 out_lrp=`vif_to_lrp $outport`
11678 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
11679 fi >> $outport.expected
11680 done
11681 }
11682
11683 as hv1 ovs-vsctl --columns=name,ofport list interface
11684 as hv1 ovn-sbctl list port_binding
11685 as hv1 ovn-sbctl list datapath_binding
11686 as hv1 ovn-sbctl list port_group
11687 as hv1 ovn-sbctl list address_set
11688 as hv1 ovn-sbctl dump-flows
11689 as hv1 ovs-ofctl dump-flows br-int
11690
11691 # Send IP packets between all pairs of source and destination ports,
11692 # packets matches ACL (pg2 to pg1) should be dropped
11693 ip_to_hex() {
11694 printf "%02x%02x%02x%02x" "$@"
11695 }
11696 for is in 1 2 3; do
11697 for js in 1 2 3; do
11698 for ks in 1 2 3; do
11699 bcast=
11700 s=$is$js$ks
11701 smac=f00000000$s
11702 sip=`ip_to_hex 192 168 $is$js $ks`
11703 for id in 1 2 3; do
11704 for jd in 1 2 3; do
11705 for kd in 1 2 3; do
11706 d=$id$jd$kd
11707 dip=`ip_to_hex 192 168 $id$jd $kd`
11708 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
11709 if test $d != $s; then unicast=$d; else unicast=; fi
11710
11711 # packets matches ACL should be dropped
11712 if test $id != 3 && test $kd == 1; then
11713 if test $is != 1 && test $ks == 2; then
11714 unicast=
11715 fi
11716 fi
11717 test_ip $s $smac $dmac $sip $dip $unicast #1
11718 done
11719 done
11720 done
11721 done
11722 done
11723 done
11724
11725 # Allow some time for packet forwarding.
11726 # XXX This can be improved.
11727 sleep 1
11728
11729 # Now check the packets actually received against the ones expected.
11730 for i in 1 2 3; do
11731 for j in 1 2 3; do
11732 for k in 1 2 3; do
11733 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11734 [$i$j$k.expected])
11735 done
11736 done
11737 done
11738
11739 # Gracefully terminate daemons
11740 OVN_CLEANUP([hv1], [hv2], [hv3])
11741 AT_CLEANUP
11742
11743 AT_SETUP([ovn -- ACLs on Port Groups])
11744 AT_KEYWORDS([ovnpg_acl])
11745 AT_SKIP_IF([test $HAVE_PYTHON = no])
11746 ovn_start
11747
11748 # Logical network:
11749 #
11750 # Three logical switches ls1, ls2, ls3.
11751 # One logical router lr0 connected to ls[123],
11752 # with nine subnets, three per logical switch:
11753 #
11754 # lrp11 on ls1 for subnet 192.168.11.0/24
11755 # lrp12 on ls1 for subnet 192.168.12.0/24
11756 # lrp13 on ls1 for subnet 192.168.13.0/24
11757 # ...
11758 # lrp33 on ls3 for subnet 192.168.33.0/24
11759 #
11760 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
11761 # digits are the subnet and the last digit distinguishes the VIF.
11762 #
11763 # This test will create two port groups and ACLs will be applied on them.
11764
11765 get_lsp_uuid () {
11766 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
11767 }
11768
11769 pg1_ports=
11770 pg2_ports=
11771 for i in 1 2 3; do
11772 ovn-nbctl ls-add ls$i
11773 for j in 1 2 3; do
11774 for k in 1 2 3; do
11775 ovn-nbctl \
11776 -- lsp-add ls$i lp$i$j$k \
11777 -- lsp-set-addresses lp$i$j$k \
11778 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
11779 # logical ports lp[12]?1 belongs to port group pg1
11780 if test $i != 3 && test $k == 1; then
11781 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
11782 fi
11783 # logical ports lp[23]?2 belongs to port group pg2
11784 if test $i != 1 && test $k == 2; then
11785 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
11786 fi
11787 done
11788 done
11789 done
11790
11791 ovn-nbctl lr-add lr0
11792 for i in 1 2 3; do
11793 for j in 1 2 3; do
11794 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
11795 ovn-nbctl \
11796 -- lsp-add ls$i lrp$i$j-attachment \
11797 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
11798 options:router-port=lrp$i$j \
11799 addresses='"00:00:00:00:ff:'$i$j'"'
11800 done
11801 done
11802
11803 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
11804 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
11805
11806 # create ACLs on pg1 to drop traffic from pg2 to pg1
11807 ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
11808 ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
11809 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
11810
11811 # Physical network:
11812 #
11813 # Three hypervisors hv[123].
11814 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
11815 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
11816 # lp?3[123] all on hv3.
11817
11818 # Given the name of a logical port, prints the name of the hypervisor
11819 # on which it is located.
11820 vif_to_hv() {
11821 case $1 in dnl (
11822 ?11) echo 1 ;; dnl (
11823 ?12 | ?21 | ?22) echo 2 ;; dnl (
11824 ?13 | ?23 | ?3?) echo 3 ;;
11825 esac
11826 }
11827
11828 # Given the name of a logical port, prints the name of its logical router
11829 # port, e.g. "vif_to_lrp 123" yields 12.
11830 vif_to_lrp() {
11831 echo ${1%?}
11832 }
11833
11834 # Given the name of a logical port, prints the name of its logical
11835 # switch, e.g. "vif_to_ls 123" yields 1.
11836 vif_to_ls() {
11837 echo ${1%??}
11838 }
11839
11840 net_add n1
11841 for i in 1 2 3; do
11842 sim_add hv$i
11843 as hv$i
11844 ovs-vsctl add-br br-phys
11845 ovn_attach n1 br-phys 192.168.0.$i
11846 done
11847 for i in 1 2 3; do
11848 for j in 1 2 3; do
11849 for k in 1 2 3; do
11850 hv=`vif_to_hv $i$j$k`
11851 as hv$hv ovs-vsctl \
11852 -- add-port br-int vif$i$j$k \
11853 -- set Interface vif$i$j$k \
11854 external-ids:iface-id=lp$i$j$k \
11855 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
11856 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
11857 ofport-request=$i$j$k
11858 done
11859 done
11860 done
11861
11862 # Pre-populate the hypervisors' ARP tables so that we don't lose any
11863 # packets for ARP resolution (native tunneling doesn't queue packets
11864 # for ARP resolution).
11865 OVN_POPULATE_ARP
11866
11867 # Allow some time for ovn-northd and ovn-controller to catch up.
11868 # XXX This should be more systematic.
11869 sleep 1
11870
11871 lsp_to_mac() {
11872 echo f0:00:00:00:0${1:0:1}:${1:1:2}
11873 }
11874
11875 lrp_to_mac() {
11876 echo 00:00:00:00:ff:$1
11877 }
11878
11879 # test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
11880 #
11881 # This shell function causes a ICMP packet to be received on INPORT.
11882 # The OUTPORTs (zero or more) list the VIFs on which the packet should
11883 # be received. INPORT and the OUTPORTs are specified as logical switch
11884 # port numbers, e.g. 123 for vif123.
11885 for i in 1 2 3; do
11886 for j in 1 2 3; do
11887 for k in 1 2 3; do
11888 : > $i$j$k.expected
11889 done
11890 done
11891 done
11892
11893 test_icmp() {
11894 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
11895 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
11896 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
11897 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
11898 icmp4.code==0"
11899 shift; shift; shift; shift; shift; shift
11900 hv=hv`vif_to_hv $inport`
11901 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
11902 in_ls=`vif_to_ls $inport`
11903 in_lrp=`vif_to_lrp $inport`
11904 for outport; do
11905 out_ls=`vif_to_ls $outport`
11906 if test $in_ls = $out_ls; then
11907 # Ports on the same logical switch receive exactly the same packet.
11908 echo $packet | ovstest test-ovn expr-to-packets
11909 else
11910 # Routing decrements TTL and updates source and dest MAC
11911 # (and checksum).
11912 out_lrp=`vif_to_lrp $outport`
11913 exp_smac=`lrp_to_mac $out_lrp`
11914 exp_dmac=`lsp_to_mac $outport`
11915 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
11916 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
11917 icmp4.type==$icmp_type && icmp4.code==0"
11918 echo $exp_packet | ovstest test-ovn expr-to-packets
11919
11920 fi >> $outport.expected
11921 done
11922 }
11923
11924 as hv1 ovs-vsctl --columns=name,ofport list interface
11925 as hv1 ovn-sbctl list port_binding
11926 as hv1 ovn-sbctl list datapath_binding
11927 as hv1 ovn-sbctl list port_group
11928 as hv1 ovn-sbctl list address_set
11929 as hv1 ovn-sbctl dump-flows
11930 as hv1 ovs-ofctl dump-flows br-int
11931
11932 # Send IP packets between all pairs of source and destination ports,
11933 # packets matches ACL1 but not ACL2 should be dropped
11934 ip_to_hex() {
11935 printf "%02x%02x%02x%02x" "$@"
11936 }
11937 for is in 1 2 3; do
11938 for js in 1 2 3; do
11939 for ks in 1 2 3; do
11940 bcast=
11941 s=$is$js$ks
11942 slsp_mac=`lsp_to_mac $s`
11943 slrp_mac=`lrp_to_mac $is$js`
11944 sip=192.168.$is$js.$ks
11945 for id in 1 2 3; do
11946 for jd in 1 2 3; do
11947 for kd in 1 2 3; do
11948 d=$id$jd$kd
11949 dlsp_mac=`lsp_to_mac $d`
11950 dlrp_mac=`lrp_to_mac $id$jd`
11951 dip=192.168.$id$jd.$kd
11952 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
11953 if test $d != $s; then unicast=$d; else unicast=; fi
11954
11955 # packets matches ACL1 but not ACL2 should be dropped
11956 if test $id != 3 && test $kd == 1; then
11957 if test $is == 1 || test $ks != 2; then
11958 unicast=
11959 fi
11960 fi
11961 # icmp request (type = 8)
11962 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
11963
11964 # if packets are not dropped, test the return traffic (icmp echo)
11965 # to make sure stateful works, too.
11966 if test x$unicast != x; then
11967 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
11968 # icmp echo (type = 0)
11969 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
11970 fi
11971 done
11972 done
11973 done
11974 done
11975 done
11976 done
11977
11978 # Allow some time for packet forwarding.
11979 # XXX This can be improved.
11980 sleep 1
11981
11982 # Now check the packets actually received against the ones expected.
11983 for i in 1 2 3; do
11984 for j in 1 2 3; do
11985 for k in 1 2 3; do
11986 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11987 [$i$j$k.expected])
11988 done
11989 done
11990 done
11991
11992 # Gracefully terminate daemons
11993 OVN_CLEANUP([hv1], [hv2], [hv3])
11994 AT_CLEANUP
11995
11996 AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
11997 ovn_start
11998
11999 ovn-nbctl ls-add ls1
12000
12001 ovn-nbctl lsp-add ls1 lp1
12002 ovn-nbctl lsp-add ls1 lp2
12003 ovn-nbctl lsp-add ls1 lp3
12004
12005 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
12006 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
12007 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
12008
12009 ovn-nbctl create Port_Group name=pg1
12010 ovn-nbctl create Port_Group name=pg2
12011
12012 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
12013 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
12014 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
12015 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
12016
12017 ovn-nbctl --wait=sb sync
12018
12019 dnl Check if port group address sets were populated with ports' addresses
12020 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12021 [0], [[["10.0.0.1", "10.0.0.2"]]
12022 ])
12023 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
12024 [0], [[["10.0.0.2", "10.0.0.3"]]
12025 ])
12026 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12027 [0], [[["2001:db8::1", "2001:db8::2"]]
12028 ])
12029 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
12030 [0], [[["2001:db8::2", "2001:db8::3"]]
12031 ])
12032
12033 ovn-nbctl --wait=sb lsp-set-addresses lp1 \
12034 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
12035
12036 dnl Check if updated address got propagated to the port group address sets
12037 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12038 [0], [[["10.0.0.11", "10.0.0.2"]]
12039 ])
12040 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12041 [0], [[["2001:db8::11", "2001:db8::2"]]
12042 ])
12043
12044 AT_CLEANUP
12045
12046 AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
12047 ovn_start
12048
12049 ovn-nbctl ls-add ls1
12050 ovn-nbctl ls-add ls2
12051 ovn-nbctl ls-add ls3
12052
12053 ovn-nbctl set Logical_Switch ls1 \
12054 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
12055 ovn-nbctl set Logical_Switch ls2 \
12056 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
12057 ovn-nbctl set Logical_Switch ls3 \
12058 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
12059
12060 ovn-nbctl lsp-add ls1 lp1
12061 ovn-nbctl lsp-add ls2 lp2
12062 ovn-nbctl lsp-add ls3 lp3
12063
12064 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
12065 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
12066 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
12067
12068 ovn-nbctl create Port_Group name=pg1
12069 ovn-nbctl create Port_Group name=pg2
12070
12071 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
12072 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
12073 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
12074 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
12075
12076 ovn-nbctl --wait=sb sync
12077
12078 dnl Check if port group address sets were populated with ports' addresses
12079 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12080 [0], [[["10.1.0.2", "10.2.0.2"]]
12081 ])
12082 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
12083 [0], [[["10.2.0.2", "10.3.0.2"]]
12084 ])
12085 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12086 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
12087 ])
12088 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
12089 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
12090 ])
12091
12092 ovn-nbctl --wait=sb set Logical_Switch ls1 \
12093 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
12094
12095 dnl Check if updated address got propagated to the port group address sets
12096 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12097 [0], [[["10.11.0.2", "10.2.0.2"]]
12098 ])
12099 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12100 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
12101 ])
12102
12103 AT_CLEANUP
12104
12105 AT_SETUP([ovn -- ACL conjunction])
12106 ovn_start
12107
12108 ovn-nbctl ls-add ls1
12109
12110 ovn-nbctl lsp-add ls1 ls1-lp1 \
12111 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
12112
12113 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
12114
12115 ovn-nbctl lsp-add ls1 ls1-lp2 \
12116 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
12117
12118 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
12119
12120 net_add n1
12121 sim_add hv1
12122
12123 as hv1
12124 ovs-vsctl add-br br-phys
12125 ovn_attach n1 br-phys 192.168.0.1
12126 ovs-vsctl -- add-port br-int hv1-vif1 -- \
12127 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
12128 options:tx_pcap=hv1/vif1-tx.pcap \
12129 options:rxq_pcap=hv1/vif1-rx.pcap \
12130 ofport-request=1
12131
12132 ovs-vsctl -- add-port br-int hv1-vif2 -- \
12133 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
12134 options:tx_pcap=hv1/vif2-tx.pcap \
12135 options:rxq_pcap=hv1/vif2-rx.pcap \
12136 ofport-request=2
12137
12138 ovn-nbctl create Address_Set name=set1 \
12139 addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
12140 ovn-nbctl create Address_Set name=set2 \
12141 addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
12142 ovn-nbctl acl-add ls1 to-lport 1002 \
12143 'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
12144 ovn-nbctl acl-add ls1 to-lport 1001 \
12145 'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
12146
12147 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
12148 #
12149 # This shell function causes an ip packet to be received on INPORT.
12150 # The packet's content has Ethernet destination DST and source SRC
12151 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
12152 # The OUTPORTs (zero or more) list the VIFs on which the packet should
12153 # be received. INPORT and the OUTPORTs are specified as logical switch
12154 # port numbers, e.g. 11 for vif11.
12155 test_ip() {
12156 # This packet has bad checksums but logical L3 routing doesn't check.
12157 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
12158 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
12159 ${dst_ip}0035111100080000
12160 shift; shift; shift; shift; shift
12161 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
12162 for outport; do
12163 echo $packet >> $outport.expected
12164 done
12165 }
12166
12167 ip_to_hex() {
12168 printf "%02x%02x%02x%02x" "$@"
12169 }
12170
12171 reset_pcap_file() {
12172 local iface=$1
12173 local pcap_file=$2
12174 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
12175 options:rxq_pcap=dummy-rx.pcap
12176 rm -f ${pcap_file}*.pcap
12177 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
12178 options:rxq_pcap=${pcap_file}-rx.pcap
12179 }
12180
12181
12182 sip=`ip_to_hex 10 0 0 4`
12183 dip=`ip_to_hex 10 0 0 6`
12184
12185 test_ip 1 f00000000001 f00000000002 $sip $dip 2
12186
12187 cat 2.expected > expout
12188 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
12189 AT_CHECK([cat 2.packets], [0], [expout])
12190
12191 # There should be total of 12 flows present with conjunction action and 2 flows
12192 # with conj match. Eg.
12193 # table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
12194 # table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
12195 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
12196 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
12197 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
12198 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
12199 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
12200 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
12201 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
12202 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
12203 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
12204 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
12205 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
12206 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
12207
12208 OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
12209 grep conjunction | wc -l`])
12210 OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
12211 grep conj_id | wc -l`])
12212
12213 as hv1 ovs-ofctl dump-flows br-int
12214
12215 # Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
12216 ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
12217 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
12218
12219 reset_pcap_file hv1-vif2 hv1/vif2
12220
12221 rm -f 2.packets
12222
12223 sip=`ip_to_hex 10 0 0 4`
12224 dip=`ip_to_hex 10 0 0 7`
12225
12226 test_ip 1 f00000000001 f00000000002 $sip $dip
12227 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
12228 AT_CHECK([cat 2.packets], [0], [])
12229
12230 AT_CLEANUP
12231
12232 AT_SETUP([ovn -- TTL exceeded])
12233 AT_KEYWORDS([ttl-exceeded])
12234 AT_SKIP_IF([test $HAVE_PYTHON = no])
12235 ovn_start
12236
12237 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
12238 #
12239 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
12240 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
12241 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
12242 # generated by OVN logical router
12243 #
12244 # INPORT is a lport number, e.g. 11 for vif11.
12245 # HV is a hypervisor number
12246 # ETH_SRC and ETH_DST are each 12 hex digits.
12247 # IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
12248 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
12249 test_ip_packet() {
12250 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
12251 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
12252 shift 10
12253
12254 local ip_ttl=01
12255 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
12256
12257 local reply_icmp_ttl=fe
12258 local icmp_type_code_response=0b00
12259 local icmp_data=00000000
12260 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
12261 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
12262 echo $reply >> vif$inport.expected
12263
12264 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12265 }
12266
12267 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
12268 #
12269 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
12270 # packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
12271 # IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
12272 # packet sent by OVN logical router
12273 test_ip6_packet() {
12274 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
12275 shift 8
12276
12277 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
12278 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
12279
12280 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
12281 echo $reply >> vif$inport.expected
12282
12283 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12284 }
12285
12286 ip_to_hex() {
12287 printf "%02x%02x%02x%02x" "$@"
12288 }
12289
12290 for i in 1 2; do
12291 net_add n$i
12292 ovn-nbctl ls-add sw$i
12293
12294 sim_add hv$i
12295 as hv$i
12296 ovs-vsctl add-br br-phys
12297 ovn_attach n$i br-phys 192.168.$i.1
12298
12299 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
12300 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
12301
12302 ovs-vsctl -- add-port br-int vif$i -- \
12303 set interface vif$i \
12304 external-ids:iface-id=sw$i-p${i}0 \
12305 options:tx_pcap=hv$i/vif$i-tx.pcap \
12306 options:rxq_pcap=hv$i/vif$i-rx.pcap \
12307 ofport-request=$i
12308 done
12309
12310 ovn-nbctl lr-add lr0
12311 for i in 1 2; do
12312 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
12313 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
12314 -- set Logical_Switch_Port lrp$i-attachment type=router \
12315 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
12316 done
12317
12318 OVN_POPULATE_ARP
12319 # allow some time for ovn-northd and ovn-controller to catch up.
12320 ovn-nbctl --wait=hv sync
12321
12322 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
12323 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
12324 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
12325
12326 OVN_CLEANUP([hv1], [hv2])
12327 AT_CLEANUP
12328
12329 AT_SETUP([ovn -- router port unreachable])
12330 AT_KEYWORDS([router-port-unreachable])
12331 AT_SKIP_IF([test $HAVE_PYTHON = no])
12332 ovn_start
12333
12334 # 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
12335 #
12336 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
12337 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
12338 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
12339 # EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
12340 #
12341 # INPORT is a lport number, e.g. 11 for vif11.
12342 # HV is a hypervisor number
12343 # ETH_SRC and ETH_DST are each 12 hex digits.
12344 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
12345 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
12346 test_ip_packet() {
12347 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
12348 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
12349 shift 11
12350
12351 local ip_ttl=ff
12352 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
12353
12354 local reply_icmp_ttl=fe
12355 local icmp_data=00000000
12356 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
12357 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
12358 echo $reply >> vif$inport.expected
12359
12360 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12361 }
12362
12363 # 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
12364 #
12365 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
12366 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
12367 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
12368 #
12369 # INPORT is an lport number, e.g. 11 for vif11.
12370 # HV is an hypervisor number
12371 # ETH_SRC and ETH_DST are each 12 hex digits.
12372 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
12373 # TCP_SPORT and TCP_DPORT are 4 hex digits.
12374 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
12375 test_tcp_syn_packet() {
12376 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
12377 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
12378 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
12379 shift 12
12380
12381 local ip_ttl=ff
12382 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
12383
12384 local tcp_rst_ttl=fe
12385 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
12386 echo $reply >> vif$inport.expected
12387
12388 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12389 }
12390
12391 # test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
12392 #
12393 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
12394 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
12395 # EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
12396 test_tcp6_packet() {
12397 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
12398 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
12399 local exp_tcp_rst_chksum=${10}
12400 shift 10
12401
12402 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
12403 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
12404
12405 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
12406 echo $reply >> vif$inport.expected
12407
12408 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12409 }
12410
12411 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
12412 #
12413 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
12414 # packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
12415 # EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
12416 test_ip6_packet() {
12417 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
12418 local exp_icmp_code=${10} exp_icmp_chksum=${11}
12419 shift 11
12420
12421 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
12422 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
12423
12424 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
12425 echo $reply >> vif$inport.expected
12426
12427 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12428 }
12429
12430 ip_to_hex() {
12431 printf "%02x%02x%02x%02x" "$@"
12432 }
12433
12434 for i in 1 2; do
12435 net_add n$i
12436 ovn-nbctl ls-add sw$i
12437
12438 sim_add hv$i
12439 as hv$i
12440 ovs-vsctl add-br br-phys
12441 ovn_attach n$i br-phys 192.168.$i.1
12442
12443 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
12444 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
12445
12446 ovs-vsctl -- add-port br-int vif$i -- \
12447 set interface vif$i \
12448 external-ids:iface-id=sw$i-p${i}0 \
12449 options:tx_pcap=hv$i/vif$i-tx.pcap \
12450 options:rxq_pcap=hv$i/vif$i-rx.pcap \
12451 ofport-request=$i
12452 done
12453
12454 ovn-nbctl lr-add lr0
12455 for i in 1 2; do
12456 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
12457 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
12458 -- set Logical_Switch_Port lrp$i-attachment type=router \
12459 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
12460 done
12461
12462 OVN_POPULATE_ARP
12463 # allow some time for ovn-northd and ovn-controller to catch up.
12464 ovn-nbctl --wait=hv sync
12465
12466 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
12467 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
12468 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
12469 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
12470
12471 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
12472 test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
12473 test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
12474 OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
12475
12476 OVN_CLEANUP([hv1], [hv2])
12477 AT_CLEANUP
12478
12479 AT_SETUP([ovn -- ovn-controller exit])
12480 AT_SKIP_IF([test $HAVE_PYTHON = no])
12481 ovn_start
12482 # Logical network:
12483 # One Logical Router: ro, with two logical switches sw1 and sw2.
12484 # sw1 is for subnet 10.0.0.0/8
12485 # sw2 is for subnet 20.0.0.0/8
12486 # sw1 has a single port bound on hv1
12487 # sw2 has a single port bound on hv2
12488
12489 ovn-nbctl lr-add ro
12490 ovn-nbctl ls-add sw1
12491 ovn-nbctl ls-add sw2
12492
12493 sw1_ro_mac=00:00:10:00:00:01
12494 sw1_ro_ip=10.0.0.1
12495 sw2_ro_mac=00:00:20:00:00:01
12496 sw2_ro_ip=20.0.0.1
12497 sw1_p1_mac=00:00:10:00:00:02
12498 sw1_p1_ip=10.0.0.2
12499 sw2_p1_mac=00:00:20:00:00:02
12500 sw2_p1_ip=20.0.0.2
12501
12502 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
12503 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
12504 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
12505 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
12506 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
12507 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
12508
12509 ovn-nbctl lsp-add sw1 sw1-p1 \
12510 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
12511
12512 ovn-nbctl lsp-add sw2 sw2-p1 \
12513 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
12514
12515 net_add n1
12516
12517 sim_add hv1
12518 as hv1
12519 ovs-vsctl add-br br-phys
12520 ovn_attach n1 br-phys 192.168.0.1
12521 ovs-vsctl -- add-port br-int hv1-vif1 -- \
12522 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
12523 options:tx_pcap=hv1/vif1-tx.pcap \
12524 options:rxq_pcap=hv1/vif1-rx.pcap \
12525 ofport-request=1
12526
12527 sim_add hv2
12528 as hv2
12529 ovs-vsctl add-br br-phys
12530 ovn_attach n1 br-phys 192.168.0.2
12531 ovs-vsctl -- add-port br-int hv2-vif1 -- \
12532 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
12533 options:tx_pcap=hv2/vif1-tx.pcap \
12534 options:rxq_pcap=hv2/vif1-rx.pcap \
12535 ofport-request=1
12536
12537 OVN_POPULATE_ARP
12538
12539 sleep 1
12540
12541 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
12542 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
12543 udp && udp.src==53 && udp.dst==4369"
12544
12545 # Start by Sending the packet and make sure it makes it there as expected
12546 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
12547
12548 # Expected packet has TTL decreased by 1
12549 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
12550 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
12551 udp && udp.src==53 && udp.dst==4369"
12552 echo $expected | ovstest test-ovn expr-to-packets > expected
12553
12554 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
12555
12556 # Stop ovn-controller on hv2
12557 as hv2 ovs-appctl -t ovn-controller exit
12558
12559 # Now send the packet again. This time, it should not arrive.
12560 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
12561
12562 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
12563
12564 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
12565 as hv2 start_daemon ovn-controller
12566
12567 OVN_CLEANUP([hv1],[hv2])
12568 AT_CLEANUP
12569
12570 AT_SETUP([ovn -- external logical port])
12571 AT_SKIP_IF([test $HAVE_PYTHON = no])
12572 ovn_start
12573
12574 net_add n1
12575 sim_add hv1
12576 sim_add hv2
12577 sim_add hv3
12578
12579 ovn-nbctl ls-add ls1
12580 ovn-nbctl lsp-add ls1 ls1-lp1 \
12581 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
12582
12583 # Add a couple of external logical port
12584 ovn-nbctl lsp-add ls1 ls1-lp_ext1 \
12585 -- lsp-set-addresses ls1-lp_ext1 "f0:00:00:00:00:03 10.0.0.6 ae70::6"
12586 ovn-nbctl lsp-set-port-security ls1-lp_ext1 \
12587 "f0:00:00:00:00:03 10.0.0.6 ae70::6"
12588 ovn-nbctl lsp-set-type ls1-lp_ext1 external
12589
12590 ovn-nbctl lsp-add ls1 ls1-lp_ext2 \
12591 -- lsp-set-addresses ls1-lp_ext2 "f0:00:00:00:00:04 10.0.0.7 ae70::7"
12592 ovn-nbctl lsp-set-port-security ls1-lp_ext2 \
12593 "f0:00:00:00:00:04 10.0.0.7 ae70::8"
12594 ovn-nbctl lsp-set-type ls1-lp_ext2 external
12595
12596 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
12597 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
12598 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
12599
12600 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
12601 options="\"server_id\"=\"00:00:00:10:00:01\"")"
12602
12603 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
12604 ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext1 ${d1}
12605 ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext2 ${d1}
12606
12607 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d2}
12608 ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext1 ${d2}
12609 ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext2 ${d2}
12610
12611 # Create a logical router and connect it to ls1
12612 ovn-nbctl lr-add lr0
12613 ovn-nbctl lrp-add lr0 lr0-ls1 a0:10:00:00:00:01 10.0.0.1/24
12614 ovn-nbctl lsp-add ls1 ls1-lr0
12615 ovn-nbctl set Logical_Switch_Port ls1-lr0 type=router \
12616 options:router-port=lr0-ls1 addresses=router
12617
12618 # Create HA chassis group
12619 ovn-nbctl ha-chassis-group-add hagrp1
12620 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
12621
12622 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name="hagrp1"`
12623
12624 # There should be 1 HA_Chassis rows with chassis sets
12625 OVS_WAIT_UNTIL([ovn-sbctl list ha_chassis | grep chassis | awk '{print $3}' \
12626 | grep '-' | wc -l ], [0], [1
12627 ])
12628
12629 as hv1
12630 ovs-vsctl add-br br-phys
12631 ovn_attach n1 br-phys 192.168.0.1
12632 ovs-vsctl -- add-port br-phys hv1-ext1 -- \
12633 set interface hv1-ext1 options:tx_pcap=hv1/ext1-tx.pcap \
12634 options:rxq_pcap=hv1/ext1-rx.pcap \
12635 ofport-request=2
12636 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12637
12638 as hv2
12639 ovs-vsctl add-br br-phys
12640 ovn_attach n1 br-phys 192.168.0.2
12641 ovs-vsctl -- add-port br-phys hv2-ext2 -- \
12642 set interface hv2-ext2 options:tx_pcap=hv2/ext2-tx.pcap \
12643 options:rxq_pcap=hv2/ext2-rx.pcap \
12644 ofport-request=2
12645 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12646
12647 as hv3
12648 ovs-vsctl add-br br-phys
12649 ovn_attach n1 br-phys 192.168.0.3
12650 ovs-vsctl -- add-port br-phys hv3-ext3 -- \
12651 set interface hv3-ext3 options:tx_pcap=hv3/ext3-tx.pcap \
12652 options:rxq_pcap=hv3/ext3-rx.pcap \
12653 ofport-request=2
12654 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12655
12656 # No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and
12657 # hv2 as ha-chassis-group is not set and no localnet port added to ls1.
12658 AT_CHECK([ovn-sbctl dump-flows ls1 | grep "offerip = 10.0.0.6" | \
12659 wc -l], [0], [0
12660 ])
12661 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12662 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12663 ])
12664 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12665 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12666 ])
12667 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12668 grep controller | grep tp_src=546 | grep \
12669 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12670 ])
12671 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12672 grep controller | grep tp_src=546 | grep \
12673 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12674 ])
12675
12676 hv1_uuid=$(ovn-sbctl list chassis hv1 | grep uuid | awk '{print $3}')
12677 hv2_uuid=$(ovn-sbctl list chassis hv2 | grep uuid | awk '{print $3}')
12678 hv3_uuid=$(ovn-sbctl list chassis hv3 | grep uuid | awk '{print $3}')
12679
12680 # The port_binding row for ls1-lp_ext1 should have empty chassis
12681 chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12682 logical_port=ls1-lp_ext1`
12683
12684 AT_CHECK([test x$chassis == x], [0], [])
12685
12686 # Associate hagrp1 ha-chassis-group to ls1-lp_ext1
12687 ovn-nbctl --wait=hv set Logical_Switch_Port ls1-lp_ext1 \
12688 ha-chassis-group=$hagrp1_uuid
12689
12690 # Get the hagrp1 uuid in SB DB.
12691 sb_hagrp1_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group \
12692 name="hagrp1"`
12693
12694 # Wait till ls1-lp_ext1 port_binding has ha_chassis_group set
12695 OVS_WAIT_UNTIL(
12696 [sb_pb_hagrp=`ovn-sbctl --bare --columns ha_chassis_group find \
12697 port_binding logical_port=ls1-lp_ext1`
12698 test "$sb_pb_hagrp" = "$sb_hagrp1_uuid"])
12699
12700 # No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and hv2
12701 # as no localnet port added to ls1 yet.
12702 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12703 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12704 ])
12705 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12706 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12707 ])
12708 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12709 grep controller | grep tp_src=546 | grep \
12710 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12711 ])
12712 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12713 grep controller | grep tp_src=546 | grep \
12714 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12715 ])
12716
12717 # Add the localnet port to the logical switch ls1
12718 ovn-nbctl lsp-add ls1 ln-public
12719 ovn-nbctl lsp-set-addresses ln-public unknown
12720 ovn-nbctl lsp-set-type ln-public localnet
12721 ovn-nbctl --wait=hv lsp-set-options ln-public network_name=phys
12722
12723 ln_public_key=$(ovn-sbctl list port_binding ln-public | grep tunnel_key | \
12724 awk '{print $3}')
12725
12726 # The ls1-lp_ext1 should be bound to hv1 as only hv1 is part of the
12727 # ha chassis group.
12728 OVS_WAIT_UNTIL(
12729 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12730 logical_port=ls1-lp_ext1`
12731 test "$chassis" = "$hv1_uuid"])
12732
12733 # There should be DHCPv4/v6 OF flows for the ls1-lp_ext1 port in hv1
12734 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12735 grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
12736 wc -l], [0], [3
12737 ])
12738 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12739 grep controller | grep tp_src=546 | grep \
12740 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
12741 grep reg14=0x$ln_public_key | wc -l], [0], [1
12742 ])
12743
12744 # There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv2
12745 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12746 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12747 ])
12748 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12749 grep controller | grep tp_src=546 | grep \
12750 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12751 ])
12752
12753 # No DHCPv4/v6 flows for the external port - ls1-lp_ext2 - 10.0.0.7 in hv1 and
12754 # hv2 as requested-chassis option is not set.
12755 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12756 grep controller | grep "0a.00.00.07" | wc -l], [0], [0
12757 ])
12758 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12759 grep controller | grep "0a.00.00.07" | wc -l], [0], [0
12760 ])
12761 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12762 grep controller | grep tp_src=546 | grep \
12763 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
12764 ])
12765 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12766 grep controller | grep tp_src=546 | grep \
12767 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
12768 ])
12769
12770 as hv1
12771 ovs-vsctl show
12772
12773 # This shell function sends a DHCP request packet
12774 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
12775 test_dhcp() {
12776 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
12777 shift; shift; shift; shift; shift;
12778 if test $use_ip != 0; then
12779 src_ip=$1
12780 dst_ip=$2
12781 shift; shift;
12782 else
12783 src_ip=`ip_to_hex 0 0 0 0`
12784 dst_ip=`ip_to_hex 255 255 255 255`
12785 fi
12786 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
12787 # udp header and dhcp header
12788 request=${request}0044004300fc0000
12789 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
12790 # client hardware padding
12791 request=${request}00000000000000000000
12792 # server hostname
12793 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12794 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12795 # boot file name
12796 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12797 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12798 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12799 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12800 # dhcp magic cookie
12801 request=${request}63825363
12802 # dhcp message type
12803 request=${request}3501${dhcp_type}ff
12804
12805 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
12806 # total IP length will be the IP length of the request packet
12807 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
12808 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
12809 udp_len=`expr $ip_len - 20`
12810 ip_len=$(printf "%x" $ip_len)
12811 udp_len=$(printf "%x" $udp_len)
12812 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
12813 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
12814 # udp header and dhcp header.
12815 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
12816 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
12817 # your ip address
12818 reply=${reply}${offer_ip}
12819 # next server ip address, relay agent ip address, client mac address
12820 reply=${reply}0000000000000000${src_mac}
12821 # client hardware padding
12822 reply=${reply}00000000000000000000
12823 # server hostname
12824 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12825 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12826 # boot file name
12827 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12828 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12829 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12830 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12831 # dhcp magic cookie
12832 reply=${reply}63825363
12833 # dhcp message type
12834 local dhcp_reply_type=02
12835 if test $dhcp_type = 03; then
12836 dhcp_reply_type=05
12837 fi
12838 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
12839 echo $reply >> ext1_v4.expected
12840
12841 as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
12842 }
12843
12844
12845 trim_zeros() {
12846 sed 's/\(00\)\{1,\}$//'
12847 }
12848
12849 # This shell function sends a DHCPv6 request packet
12850 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
12851 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
12852 # packet should be received twice (one from ovn-controller and the other
12853 # from the "ovs-ofctl monitor br-int resume"
12854 test_dhcpv6() {
12855 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
12856 local req_pkt_in_expected=$6
12857 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
12858 # dst ip ff02::1:2
12859 request=${request}ff020000000000000000000000010002
12860 # udp header and dhcpv6 header
12861 request=${request}02220223002affff${msg_code}010203
12862 # Client identifier
12863 request=${request}0001000a00030001${src_mac}
12864 # IA-NA (Identity Association for Non Temporary Address)
12865 request=${request}0003000c0102030400000e1000001518
12866 shift; shift; shift; shift; shift;
12867
12868 local server_mac=000000100001
12869 local server_lla=fe80000000000000020000fffe100001
12870 local reply_code=07
12871 if test $msg_code = 01; then
12872 reply_code=02
12873 fi
12874 local msg_len=54
12875 if test $offer_ip = 1; then
12876 msg_len=28
12877 fi
12878 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101
12879 reply=${reply}${server_lla}${src_lla}
12880
12881 # udp header and dhcpv6 header
12882 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
12883 # Client identifier
12884 reply=${reply}0001000a00030001${src_mac}
12885 # IA-NA
12886 if test $offer_ip != 1; then
12887 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}
12888 reply=${reply}ffffffffffffffff
12889 fi
12890 # Server identifier
12891 reply=${reply}0002000a00030001${server_mac}
12892
12893 echo $reply | trim_zeros >> ext${inport}_v6.expected
12894 # The inport also receives the request packet since it is connected
12895 # to the br-phys.
12896 #echo $request >> ext${inport}_v6.expected
12897
12898 as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
12899 }
12900
12901 reset_pcap_file() {
12902 local iface=$1
12903 local pcap_file=$2
12904 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
12905 options:rxq_pcap=dummy-rx.pcap
12906 rm -f ${pcap_file}*.pcap
12907 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
12908 options:rxq_pcap=${pcap_file}-rx.pcap
12909 }
12910
12911 ip_to_hex() {
12912 printf "%02x%02x%02x%02x" "$@"
12913 }
12914
12915 AT_CAPTURE_FILE([ofctl_monitor0_hv1.log])
12916 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
12917 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv1.log
12918
12919 AT_CAPTURE_FILE([ofctl_monitor0_hv2.log])
12920 as hv2 ovs-ofctl monitor br-int resume --detach --no-chdir \
12921 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv2.log
12922
12923 AT_CAPTURE_FILE([ofctl_monitor0_hv3.log])
12924 as hv3 ovs-ofctl monitor br-int resume --detach --no-chdir \
12925 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv3.log
12926
12927 as hv1
12928 reset_pcap_file hv1-ext1 hv1/ext1
12929
12930 # Send DHCPDISCOVER.
12931 offer_ip=`ip_to_hex 10 0 0 6`
12932 server_ip=`ip_to_hex 10 0 0 1`
12933 server_mac=ff1000000001
12934 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
12935 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
12936 $expected_dhcp_opts
12937
12938 # NXT_RESUMEs should be 1 in hv1.
12939 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12940
12941 # NXT_RESUMEs should be 0 in hv2.
12942 OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12943
12944 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
12945 cat ext1_v4.expected | cut -c -48 > expout
12946 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
12947 # Skipping the IPv4 checksum.
12948 cat ext1_v4.expected | cut -c 53- > expout
12949 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
12950
12951 # ovs-ofctl also resumes the packets and this causes other ports to receive
12952 # the DHCP request packet. So reset the pcap files so that its easier to test.
12953 as hv1
12954 reset_pcap_file hv1-ext1 hv1/ext1
12955
12956 rm -f ext1_v4.expected
12957 rm -f ext1_v4.packets
12958
12959 # Send DHCPv6 request
12960 src_mac=f00000000003
12961 src_lla=fe80000000000000f20000fffe000003
12962 offer_ip=ae700000000000000000000000000006
12963 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
12964
12965 # NXT_RESUMEs should be 2 in hv1.
12966 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12967
12968 # NXT_RESUMEs should be 0 in hv2.
12969 OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12970
12971 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
12972 sort > ext1_v6.packets
12973 cat ext1_v6.expected | cut -c -120 > expout
12974 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
12975 # Skipping the UDP checksum
12976 cat ext1_v6.expected | cut -c 125- > expout
12977 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
12978
12979 rm -f ext1_v6.expected
12980 rm -f ext1_v6.packets
12981
12982 as hv1
12983 reset_pcap_file hv1-ext1 hv1/ext1
12984
12985 # Delete the ha-chassis hv1.
12986 ovn-nbctl ha-chassis-group-remove-chassis hagrp1 hv1
12987 OVS_WAIT_UNTIL(
12988 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12989 logical_port=ls1-lp_ext1`
12990 test "$chassis" = ""])
12991
12992 # Add hv2 to the ha chassis group
12993 ovn-nbctl --wait=hv ha-chassis-group-add-chassis hagrp1 hv2 20
12994
12995 ovn-sbctl list ha_chassis_group
12996 ovn-sbctl list ha_chassis
12997
12998 ovn-sbctl find port_binding logical_port=ls1-lp_ext1
12999
13000 # The ls1-lp_ext1 should be bound to hv2
13001 OVS_WAIT_UNTIL(
13002 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13003 logical_port=ls1-lp_ext1`
13004 test "$chassis" = "$hv2_uuid"])
13005
13006 # There should be OF flows for DHCP4/v6 for the ls1-lp_ext1 port in hv2
13007 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
13008 grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
13009 wc -l], [0], [3
13010 ])
13011 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
13012 grep controller | grep tp_src=546 | grep \
13013 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
13014 grep reg14=0x$ln_public_key | wc -l], [0], [1
13015 ])
13016
13017 # There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv1
13018 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
13019 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
13020 ])
13021 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
13022 grep controller | grep tp_src=546 | grep \
13023 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
13024 grep reg14=0x$ln_public_key | wc -l], [0], [0
13025 ])
13026
13027 # Send DHCPDISCOVER again for hv1/ext1. The DHCP response should come from
13028 # hv2 ovn-controller.
13029 offer_ip=`ip_to_hex 10 0 0 6`
13030 server_ip=`ip_to_hex 10 0 0 1`
13031 server_mac=ff1000000001
13032 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13033 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13034 $expected_dhcp_opts
13035
13036 # NXT_RESUMEs should be 2 in hv1.
13037 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13038
13039 # NXT_RESUMEs should be 1 in hv2.
13040 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13041
13042 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13043 cat ext1_v4.expected | cut -c -48 > expout
13044 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13045 # Skipping the IPv4 checksum.
13046 cat ext1_v4.expected | cut -c 53- > expout
13047 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13048
13049 # ovs-ofctl also resumes the packets and this causes other ports to receive
13050 # the DHCP request packet. So reset the pcap files so that its easier to test.
13051 as hv1
13052 reset_pcap_file hv1-ext1 hv1/ext1
13053
13054 rm -f ext1_v4.expected
13055
13056 # Send DHCPv6 request again
13057 src_mac=f00000000003
13058 src_lla=fe80000000000000f20000fffe000003
13059 offer_ip=ae700000000000000000000000000006
13060 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip 1
13061
13062 # NXT_RESUMEs should be 2 in hv1.
13063 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13064
13065 # NXT_RESUMEs should be 2 in hv2.
13066 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13067
13068 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13069 sort > ext1_v6.packets
13070 cat ext1_v6.expected | cut -c -120 > expout
13071 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13072 # Skipping the UDP checksum
13073 cat ext1_v6.expected | cut -c 125- > expout
13074 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13075
13076 rm -f ext1_v6.expected
13077 rm -f ext1_v6.packets
13078
13079 as hv1
13080 ovs-vsctl show
13081 reset_pcap_file hv1-ext1 hv1/ext1
13082 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13083 reset_pcap_file br-phys hv1/br-phys
13084
13085 as hv2
13086 ovs-vsctl show
13087 reset_pcap_file hv2-ext2 hv2/ext2
13088 reset_pcap_file br-phys_n1 hv2/br-phys_n1
13089 reset_pcap_file br-phys hv2/br-phys
13090
13091 # From ls1-lp_ext1, send ARP request for the router ip. The ARP
13092 # response should come from the router pipeline of hv2.
13093 ext1_mac=f00000000003
13094 router_mac=a01000000001
13095 ext1_ip=`ip_to_hex 10 0 0 6`
13096 router_ip=`ip_to_hex 10 0 0 1`
13097 arp_request=ffffffffffff${ext1_mac}08060001080006040001${ext1_mac}${ext1_ip}000000000000${router_ip}
13098
13099 as hv1 ovs-appctl netdev-dummy/receive hv1-ext1 $arp_request
13100 expected_response=${src_mac}${router_mac}08060001080006040002${router_mac}${router_ip}${ext1_mac}${ext1_ip}
13101 echo $expected_response > expout
13102 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_arp_resp
13103 AT_CHECK([cat ext1_arp_resp], [0], [expout])
13104
13105 # Verify that the response came from hv2
13106 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap > ext1_arp_resp
13107 AT_CHECK([cat ext1_arp_resp], [0], [expout])
13108
13109 # Now add 3 ha chassis to the ha chassis group
13110 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
13111 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv2 20
13112 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 10
13113
13114 # hv1 should be master and claim ls1-lp_ext1
13115 OVS_WAIT_UNTIL(
13116 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13117 logical_port=ls1-lp_ext1`
13118 test "$chassis" = "$hv1_uuid"])
13119
13120 as hv1
13121 ovs-vsctl show
13122 reset_pcap_file hv1-ext1 hv1/ext1
13123 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13124 reset_pcap_file br-phys hv1/br-phys
13125
13126 as hv2
13127 ovs-vsctl show
13128 reset_pcap_file hv2-ext2 hv2/ext2
13129 reset_pcap_file br-phys_n1 hv2/br-phys_n1
13130 reset_pcap_file br-phys hv2/br-phys
13131
13132 as hv3
13133 ovs-vsctl show
13134 reset_pcap_file hv3-ext3 hv3/ext3
13135 reset_pcap_file br-phys_n1 hv3/br-phys_n1
13136 reset_pcap_file br-phys hv3/br-phys
13137
13138 # Send DHCPDISCOVER.
13139 offer_ip=`ip_to_hex 10 0 0 6`
13140 server_ip=`ip_to_hex 10 0 0 1`
13141 server_mac=ff1000000001
13142 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13143 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13144 $expected_dhcp_opts
13145
13146 # NXT_RESUMEs should be 3 in hv1.
13147 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13148
13149 # NXT_RESUMEs should be 2 in hv2.
13150 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13151
13152 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13153 cat ext1_v4.expected | cut -c -48 > expout
13154 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13155 # Skipping the IPv4 checksum.
13156 cat ext1_v4.expected | cut -c 53- > expout
13157 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13158
13159 # ovs-ofctl also resumes the packets and this causes other ports to receive
13160 # the DHCP request packet. So reset the pcap files so that its easier to test.
13161 as hv1
13162 reset_pcap_file hv1-ext1 hv1/ext1
13163
13164 rm -f ext1_v4.expected
13165 rm -f ext1_v4.packets
13166
13167 # Send DHCPv6 request
13168 src_mac=f00000000003
13169 src_lla=fe80000000000000f20000fffe000003
13170 offer_ip=ae700000000000000000000000000006
13171 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
13172
13173 # NXT_RESUMEs should be 4 in hv1.
13174 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13175
13176 # NXT_RESUMEs should be 2 in hv2.
13177 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13178
13179 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13180 sort > ext1_v6.packets
13181 cat ext1_v6.expected | cut -c -120 > expout
13182 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13183 # Skipping the UDP checksum
13184 cat ext1_v6.expected | cut -c 125- > expout
13185 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13186
13187 rm -f ext1_v6.expected
13188 rm -f ext1_v6.packets
13189 as hv1 reset_pcap_file hv1-ext1 hv1/ext1
13190
13191 # Now increase the priority of hv3 so it becomes master.
13192 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 50
13193
13194 # hv3 should be master and claim ls1-lp_ext1
13195 OVS_WAIT_UNTIL(
13196 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13197 logical_port=ls1-lp_ext1`
13198 test "$chassis" = "$hv3_uuid"])
13199
13200 as hv1
13201 ovs-vsctl show
13202 reset_pcap_file hv1-ext1 hv1/ext1
13203 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13204 reset_pcap_file br-phys hv1/br-phys
13205
13206 as hv2
13207 ovs-vsctl show
13208 reset_pcap_file hv2-ext2 hv2/ext2
13209 reset_pcap_file br-phys_n1 hv2/br-phys_n1
13210 reset_pcap_file br-phys hv2/br-phys
13211
13212 as hv2
13213 ovs-vsctl show
13214 reset_pcap_file hv3-ext3 hv3/ext3
13215 reset_pcap_file br-phys_n1 hv3/br-phys_n1
13216 reset_pcap_file br-phys hv3/br-phys
13217
13218 # Send DHCPDISCOVER.
13219 offer_ip=`ip_to_hex 10 0 0 6`
13220 server_ip=`ip_to_hex 10 0 0 1`
13221 server_mac=ff1000000001
13222 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13223 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13224 $expected_dhcp_opts
13225
13226 # NXT_RESUMEs should be 4 in hv1.
13227 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13228
13229 # NXT_RESUMEs should be 2 in hv2.
13230 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13231
13232 # NXT_RESUMEs should be 1 in hv3.
13233 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
13234
13235 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13236 cat ext1_v4.expected | cut -c -48 > expout
13237 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13238 # Skipping the IPv4 checksum.
13239 cat ext1_v4.expected | cut -c 53- > expout
13240 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13241
13242 # ovs-ofctl also resumes the packets and this causes other ports to receive
13243 # the DHCP request packet. So reset the pcap files so that its easier to test.
13244 as hv1
13245 reset_pcap_file hv1-ext1 hv1/ext1
13246
13247 rm -f ext1_v4.expected
13248 rm -f ext1_v4.packets
13249
13250 # Send DHCPv6 request
13251 src_mac=f00000000003
13252 src_lla=fe80000000000000f20000fffe000003
13253 offer_ip=ae700000000000000000000000000006
13254 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
13255
13256 # NXT_RESUMEs should be 4 in hv1.
13257 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13258
13259 # NXT_RESUMEs should be 2 in hv2.
13260 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13261
13262 # NXT_RESUMEs should be 2 in hv3.
13263 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
13264
13265 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13266 sort > ext1_v6.packets
13267 cat ext1_v6.expected | cut -c -120 > expout
13268 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13269 # Skipping the UDP checksum
13270 cat ext1_v6.expected | cut -c 125- > expout
13271 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13272
13273 # disconnect hv3 from the network, hv1 should take over
13274 as hv3
13275 port=${sandbox}_br-phys
13276 as main ovs-vsctl del-port n1 $port
13277
13278 # hv1 should be master and claim ls1-lp_ext1
13279 OVS_WAIT_UNTIL(
13280 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13281 logical_port=ls1-lp_ext1`
13282 test "$chassis" = "$hv1_uuid"])
13283
13284 OVN_CLEANUP([hv1],[hv2],[hv3])
13285 AT_CLEANUP
13286
13287 AT_SETUP([ovn -- Address Set Incremental Processing])
13288 AT_KEYWORDS([ovn_as_inc])
13289 AT_SKIP_IF([test $HAVE_PYTHON = no])
13290 ovn_start
13291
13292 net_add n1
13293 sim_add hv1
13294 as hv1
13295 ovs-vsctl add-br br-phys
13296 ovn_attach n1 br-phys 192.168.0.10
13297
13298 ovn-nbctl ls-add ls1
13299 for i in 1 2; do
13300 ovn-nbctl lsp-add ls1 lp$i \
13301 -- lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.1.$i"
13302 as hv1 ovs-vsctl \
13303 -- add-port br-int vif$i \
13304 -- set Interface vif$i \
13305 external-ids:iface-id=lp$i
13306 done
13307
13308 for i in 1 2 3; do
13309 as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
13310 as2_uuid=`ovn-nbctl --wait=hv create addr name=as2`
13311 ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
13312 'outport=="lp1" && ip4 && ip4.src == {$as1, $as2}' allow-related
13313 ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10"
13314 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [0], [ignore])
13315
13316 # Update address set as1
13317 ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10 10.1.2.11"
13318 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.11"], [0], [ignore])
13319
13320 # Update address set as2
13321 ovn-nbctl --wait=hv set addr as2 addresses="10.1.2.12 10.1.2.13"
13322 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
13323
13324 # Add another ACL referencing as1
13325 n_flows_before=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13326 ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
13327 'outport=="lp2" && ip4 && ip4.src == $as1' allow-related
13328 n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13329 AT_CHECK([test $(expr $n_flows_before \* 2) = $n_flows_after], [0], [ignore])
13330
13331 # Remove an ACL
13332 ovn-nbctl --wait=hv acl-del ls1 to-lport 200 \
13333 'outport=="lp2" && ip4 && ip4.src == $as1'
13334 n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13335 AT_CHECK([test $n_flows_before = $n_flows_after], [0], [ignore])
13336
13337 # Remove as1 while it is still used by an ACL, the lflows should be reparsed and
13338 # parsing should fail.
13339 echo "before del as1"
13340 ovn-nbctl list addr | grep as1
13341 ovn-nbctl --wait=hv destroy addr $as1_uuid
13342 echo "after del as1"
13343 ovn-nbctl list addr | grep as1
13344 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [1], [ignore])
13345 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
13346
13347 # Recreate as1
13348 as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
13349 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
13350
13351 # Remove ACLs and address sets
13352 ovn-nbctl --wait=hv destroy addr $as1_uuid -- destroy addr $as2_uuid
13353 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
13354
13355 ovn-nbctl --wait=hv acl-del ls1
13356 done
13357
13358 # Gracefully terminate daemons
13359 OVN_CLEANUP([hv1])
13360 AT_CLEANUP
13361
13362 AT_SETUP([ovn -- ovn-controller restart])
13363 AT_SKIP_IF([test $HAVE_PYTHON = no])
13364 ovn_start
13365
13366 # Logical network:
13367 # One Logical Router: ro, with two logical switches sw1 and sw2.
13368 # sw1 is for subnet 10.0.0.0/8
13369 # sw2 is for subnet 20.0.0.0/8
13370 # sw1 has a single port bound on hv1
13371 # sw2 has a single port bound on hv2
13372
13373 ovn-nbctl lr-add ro
13374 ovn-nbctl ls-add sw1
13375 ovn-nbctl ls-add sw2
13376
13377 sw1_ro_mac=00:00:10:00:00:01
13378 sw1_ro_ip=10.0.0.1
13379 sw2_ro_mac=00:00:20:00:00:01
13380 sw2_ro_ip=20.0.0.1
13381 sw1_p1_mac=00:00:10:00:00:02
13382 sw1_p1_ip=10.0.0.2
13383 sw2_p1_mac=00:00:20:00:00:02
13384 sw2_p1_ip=20.0.0.2
13385
13386 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
13387 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
13388 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
13389 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
13390 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
13391 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
13392
13393 ovn-nbctl lsp-add sw1 sw1-p1 \
13394 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
13395
13396 ovn-nbctl lsp-add sw2 sw2-p1 \
13397 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
13398
13399 net_add n1
13400
13401 sim_add hv1
13402 as hv1
13403 ovs-vsctl add-br br-phys
13404 ovn_attach n1 br-phys 192.168.0.1
13405 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13406 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
13407 options:tx_pcap=hv1/vif1-tx.pcap \
13408 options:rxq_pcap=hv1/vif1-rx.pcap \
13409 ofport-request=1
13410
13411 sim_add hv2
13412 as hv2
13413 ovs-vsctl add-br br-phys
13414 ovn_attach n1 br-phys 192.168.0.2
13415 ovs-vsctl -- add-port br-int hv2-vif1 -- \
13416 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
13417 options:tx_pcap=hv2/vif1-tx.pcap \
13418 options:rxq_pcap=hv2/vif1-rx.pcap \
13419 ofport-request=1
13420
13421 OVN_POPULATE_ARP
13422
13423 sleep 1
13424
13425 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
13426 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
13427 udp && udp.src==53 && udp.dst==4369"
13428
13429 # Start by Sending the packet and make sure it makes it there as expected
13430 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
13431
13432 # Expected packet has TTL decreased by 1
13433 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
13434 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
13435 udp && udp.src==53 && udp.dst==4369"
13436 echo $expected | ovstest test-ovn expr-to-packets > expected
13437
13438 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13439
13440 # Stop ovn-controller on hv2 with --restart flag
13441 as hv2 ovs-appctl -t ovn-controller exit --restart
13442
13443 # Now send the packet again. This time, it should still arrive
13444 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
13445
13446 cat expected expected > expected2
13447
13448 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
13449
13450 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
13451 as hv2 start_daemon ovn-controller
13452
13453 OVN_CLEANUP([hv1],[hv2])
13454
13455
13456 AT_CLEANUP
13457
13458 AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
13459 ovn_start
13460
13461 # Set up a switch with some switch ports of varying address types
13462 ovn-nbctl ls-add sw1
13463 ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
13464
13465 ovn-nbctl lsp-add sw1 sw1-p1
13466 ovn-nbctl lsp-add sw1 sw1-p2
13467 ovn-nbctl lsp-add sw1 sw1-p3
13468 ovn-nbctl lsp-add sw1 sw1-p4
13469
13470 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"
13471 ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
13472 ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
13473 ovn-nbctl lsp-set-addresses sw1-p4 "router"
13474 ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
13475
13476 ovn-nbctl list logical_switch_port
13477
13478 # Now try to add duplicate addresses on a new port. These should all fail
13479 ovn-nbctl --wait=sb lsp-add sw1 sw1-p5
13480 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
13481 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
13482 ])
13483 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
13484 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
13485 ])
13486 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
13487 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
13488 ])
13489 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
13490 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
13491 ])
13492 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
13493 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
13494 ])
13495 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
13496 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
13497 ])
13498
13499 # Now try re-setting sw1-p1. This should succeed
13500 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
13501
13502 # Now create a new switch and try setting IP addresses the same as the
13503 # first switch. This should succeed.
13504 ovn-nbctl ls-add sw2
13505 ovn-nbctl lsp-add sw2 sw2-p1
13506
13507 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
13508 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
13509 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
13510 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
13511
13512 AT_CLEANUP
13513
13514 AT_SETUP([ovn -- router - check packet length - icmp defrag])
13515 AT_KEYWORDS([check packet length])
13516 AT_SKIP_IF([test $HAVE_PYTHON = no])
13517 ovn_start
13518
13519 ovn-nbctl ls-add sw0
13520 ovn-nbctl lsp-add sw0 sw0-port1
13521 ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:01 10.0.0.3"
13522
13523 ovn-nbctl lr-add lr0
13524 ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
13525 ovn-nbctl lsp-add sw0 sw0-lr0
13526 ovn-nbctl lsp-set-type sw0-lr0 router
13527 ovn-nbctl lsp-set-addresses sw0-lr0 router
13528 ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
13529
13530 ovn-nbctl ls-add public
13531 ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
13532 ovn-nbctl lsp-add public public-lr0
13533 ovn-nbctl lsp-set-type public-lr0 router
13534 ovn-nbctl lsp-set-addresses public-lr0 router
13535 ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
13536
13537 # localnet port
13538 ovn-nbctl lsp-add public ln-public
13539 ovn-nbctl lsp-set-type ln-public localnet
13540 ovn-nbctl lsp-set-addresses ln-public unknown
13541 ovn-nbctl lsp-set-options ln-public network_name=phys
13542
13543 ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
13544 ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
13545
13546 net_add n1
13547
13548 sim_add hv1
13549 as hv1
13550 ovs-vsctl add-br br-phys
13551 ovn_attach n1 br-phys 192.168.0.1
13552 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
13553 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13554 set interface hv1-vif1 external-ids:iface-id=sw0-port1 \
13555 options:tx_pcap=hv1/vif1-tx.pcap \
13556 options:rxq_pcap=hv1/vif1-rx.pcap \
13557 ofport-request=1
13558
13559 reset_pcap_file() {
13560 local iface=$1
13561 local pcap_file=$2
13562 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
13563 options:rxq_pcap=dummy-rx.pcap
13564 rm -f ${pcap_file}*.pcap
13565 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
13566 options:rxq_pcap=${pcap_file}-rx.pcap
13567 }
13568
13569 ip_to_hex() {
13570 printf "%02x%02x%02x%02x" "$@"
13571 }
13572
13573 test_ip_packet_larger() {
13574 local icmp_pmtu_reply_expected=$1
13575
13576 # Send ip packet from sw0-port1 to outside
13577 src_mac="505400000001" # sw-port1 mac
13578 dst_mac="00000000ff01" # sw0-lr0 mac (internal router leg)
13579 src_ip=`ip_to_hex 10 0 0 3`
13580 dst_ip=`ip_to_hex 172 168 0 3`
13581 # Set the packet length to 100.
13582 pkt_len=0064
13583 packet=${dst_mac}${src_mac}08004500${pkt_len}0000000040010000
13584 orig_packet_l3=${src_ip}${dst_ip}0304000000000000
13585 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13586 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13587 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13588 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13589 packet=${packet}${orig_packet_l3}
13590
13591 gw_ip_garp=ffffffffffff00002020121308060001080006040001000020201213aca80064000000000000aca80064
13592
13593 # If icmp_pmtu_reply_expected is 0, it means the packet is lesser than
13594 # the gateway mtu and should be delivered to the provider bridge via the
13595 # localnet port.
13596 # If icmp_pmtu_reply_expected is 1, it means the packet is larger than
13597 # the gateway mtu and ovn-controller should drop the packet and instead
13598 # generate ICMPv4 Destination Unreachable message with pmtu set to 42.
13599 if test $icmp_pmtu_reply_expected = 0; then
13600 # Packet to expect at br-phys.
13601 src_mac="000020201213"
13602 dst_mac="00000012af11"
13603 src_ip=`ip_to_hex 10 0 0 3`
13604 dst_ip=`ip_to_hex 172 168 0 3`
13605 expected=${dst_mac}${src_mac}08004500${pkt_len}000000003f010100
13606 expected=${expected}${src_ip}${dst_ip}0304000000000000
13607 expected=${expected}000000000000000000000000000000000000
13608 expected=${expected}000000000000000000000000000000000000
13609 expected=${expected}000000000000000000000000000000000000
13610 expected=${expected}000000000000000000000000000000000000
13611 echo $expected > br_phys_n1.expected
13612 echo $gw_ip_garp >> br_phys_n1.expected
13613 else
13614 # MTU would be 100 - 18 = 82 (hex 0052)
13615 mtu=0052
13616 src_ip=`ip_to_hex 10 0 0 1`
13617 dst_ip=`ip_to_hex 10 0 0 3`
13618 # pkt len should be 128 (28 (icmp packet) + 100 (orig ip + payload))
13619 reply_pkt_len=0080
13620 ip_csum=bd91
13621 icmp_reply=${src_mac}${dst_mac}08004500${reply_pkt_len}00004000fe016879
13622 icmp_reply=${icmp_reply}${src_ip}${dst_ip}0304${ip_csum}0000${mtu}
13623 icmp_reply=${icmp_reply}4500${pkt_len}000000003f010100
13624 icmp_reply=${icmp_reply}${orig_packet_l3}
13625 echo $icmp_reply > hv1-vif1.expected
13626 fi
13627
13628 as hv1 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13629 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
13630
13631 # Send packet from sw0-port1 to outside
13632 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
13633
13634 if test $icmp_pmtu_reply_expected = 0; then
13635 OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [br_phys_n1.expected])
13636 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > pkts
13637 # hv1/vif1-tx.pcap can receive the GARP packet generated by ovn-controller
13638 # for the gateway router port. So ignore this packet.
13639 cat pkts | grep -v $gw_ip_garp > packets
13640 AT_CHECK([cat packets], [0], [])
13641 else
13642 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [hv1-vif1.expected])
13643 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap > \
13644 pkts
13645 # hv1/br-phys_n1-tx.pcap can receive the GARP packet generated by ovn-controller
13646 # for the gateway router port. So ignore this packet.
13647 cat pkts | grep -v $gw_ip_garp > packets
13648 AT_CHECK([cat packets], [0], [])
13649 fi
13650 }
13651
13652 ovn-nbctl show
13653 ovn-sbctl show
13654
13655 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int \
13656 | grep "check_pkt_larger" | wc -l], [0], [[0
13657 ]])
13658 dp_uuid=$(ovn-sbctl find datapath_binding | grep sw0 -B2 | grep _uuid | \
13659 awk '{print $3}')
13660 ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
13661 logical_port=lr0-public mac="00\:00\:00\:12\:af\:11"
13662
13663 # Set the gateway mtu to 100. If the packet length is > 100, ovn-controller
13664 # should send icmp host not reachable with pmtu set to 100.
13665 ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=100
13666 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
13667 OVS_WAIT_UNTIL([
13668 test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(100)" | \
13669 wc -l` -eq 1
13670 ])
13671
13672 icmp_reply_expected=1
13673 test_ip_packet_larger $icmp_reply_expected
13674
13675 # Set the gateway mtu to 500.
13676 ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=500
13677 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
13678 OVS_WAIT_UNTIL([
13679 test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(500)" | \
13680 wc -l` -eq 1
13681 ])
13682
13683 # Now the packet should be sent via the localnet port to br-phys.
13684 icmp_reply_expected=0
13685 test_ip_packet_larger $icmp_reply_expected
13686 OVN_CLEANUP([hv1])
13687 AT_CLEANUP
13688
13689 AT_SETUP([ovn -- IP packet buffering])
13690 AT_KEYWORDS([ip-buffering])
13691 AT_SKIP_IF([test $HAVE_PYTHON = no])
13692 ovn_start
13693
13694 # Logical network:
13695 # One LR lr0 that has switches sw0 (192.168.1.0/24) and
13696 # sw1 (172.16.1.0/24) connected to it.
13697 #
13698 # Physical network:
13699 # Tw0 hypervisors hv[12].
13700 # hv1 hosts vif sw0-p0.
13701 # hv1 hosts vif sw1-p0.
13702
13703 send_icmp_packet() {
13704 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
13705 shift 8
13706
13707 local ip_ttl=ff
13708 local ip_len=001c
13709 local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
13710 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
13711 }
13712
13713 send_icmp6_packet() {
13714 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
13715 shift 8
13716
13717 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
13718 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
13719
13720 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
13721 }
13722
13723 get_arp_req() {
13724 local eth_src=$1 spa=$2 tpa=$3
13725 local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
13726 echo $request
13727 }
13728
13729 send_arp_reply() {
13730 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
13731 local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
13732 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
13733 }
13734
13735 send_na() {
13736 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
13737 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
13738 local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
13739
13740 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
13741 }
13742
13743 get_nd() {
13744 local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
13745 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
13746 request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
13747
13748 echo $request
13749 }
13750
13751 net_add n1
13752
13753 sim_add hv1
13754 as hv1
13755 ovs-vsctl add-br br-phys
13756 ovn_attach n1 br-phys 192.168.0.1
13757 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13758 set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
13759 options:tx_pcap=hv1/vif1-tx.pcap \
13760 options:rxq_pcap=hv1/vif1-rx.pcap \
13761 ofport-request=1
13762
13763 sim_add hv2
13764 as hv2
13765 ovs-vsctl add-br br-phys
13766 ovn_attach n1 br-phys 192.168.0.2
13767 ovs-vsctl -- add-port br-int hv2-vif1 -- \
13768 set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
13769 options:tx_pcap=hv2/vif1-tx.pcap \
13770 options:rxq_pcap=hv2/vif1-rx.pcap \
13771 ofport-request=1
13772
13773 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
13774 ovn-nbctl ls-add sw0
13775 ovn-nbctl ls-add sw1
13776
13777 ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001:0:0:0:0:0:0:1/64
13778 ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
13779 type=router options:router-port=sw0 \
13780 -- lsp-set-addresses rp-sw0 router
13781
13782 ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002:0:0:0:0:0:0:1/64
13783 ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
13784 type=router options:router-port=sw1 \
13785 -- lsp-set-addresses rp-sw1 router
13786
13787 ovn-nbctl lsp-add sw0 sw0-p0 \
13788 -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
13789
13790 ovn-nbctl lsp-add sw1 sw1-p0 \
13791 -- lsp-set-addresses sw1-p0 unknown
13792
13793 OVN_POPULATE_ARP
13794 ovn-nbctl --wait=hv sync
13795
13796 ip_to_hex() {
13797 printf "%02x%02x%02x%02x" "$@"
13798 }
13799
13800 src_mac=f00000010203
13801 src_ip=$(ip_to_hex 192 168 1 2)
13802 src_ip6=20010000000000000000000000000002
13803
13804 router_mac0=000001010203
13805 router_mac1=000002010203
13806 router_ip=$(ip_to_hex 172 16 1 1)
13807 router_ip6=20020000000000000000000000000001
13808
13809 dst_mac=001122334455
13810 dst_ip=$(ip_to_hex 172 16 1 10)
13811 dst_ip6=20020000000000000000000000000010
13812
13813 data=0800bee4391a0001
13814
13815 send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
13816 send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
13817 echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
13818 echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
13819
13820 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13821
13822 nd_ip=ff0200000000000000000001ff000010
13823 ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
13824
13825 send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
13826 echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
13827 echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
13828 send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
13829
13830 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13831
13832 OVN_CLEANUP([hv1],[hv2])
13833 AT_CLEANUP
13834
13835 AT_SETUP([ovn -- neighbor update on same HV])
13836 AT_SKIP_IF([test $HAVE_PYTHON = no])
13837 ovn_start
13838
13839 # Logical network:
13840 # A public switch (pub) with a localnet port connected to two LRs (lr0 and lr1)
13841 # each with a distributed gateway port.
13842 # Two VMs: lp0 on sw0 connected to lr0
13843 # lp1 on sw1 connected to lr1
13844 #
13845 # This test adds a floating IP to each VM so when they are bound to the same
13846 # hypervisor, it checks that the GARP sent by ovn-controller causes the
13847 # MAC_Binding entries to be updated properly on each logical router.
13848 # It will also capture packets on the physical interface to make sure that the
13849 # GARPs have been sent out to the external network as well.
13850
13851 # Create logical switches
13852 ovn-nbctl ls-add sw0
13853 ovn-nbctl ls-add sw1
13854 ovn-nbctl ls-add pub
13855
13856 # Created localnet port on public switch
13857 ovn-nbctl lsp-add pub ln-pub
13858 ovn-nbctl lsp-set-type ln-pub localnet
13859 ovn-nbctl lsp-set-addresses ln-pub unknown
13860 ovn-nbctl lsp-set-options ln-pub network_name=phys
13861
13862 # Create logical routers and connect them to public switch
13863 ovn-nbctl create Logical_Router name=lr0
13864 ovn-nbctl create Logical_Router name=lr1
13865
13866 ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
13867 ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
13868 type=router options:router-port=lr0-pub options:nat-addresses="router" addresses="router"
13869 ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
13870 ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
13871 type=router options:router-port=lr1-pub options:nat-addresses="router" addresses="router"
13872
13873 ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
13874 ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
13875
13876 # Connect sw0 and sw1 to lr0 and lr1
13877 ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
13878 ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
13879 options:router-port=lr0-sw0 addresses="router"
13880 ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
13881 ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
13882 options:router-port=lr1-sw1 addresses="router"
13883
13884
13885 # Add SNAT rules
13886 ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
13887 ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
13888
13889 net_add n1
13890 sim_add hv1
13891 as hv1
13892 ovs-vsctl add-br br-phys
13893 ovn_attach n1 br-phys 172.24.4.1
13894 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
13895
13896 ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
13897 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
13898
13899 ovn-nbctl lsp-add sw0 lp0
13900 ovn-nbctl lsp-add sw1 lp1
13901 ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
13902 ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
13903
13904 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp0` = xup])
13905 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
13906
13907 # Create two floating IPs, one for each VIF
13908 ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
13909 ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
13910
13911 # Check that the MAC_Binding entries have been properly created
13912 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr0-pub" ip="172.24.4.200" | wc -l` -gt 0])
13913 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr1-pub" ip="172.24.4.100" | wc -l` -gt 0])
13914
13915 # Check that the GARPs went also to the external physical network
13916 # Wait until at least 4 packets have arrived and copy them to a separate file as
13917 # more GARPs are expected in the capture in order to avoid race conditions.
13918 OVS_WAIT_UNTIL([test `$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | wc -l` -gt 4])
13919 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | head -n4 > hv1/br-phys-tx4.pcap
13920
13921 # GARP for lp0 172.24.4.100 on lr0-pub MAC (f0:00:00:00:00:01)
13922 echo "fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464" > expout
13923 # GARP for 172.24.4.220 on lr0-pub (f0:00:00:00:00:01)
13924 echo "fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc" >> expout
13925 # GARP for lp1 172.24.4.200 on lr1-pub MAC (f0:00:00:00:01:01)
13926 echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8" >> expout
13927 # GARP for 172.24.4.221 on lr1-pub (f0:00:00:00:01:01)
13928 echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd" >> expout
13929 AT_CHECK([sort hv1/br-phys-tx4.pcap], [0], [expout])
13930 #OVN_CHECK_PACKETS([hv1/br-phys-tx4.pcap], [br-phys.expected])
13931
13932 OVN_CLEANUP([hv1])
13933 AT_CLEANUP
13934
13935 AT_SETUP([ovn -- ipam to non-ipam])
13936 ovn_start
13937
13938 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
13939 ovn-nbctl ls-add sw0
13940 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
13941 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
13942
13943 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
13944 ["0a:00:00:a8:01:03 192.168.1.2"
13945 ])
13946
13947 ovn-nbctl --wait=sb lsp-set-addresses p0 router
13948
13949 ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses
13950
13951 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0], [[[]]
13952 ])
13953 AT_CLEANUP
13954
13955 AT_SETUP([ovn -- ipam router ports])
13956 ovn_start
13957
13958 ovn-nbctl ls-add sw
13959 ovn-nbctl set logical_switch sw other-config:subnet=192.168.1.0/24
13960
13961 for i in 2 3 4; do
13962 ovn-nbctl lr-add ro$i
13963 ovn-nbctl lsp-add sw swp$i
13964 ovn-nbctl --wait=sb lsp-set-addresses swp$i "02:00:00:00:00:0$i dynamic"
13965 cidr=$(ovn-nbctl get logical_switch_port swp$i dynamic_addresses |cut -f2 -d' '|cut -f1 -d\")
13966 ovn-nbctl lrp-add ro$i rop$i 02:00:00:00:00:0$i $cidr/24 -- set logical_switch_port swp$i type=router options:router-port=rop$i addresses=router;
13967 AT_CHECK_UNQUOTED([ovn-nbctl get logical_router_port rop$i networks], [0], [[["192.168.1.$i/24"]]
13968 ])
13969 done
13970
13971 ovn-nbctl list logical_switch_port
13972 ovn-nbctl list logical_router_port
13973
13974 AT_CLEANUP
13975
13976 AT_SETUP([ovn -- test transport zones])
13977 ovn_start
13978
13979 net_add n1
13980 for i in 1 2 3 4 5; do
13981 sim_add hv$i
13982 as hv$i
13983 ovs-vsctl add-br br-phys
13984 ovn_attach n1 br-phys 192.168.$i.1
13985 done
13986
13987 dnl Wait for the changes to be propagated
13988 ovn-nbctl --wait=sb --timeout=3 sync
13989 ovn-nbctl --wait=hv --timeout=3 sync
13990
13991 dnl Assert that each Chassis has a tunnel formed to every other Chassis
13992 as hv1
13993 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13994 [[ovn-hv2-0
13995 ovn-hv3-0
13996 ovn-hv4-0
13997 ovn-hv5-0
13998 ]])
13999
14000 as hv2
14001 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14002 [[ovn-hv1-0
14003 ovn-hv3-0
14004 ovn-hv4-0
14005 ovn-hv5-0
14006 ]])
14007
14008 as hv3
14009 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14010 [[ovn-hv1-0
14011 ovn-hv2-0
14012 ovn-hv4-0
14013 ovn-hv5-0
14014 ]])
14015
14016 as hv4
14017 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14018 [[ovn-hv1-0
14019 ovn-hv2-0
14020 ovn-hv3-0
14021 ovn-hv5-0
14022 ]])
14023
14024 as hv5
14025 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14026 [[ovn-hv1-0
14027 ovn-hv2-0
14028 ovn-hv3-0
14029 ovn-hv4-0
14030 ]])
14031
14032 dnl Let's now add some Chassis to different transport zones
14033 dnl * hv1: Will be part of two transport zones: tz1 and tz2 so it
14034 dnl should have tunnels formed between the other two Chassis (hv2 and hv3)
14035 dnl
14036 dnl * hv2: Will be part of one transport zone: tz1. It should have a tunnel
14037 dnl to hv1 but not to hv3
14038 dnl
14039 dnl * hv3: Will be part of one transport zone: tz2. It should have a tunnel
14040 dnl to hv1 but not to hv2
14041 dnl
14042 dnl * hv4 and hv5: Will not have any TZ set so they will keep the tunnels
14043 dnl between themselves and remove the tunnels to other Chassis which now
14044 dnl belongs to some TZs
14045 dnl
14046 as hv1
14047 ovs-vsctl set open . external-ids:ovn-transport-zones=tz1,tz2
14048
14049 as hv2
14050 ovs-vsctl set open . external-ids:ovn-transport-zones=tz1
14051
14052 as hv3
14053 ovs-vsctl set open . external-ids:ovn-transport-zones=tz2
14054
14055 dnl Wait for the changes to be propagated
14056 ovn-nbctl --wait=sb --timeout=3 sync
14057 ovn-nbctl --wait=hv --timeout=3 sync
14058
14059 as hv1
14060 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14061 [[ovn-hv2-0
14062 ovn-hv3-0
14063 ]])
14064
14065 as hv2
14066 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14067 [[ovn-hv1-0
14068 ]])
14069
14070 as hv3
14071 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14072 [[ovn-hv1-0
14073 ]])
14074
14075 as hv4
14076 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14077 [[ovn-hv5-0
14078 ]])
14079
14080 as hv5
14081 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14082 [[ovn-hv4-0
14083 ]])
14084
14085 dnl Removing the transport zones should make all Chassis to create
14086 dnl tunnels between every other Chassis again
14087 for i in 1 2 3; do
14088 as hv$i
14089 ovs-vsctl remove open . external-ids ovn-transport-zones
14090 done
14091
14092 dnl Wait for the changes to be propagated
14093 ovn-nbctl --wait=sb --timeout=3 sync
14094 ovn-nbctl --wait=hv --timeout=3 sync
14095
14096 as hv1
14097 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14098 [[ovn-hv2-0
14099 ovn-hv3-0
14100 ovn-hv4-0
14101 ovn-hv5-0
14102 ]])
14103
14104 as hv2
14105 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14106 [[ovn-hv1-0
14107 ovn-hv3-0
14108 ovn-hv4-0
14109 ovn-hv5-0
14110 ]])
14111
14112 as hv3
14113 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14114 [[ovn-hv1-0
14115 ovn-hv2-0
14116 ovn-hv4-0
14117 ovn-hv5-0
14118 ]])
14119
14120 as hv4
14121 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14122 [[ovn-hv1-0
14123 ovn-hv2-0
14124 ovn-hv3-0
14125 ovn-hv5-0
14126 ]])
14127
14128 as hv5
14129 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14130 [[ovn-hv1-0
14131 ovn-hv2-0
14132 ovn-hv3-0
14133 ovn-hv4-0
14134 ]])
14135
14136 OVN_CLEANUP([hv1], [hv2], [hv3])
14137 AT_CLEANUP
14138
14139 AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR chassis mac])
14140 ovn_start
14141
14142
14143 # In this test cases we create 2 switches, all connected to same
14144 # physical network (through br-phys on each HV). Each switch has
14145 # 1 VIF. Each HV has 1 VIF port. The first digit
14146 # of VIF port name indicates the hypervisor it is bound to, e.g.
14147 # lp23 means VIF 3 on hv2.
14148 #
14149 # Each switch's VLAN tag and their logical switch ports are:
14150 # - ls1:
14151 # - tagged with VLAN 101
14152 # - ports: lp11
14153 # - ls2:
14154 # - tagged with VLAN 201
14155 # - ports: lp22
14156 #
14157 # Note: a localnet port is created for each switch to connect to
14158 # physical network.
14159
14160 for i in 1 2; do
14161 ls_name=ls$i
14162 ovn-nbctl ls-add $ls_name
14163 ln_port_name=ln$i
14164 if test $i -eq 1; then
14165 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
14166 elif test $i -eq 2; then
14167 ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
14168 fi
14169 ovn-nbctl lsp-set-addresses $ln_port_name unknown
14170 ovn-nbctl lsp-set-type $ln_port_name localnet
14171 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
14172 done
14173
14174 # lsp_to_ls LSP
14175 #
14176 # Prints the name of the logical switch that contains LSP.
14177 lsp_to_ls () {
14178 case $1 in dnl (
14179 lp?[[11]]) echo ls1 ;; dnl (
14180 lp?[[12]]) echo ls2 ;; dnl (
14181 *) AT_FAIL_IF([:]) ;;
14182 esac
14183 }
14184
14185 vif_to_ls () {
14186 case $1 in dnl (
14187 vif?[[11]]) echo ls1 ;; dnl (
14188 vif?[[12]]) echo ls2 ;; dnl (
14189 *) AT_FAIL_IF([:]) ;;
14190 esac
14191 }
14192
14193 hv_to_num () {
14194 case $1 in dnl (
14195 hv1) echo 1 ;; dnl (
14196 hv2) echo 2 ;; dnl (
14197 *) AT_FAIL_IF([:]) ;;
14198 esac
14199 }
14200
14201 vif_to_num () {
14202 case $1 in dnl (
14203 vif22) echo 22 ;; dnl (
14204 vif21) echo 21 ;; dnl (
14205 *) AT_FAIL_IF([:]) ;;
14206 esac
14207 }
14208
14209 vif_to_hv () {
14210 case $1 in dnl (
14211 vif[[1]]?) echo hv1 ;; dnl (
14212 vif[[2]]?) echo hv2 ;; dnl (
14213 *) AT_FAIL_IF([:]) ;;
14214 esac
14215 }
14216
14217 vif_to_lrp () {
14218 echo router-to-`vif_to_ls $1`
14219 }
14220
14221 hv_to_chassis_mac () {
14222 case $1 in dnl (
14223 hv[[1]]) echo aa:bb:cc:dd:ee:11 ;; dnl (
14224 hv[[2]]) echo aa:bb:cc:dd:ee:22 ;; dnl (
14225 *) AT_FAIL_IF([:]) ;;
14226 esac
14227 }
14228
14229 ip_to_hex() {
14230 printf "%02x%02x%02x%02x" "$@"
14231 }
14232
14233 net_add n1
14234 for i in 1 2; do
14235 sim_add hv$i
14236 as hv$i
14237 ovs-vsctl add-br br-phys
14238 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
14239 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
14240 ovn_attach n1 br-phys 192.168.0.$i
14241
14242 ovs-vsctl add-port br-int vif$i$i -- \
14243 set Interface vif$i$i external-ids:iface-id=lp$i$i \
14244 options:tx_pcap=hv$i/vif$i$i-tx.pcap \
14245 options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
14246 ofport-request=$i$i
14247
14248 lsp_name=lp$i$i
14249 ls_name=$(lsp_to_ls $lsp_name)
14250
14251 ovn-nbctl lsp-add $ls_name $lsp_name
14252 ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
14253 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
14254
14255 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
14256
14257 done
14258
14259 ovn-nbctl lr-add router
14260 ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
14261 ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
14262
14263 ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
14264 ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
14265
14266 ovn-nbctl --wait=sb sync
14267 #ovn-sbctl dump-flows
14268
14269 ovn-nbctl show
14270 ovn-sbctl show
14271
14272 OVN_POPULATE_ARP
14273
14274 test_ip() {
14275 # This packet has bad checksums but logical L3 routing doesn't check.
14276 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
14277 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
14278 shift; shift; shift; shift; shift
14279 hv=`vif_to_hv $inport`
14280 hv_num=`hv_to_num $hv`
14281 chassis_mac=`hv_to_chassis_mac $hv`
14282 as $hv ovs-appctl netdev-dummy/receive $inport $packet
14283 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
14284 in_ls=`vif_to_ls $inport`
14285 in_lrp=`vif_to_lrp $inport`
14286 for outport; do
14287 out_ls=`vif_to_ls $outport`
14288 if test $in_ls = $out_ls; then
14289 # Ports on the same logical switch receive exactly the same packet.
14290 echo $packet
14291 else
14292 # Routing decrements TTL and updates source and dest MAC
14293 # (and checksum).
14294 outport_num=`vif_to_num $outport`
14295 out_lrp=`vif_to_lrp $outport`
14296 echo f000000000${outport_num}aabbccddee${hv_num}${hv_num}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
14297 fi >> $outport.expected
14298 done
14299 }
14300
14301 # Dump a bunch of info helpful for debugging if there's a failure.
14302
14303 echo "------ OVN dump ------"
14304 ovn-nbctl show
14305 ovn-sbctl show
14306
14307 echo "------ hv1 dump ------"
14308 as hv1 ovs-vsctl show
14309 as hv1 ovs-vsctl list Open_Vswitch
14310
14311 echo "------ hv2 dump ------"
14312 as hv2 ovs-vsctl show
14313 as hv2 ovs-vsctl list Open_Vswitch
14314
14315 echo "Send traffic"
14316 sip=`ip_to_hex 192 168 1 1`
14317 dip=`ip_to_hex 192 168 2 2`
14318 test_ip vif11 f00000000011 000001010203 $sip $dip vif22
14319
14320 echo "----------- Post Traffic hv1 dump -----------"
14321 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
14322 as hv1 ovs-appctl fdb/show br-phys
14323
14324 echo "----------- Post Traffic hv2 dump -----------"
14325 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
14326 as hv2 ovs-appctl fdb/show br-phys
14327
14328 OVN_CHECK_PACKETS([hv2/vif22-tx.pcap], [vif22.expected])
14329
14330 OVN_CLEANUP([hv1],[hv2])
14331
14332 AT_CLEANUP
14333
14334 # Run ovn-nbctl in daemon mode, change to a backup database and verify that
14335 # an insert operation is not allowed.
14336 AT_SETUP([ovn -- can't write to a backup database server instance])
14337 ovn_start
14338 on_exit 'kill $(cat ovn-nbctl.pid)'
14339 export OVN_NB_DAEMON=$(ovn-nbctl --pidfile --detach)
14340
14341 AT_CHECK([ovn-nbctl ls-add sw0])
14342 as ovn-nb
14343 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/sync-status | grep active | wc -l], [0], [1
14344 ])
14345 ovs-appctl -t ovsdb-server ovsdb-server/set-active-ovsdb-server tcp:192.0.2.2:6641
14346 ovs-appctl -t ovsdb-server ovsdb-server/connect-active-ovsdb-server
14347 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/sync-status | grep -c backup], [0], [1
14348 ])
14349 AT_CHECK([ovn-nbctl ls-add sw1], [1], [ignore],
14350 [ovn-nbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
14351 ])
14352
14353 AT_CLEANUP