]> git.proxmox.com Git - mirror_ovs.git/blob - tests/ovn.at
treewide: Convert leading tabs to spaces.
[mirror_ovs.git] / tests / ovn.at
1 # OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2 #
3 # This compares packets read from PCAP, in pcap format, to those read
4 # from EXPECTED, which is a text file containing packets as hex
5 # strings, one per line. If PCAP contains fewer packets than
6 # EXPECTED, it waits up to 10 seconds for more packets to appear.
7 #
8 # The implementation is an m4 macro that is mostly implemented in
9 # terms of a shell function. This reduces the size of the generated
10 # testsuite file since the shell function is only emitted once even
11 # when this macro is invoked many times.
12 m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
20 ovs_wait_cond () {
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
24 }
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
26
27 sort $exp_text > expout
28 }
29 ])
30 m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
33
34 AT_BANNER([OVN components])
35
36 AT_SETUP([ovn -- lexer])
37 dnl For lines without =>, input and expected output are identical.
38 dnl For lines with =>, input precedes => and expected output follows =>.
39 AT_DATA([test-cases.txt], [dnl
40 foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41 "abc\u0020def" => "abc def"
42 " => error("Input ends inside quoted string.")dnl "
43
44 $foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45 $1 => error("`$' must be followed by a valid identifier.") 1
46
47 a/*b*/c => a c
48 a//b c => a
49 a/**/b => a b
50 a/*/b => a error("`/*' without matching `*/'.")
51 a/*/**/b => a b
52 a/b => a error("`/' is only valid as part of `//' or `/*'.") b
53
54 0 1 12345 18446744073709551615
55 18446744073709551616 => error("Decimal constants must be less than 2**64.")
56 9999999999999999999999 => error("Decimal constants must be less than 2**64.")
57 01 => error("Decimal constants must not have leading zeros.")
58
59 0/0
60 0/1
61 1/0 => error("Value contains unmasked 1-bits.")
62 1/1
63 128/384
64 1/3
65 1/ => error("Integer constant expected.")
66
67 1/0x123 => error("Value and mask have incompatible formats.")
68
69 0x1234
70 0x01234 => 0x1234
71 0x0 => 0
72 0x000 => 0
73 0xfedcba9876543210
74 0XFEDCBA9876543210 => 0xfedcba9876543210
75 0xfedcba9876543210fedcba9876543210
76 0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
77 0x => error("Hex digits expected following 0x.")
78 0X => error("Hex digits expected following 0X.")
79 0x0/0x0 => 0/0
80 0x0/0x1 => 0/0x1
81 0x1/0x0 => error("Value contains unmasked 1-bits.")
82 0xffff/0x1ffff
83 0x. => error("Invalid syntax in hexadecimal constant.")
84
85 192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86 256.1.2.3 => error("Invalid numeric constant.")
87 192.168.0.0/16
88 192.168.0.0/255.255.0.0 => 192.168.0.0/16
89 192.168.0.0/255.255.255.0 => 192.168.0.0/24
90 192.168.0.0/255.255.0.255
91 192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
92 192.168.0.0/32
93 192.168.0.0/255.255.255.255 => 192.168.0.0/32
94 1.2.3.4:5 => 1.2.3.4 : 5
95
96 ::
97 ::1
98 ff00::1234 => ff00::1234
99 2001:db8:85a3::8a2e:370:7334
100 2001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
101 2001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
102 ::ffff:192.0.2.128
103 ::ffff:c000:0280 => ::ffff:192.0.2.128
104 ::1/::1
105 ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
106 ::1/128
107 ff00::/8
108 ff00::/ff00:: => ff00::/8
109
110 01:23:45:67:ab:cd
111 01:23:45:67:AB:CD => 01:23:45:67:ab:cd
112 fe:dc:ba:98:76:54
113 FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
114 01:00:00:00:00:00/01:00:00:00:00:00
115 ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116 fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117 ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118 fe:x => error("Invalid numeric constant.")
119 00:01:02:03:04:x => error("Invalid numeric constant.")
120
121 # Test that operators are tokenized as expected, even without white space.
122 (){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
123 & => error("`&' is only valid as part of `&&'.")
124 | => error("`|' is only valid as part of `||'.")
125 - => error("`-' is only valid as part of `--'.")
126
127 ^ => error("Invalid character `^' in input.")
128 ])
129 AT_CAPTURE_FILE([input.txt])
130 sed 's/ =>.*//' test-cases.txt > input.txt
131 sed 's/.* => //' test-cases.txt > expout
132 AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
133 AT_CLEANUP
134
135 dnl The OVN expression parser needs to know what fields overlap with one
136 dnl another. This test therefore verifies that all the smaller registers
137 dnl are defined as terms of subfields of the larger ones.
138 dnl
139 dnl When we add or remove registers this test needs to be updated, of course.
140 AT_SETUP([ovn -- registers])
141 AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142 [[reg0 = xxreg0[96..127]
143 reg1 = xxreg0[64..95]
144 reg2 = xxreg0[32..63]
145 reg3 = xxreg0[0..31]
146 reg4 = xxreg1[96..127]
147 reg5 = xxreg1[64..95]
148 reg6 = xxreg1[32..63]
149 reg7 = xxreg1[0..31]
150 reg8 = xreg4[32..63]
151 reg9 = xreg4[0..31]
152 xreg0 = xxreg0[64..127]
153 xreg1 = xxreg0[0..63]
154 xreg2 = xxreg1[64..127]
155 xreg3 = xxreg1[0..63]
156 xreg4 = OXM_OF_PKT_REG4
157 xxreg0 = NXM_NX_XXREG0
158 xxreg1 = NXM_NX_XXREG1
159 ]])
160 AT_CLEANUP
161
162 dnl Check that the OVN conntrack field definitions are correct.
163 AT_SETUP([ovn -- conntrack fields])
164 AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
165 [[ct.dnat = ct_state[7]
166 ct.est = ct_state[1]
167 ct.inv = ct_state[4]
168 ct.new = ct_state[0]
169 ct.rel = ct_state[2]
170 ct.rpl = ct_state[3]
171 ct.snat = ct_state[6]
172 ct.trk = ct_state[5]
173 ct_label = NXM_NX_CT_LABEL
174 ct_label.blocked = ct_label[0]
175 ct_mark = NXM_NX_CT_MARK
176 ct_state = NXM_NX_CT_STATE
177 ]])
178 AT_CLEANUP
179
180 AT_SETUP([ovn -- composition])
181 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
182 AT_CLEANUP
183
184 AT_SETUP([ovn -- expression parser])
185 dnl For lines without =>, input and expected output are identical.
186 dnl For lines with =>, input precedes => and expected output follows =>.
187 AT_DATA([test-cases.txt], [[
188 eth.type == 0x800
189 eth.type==0x800 => eth.type == 0x800
190 eth.type[0..15] == 0x800 => eth.type == 0x800
191
192 vlan.present
193 vlan.present == 1 => vlan.present
194 !(vlan.present == 0) => vlan.present
195 !(vlan.present != 1) => vlan.present
196 !vlan.present
197 vlan.present == 0 => !vlan.present
198 vlan.present != 1 => !vlan.present
199 !(vlan.present == 1) => !vlan.present
200 !(vlan.present != 0) => !vlan.present
201
202 eth.dst[0]
203 eth.dst[0] == 1 => eth.dst[0]
204 eth.dst[0] != 0 => eth.dst[0]
205 !(eth.dst[0] == 0) => eth.dst[0]
206 !(eth.dst[0] != 1) => eth.dst[0]
207
208 !eth.dst[0]
209 eth.dst[0] == 0 => !eth.dst[0]
210 eth.dst[0] != 1 => !eth.dst[0]
211 !(eth.dst[0] == 1) => !eth.dst[0]
212 !(eth.dst[0] != 0) => !eth.dst[0]
213
214 vlan.tci[12..15] == 0x3
215 vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
216 vlan.tci[12..15] != 0x3
217 vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
218
219 !vlan.pcp => vlan.pcp == 0
220 !(vlan.pcp) => vlan.pcp == 0
221 vlan.pcp == 0x4
222 vlan.pcp != 0x4
223 vlan.pcp > 0x4
224 vlan.pcp >= 0x4
225 vlan.pcp < 0x4
226 vlan.pcp <= 0x4
227 !(vlan.pcp != 0x4) => vlan.pcp == 0x4
228 !(vlan.pcp == 0x4) => vlan.pcp != 0x4
229 !(vlan.pcp <= 0x4) => vlan.pcp > 0x4
230 !(vlan.pcp < 0x4) => vlan.pcp >= 0x4
231 !(vlan.pcp >= 0x4) => vlan.pcp < 0x4
232 !(vlan.pcp > 0x4) => vlan.pcp <= 0x4
233 0x4 == vlan.pcp => vlan.pcp == 0x4
234 0x4 != vlan.pcp => vlan.pcp != 0x4
235 0x4 < vlan.pcp => vlan.pcp > 0x4
236 0x4 <= vlan.pcp => vlan.pcp >= 0x4
237 0x4 > vlan.pcp => vlan.pcp < 0x4
238 0x4 >= vlan.pcp => vlan.pcp <= 0x4
239 !(0x4 != vlan.pcp) => vlan.pcp == 0x4
240 !(0x4 == vlan.pcp) => vlan.pcp != 0x4
241 !(0x4 >= vlan.pcp) => vlan.pcp > 0x4
242 !(0x4 > vlan.pcp) => vlan.pcp >= 0x4
243 !(0x4 <= vlan.pcp) => vlan.pcp < 0x4
244 !(0x4 < vlan.pcp) => vlan.pcp <= 0x4
245
246 1 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
247 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
248 1 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
249 1 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
250 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
251 4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
252 4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
253 4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
254 4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
255 !(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
256 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
257 !(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
258 !(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
259 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
260 !(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
261 !(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
262 !(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
263 !(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
264
265 vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266 vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
267
268 vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
269 vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
270
271 vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
272 vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
273 vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
274
275 ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
276 ip6.src == ::1 => ip6.src == 0x1
277
278 ip4.src == 1.2.3.4 => ip4.src == 0x1020304
279 ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
280 ip6.src == ::1 => ip6.src == 0x1
281
282 1
283 0
284 !1 => 0
285 !0 => 1
286
287 inport == "eth0"
288 !(inport != "eth0") => inport == "eth0"
289
290 ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
291 inport == 1 => String field inport is not compatible with integer constant.
292 ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
293
294 ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
295 eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
296 vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
297
298 inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
299 !(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
300 eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
301 !(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
302 inport = "eth0" => Syntax error at `=' expecting relational operator.
303
304 123 == 123 => Syntax error at `123' expecting field name.
305
306 $name => Syntax error at `$name' expecting address set name.
307 @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 sed 's/ =>.*//' test-cases.txt > input.txt
358 sed 's/.* => //' test-cases.txt > expout
359 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
360 AT_CLEANUP
361
362 AT_SETUP([ovn -- expression annotation])
363 dnl Input precedes =>, expected output follows =>.
364 dnl Empty lines and lines starting with # are ignored.
365 AT_DATA([test-cases.txt], [[
366 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
367 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
368 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
369 ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
370 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
371
372 # Nested expressions over a single symbol should be annotated with symbol's
373 # prerequisites only once, at the top level.
374 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)
375
376 ip => eth.type == 0x800 || eth.type == 0x86dd
377 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
378 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
379 ip > 0 => Only == and != operators may be used with nominal field ip.
380 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
381 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
382
383 vlan.present => vlan.tci[12]
384 !vlan.present => !vlan.tci[12]
385
386 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
387 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
388 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
389
390 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
391 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
392 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
393
394 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
395 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
396 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'.
397 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'.
398 ]])
399 sed 's/ =>.*//' test-cases.txt > input.txt
400 sed 's/.* => //' test-cases.txt > expout
401 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
402 AT_CLEANUP
403
404 AT_SETUP([ovn -- 1-term expression conversion])
405 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
406 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
407 ])
408 AT_CLEANUP
409
410 AT_SETUP([ovn -- 2-term expression conversion])
411 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
412 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
413 ])
414 AT_CLEANUP
415
416 AT_SETUP([ovn -- 3-term expression conversion])
417 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
418 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
419 ])
420 AT_CLEANUP
421
422 AT_SETUP([ovn -- 3-term numeric expression simplification])
423 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
424 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
425 ])
426 AT_CLEANUP
427
428 AT_SETUP([ovn -- 4-term string expression simplification])
429 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
430 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
431 ])
432 AT_CLEANUP
433
434 AT_SETUP([ovn -- 3-term mixed expression simplification])
435 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
436 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
437 ])
438 AT_CLEANUP
439
440 AT_SETUP([ovn -- simplification special cases])
441 simplify() {
442 echo "$1" | ovstest test-ovn simplify-expr
443 }
444 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
445 ])
446 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
447 ])
448 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
449 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
450 ])
451 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
452 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
453 ])
454 AT_CHECK([simplify 'tcp.dst > 0'], [0],
455 [[(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)
456 ]])
457 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
458 [[(!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)
459 ]])
460 AT_CLEANUP
461
462 AT_SETUP([ovn -- is_chassis_resident simplification])
463 simplify() {
464 echo "$1" | ovstest test-ovn simplify-expr
465 }
466 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
467 ])
468 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
469 ])
470 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
471 ])
472 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
473 ])
474 AT_CLEANUP
475
476 AT_SETUP([ovn -- 4-term numeric expression normalization])
477 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
478 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
479 ])
480 AT_CLEANUP
481
482 AT_SETUP([ovn -- 4-term string expression normalization])
483 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
484 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
485 ])
486 AT_CLEANUP
487
488 AT_SETUP([ovn -- 4-term mixed expression normalization])
489 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
490 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
491 ])
492 AT_CLEANUP
493
494 AT_SETUP([ovn -- 5-term numeric expression normalization])
495 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
496 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
497 ])
498 AT_CLEANUP
499
500 AT_SETUP([ovn -- 5-term string expression normalization])
501 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
503 ])
504 AT_CLEANUP
505
506 AT_SETUP([ovn -- 5-term mixed expression normalization])
507 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
508 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
509 ])
510 AT_CLEANUP
511
512 AT_SETUP([ovn -- 4-term numeric expressions to flows])
513 AT_KEYWORDS([expression])
514 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
515 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
516 ])
517 AT_CLEANUP
518
519 AT_SETUP([ovn -- 4-term string expressions to flows])
520 AT_KEYWORDS([expression])
521 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
522 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
523 ])
524 AT_CLEANUP
525
526 AT_SETUP([ovn -- 4-term mixed expressions to flows])
527 AT_KEYWORDS([expression])
528 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
529 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
530 ])
531 AT_CLEANUP
532
533 AT_SETUP([ovn -- 3-term numeric expressions to flows])
534 AT_KEYWORDS([expression])
535 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
536 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
537 ])
538 AT_CLEANUP
539
540 AT_SETUP([ovn -- converting expressions to flows -- string fields])
541 AT_KEYWORDS([expression])
542 expr_to_flow () {
543 echo "$1" | ovstest test-ovn expr-to-flows | sort
544 }
545 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
546 ])
547 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
548 ])
549 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
550 ])
551 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
552 ip,reg14=0x5
553 ipv6,reg14=0x5
554 ])
555 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
556 ip,reg14=0x6
557 ipv6,reg14=0x6
558 ])
559 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
560 ])
561 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
562 [reg14=0x5
563 reg14=0x6
564 reg14=0xfffe
565 ])
566 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
567 ip,reg14=0x5
568 ip,reg14=0x6
569 ipv6,reg14=0x5
570 ipv6,reg14=0x6
571 ])
572 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
573 (no flows)
574 ])
575 AT_CLEANUP
576
577 AT_SETUP([ovn -- converting expressions to flows -- address sets])
578 AT_KEYWORDS([expression])
579 expr_to_flow () {
580 echo "$1" | ovstest test-ovn expr-to-flows | sort
581 }
582 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
583 ip,nw_src=10.0.0.1
584 ip,nw_src=10.0.0.2
585 ip,nw_src=10.0.0.3
586 ])
587 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
588 ip,nw_src=10.0.0.1
589 ip,nw_src=10.0.0.2
590 ip,nw_src=10.0.0.3
591 ])
592 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
593 ip,nw_src=1.2.3.4
594 ip,nw_src=10.0.0.1
595 ip,nw_src=10.0.0.2
596 ip,nw_src=10.0.0.3
597 ])
598 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
599 ip,nw_src=1.2.0.0/20
600 ip,nw_src=10.0.0.1
601 ip,nw_src=10.0.0.2
602 ip,nw_src=10.0.0.3
603 ip,nw_src=5.5.5.0/24
604 ])
605 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
606 ipv6,ipv6_src=::1
607 ipv6,ipv6_src=::2
608 ipv6,ipv6_src=::3
609 ])
610 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
611 ipv6,ipv6_src=::1
612 ipv6,ipv6_src=::2
613 ipv6,ipv6_src=::3
614 ipv6,ipv6_src=::4
615 ])
616 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
617 dl_src=00:00:00:00:00:01
618 dl_src=00:00:00:00:00:02
619 dl_src=00:00:00:00:00:03
620 ])
621 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
622 dl_src=00:00:00:00:00:01
623 dl_src=00:00:00:00:00:02
624 dl_src=00:00:00:00:00:03
625 ])
626 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
627 dl_src=00:00:00:00:00:01
628 dl_src=00:00:00:00:00:02
629 dl_src=00:00:00:00:00:03
630 dl_src=ba:be:be:ef:de:ad
631 ])
632 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
633 (no flows)
634 ])
635 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
636 ip,nw_src=1.2.3.4
637 ])
638 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
639 ip,nw_src=1.2.3.4
640 ])
641 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
642
643 ])
644 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
645 ip,nw_src=0.0.0.0/1.0.0.0
646 ip,nw_src=128.0.0.0/1
647 ip,nw_src=16.0.0.0/16.0.0.0
648 ip,nw_src=2.0.0.0/2.0.0.0
649 ip,nw_src=32.0.0.0/32.0.0.0
650 ip,nw_src=4.0.0.0/4.0.0.0
651 ip,nw_src=64.0.0.0/64.0.0.0
652 ip,nw_src=8.0.0.0/8.0.0.0
653 ])
654 AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
655 ip,nw_src=0.0.0.0/1.0.0.0
656 ip,nw_src=128.0.0.0/1
657 ip,nw_src=16.0.0.0/16.0.0.0
658 ip,nw_src=2.0.0.0/2.0.0.0
659 ip,nw_src=32.0.0.0/32.0.0.0
660 ip,nw_src=4.0.0.0/4.0.0.0
661 ip,nw_src=64.0.0.0/64.0.0.0
662 ip,nw_src=8.0.0.0/8.0.0.0
663 ])
664 AT_CLEANUP
665
666 AT_SETUP([ovn -- converting expressions to flows -- port groups])
667 AT_KEYWORDS([expression])
668 expr_to_flow () {
669 echo "$1" | ovstest test-ovn expr-to-flows | sort
670 }
671 AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
672 reg15=0x11
673 reg15=0x12
674 reg15=0x13
675 ])
676 AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
677 (no flows)
678 ])
679 AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
680 reg15=0x11
681 ])
682 AT_CLEANUP
683
684 AT_SETUP([ovn -- converting expressions to flows -- conjunction])
685 AT_KEYWORDS([conjunction])
686 expr_to_flow () {
687 echo "$1" | ovstest test-ovn expr-to-flows | sort
688 }
689
690 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
691 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
692 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
693 conj_id=1,ip
694 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
695 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
696 ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
697 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
698 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
699 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
700 ])
701
702 lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
703 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
704 ct_state=+est+trk,ct_label=0x1/0x1,ip
705 ct_state=+est+trk,ct_label=0x1/0x1,ipv6
706 ct_state=-est+trk,ip
707 ct_state=-est+trk,ipv6
708 ])
709
710 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
711 ip4.dst == {20.0.0.1, 20.0.0.2}"
712 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
713 conj_id=1,ip
714 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
715 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
716 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
717 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
718 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
719 ])
720
721 lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
722 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
723 tcp.dst >= 1000 && tcp.dst <= 1010"
724
725 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
726 conj_id=1,tcp
727 tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
728 tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
729 tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
730 tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
731 tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
732 tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
733 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
734 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
735 tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
736 tcp,tp_dst=1000: conjunction(1, 2/3)
737 tcp,tp_dst=1001: conjunction(1, 2/3)
738 tcp,tp_dst=1010: conjunction(1, 2/3)
739 ])
740
741 lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
742 ((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
743 tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
744 || ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
745
746 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
747 conj_id=1,tcp
748 ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
749 ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
750 ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
751 ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
752 ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
753 ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
754 tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
755 tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
756 tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
757 tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
758 tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
759 tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
760 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
761 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
762 tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
763 tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
764 tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
765 tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
766 tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
767 tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
768 tcp,tp_dst=1000: conjunction(1, 2/4)
769 tcp,tp_dst=1001: conjunction(1, 2/4)
770 tcp,tp_dst=2000: conjunction(1, 2/4)
771 tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
772 tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
773 tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
774 tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
775 tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
776 tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
777 tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
778 tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
779 tcp,tp_src=1000: conjunction(1, 3/4)
780 tcp,tp_src=1001: conjunction(1, 3/4)
781 tcp,tp_src=2000: conjunction(1, 3/4)
782 ])
783 AT_CLEANUP
784
785 AT_SETUP([ovn -- action parsing])
786 dnl Unindented text is input (a set of OVN logical actions).
787 dnl Indented text is expected output.
788 AT_DATA([test-cases.txt],
789 [[# drop
790 drop;
791 encodes as drop
792 drop; next;
793 Syntax error at `next' expecting end of input.
794 next; drop;
795 Syntax error at `drop' expecting action.
796
797 # output
798 output;
799 encodes as resubmit(,64)
800
801 # next
802 next;
803 encodes as resubmit(,19)
804 next(11);
805 formats as next;
806 encodes as resubmit(,19)
807 next(0);
808 encodes as resubmit(,8)
809 next(23);
810 encodes as resubmit(,31)
811
812 next();
813 Syntax error at `)' expecting "pipeline" or "table".
814 next(10;
815 Syntax error at `;' expecting `)'.
816 next(24);
817 "next" action cannot advance beyond table 23.
818
819 next(table=11);
820 formats as next;
821 encodes as resubmit(,19)
822 next(pipeline=ingress);
823 formats as next;
824 encodes as resubmit(,19)
825 next(table=11, pipeline=ingress);
826 formats as next;
827 encodes as resubmit(,19)
828 next(pipeline=ingress, table=11);
829 formats as next;
830 encodes as resubmit(,19)
831
832 next(pipeline=egress);
833 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
834
835 next(table=10);
836 formats as next(10);
837 encodes as resubmit(,18)
838
839 # Loading a constant value.
840 tcp.dst=80;
841 formats as tcp.dst = 80;
842 encodes as set_field:80->tcp_dst
843 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
844 eth.dst[40] = 1;
845 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
846 vlan.pcp = 2;
847 encodes as set_field:0x4000/0xe000->vlan_tci
848 has prereqs vlan.tci[12]
849 vlan.tci[13..15] = 2;
850 encodes as set_field:0x4000/0xe000->vlan_tci
851 inport = "";
852 encodes as set_field:0->reg14
853 ip.ttl=4;
854 formats as ip.ttl = 4;
855 encodes as set_field:4->nw_ttl
856 has prereqs eth.type == 0x800 || eth.type == 0x86dd
857 outport="eth0"; next; outport="LOCAL"; next;
858 formats as outport = "eth0"; next; outport = "LOCAL"; next;
859 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
860
861 inport[1] = 1;
862 Cannot select subfield of string field inport.
863 ip.proto[1] = 1;
864 Cannot select subfield of nominal field ip.proto.
865 eth.dst[40] == 1;
866 Syntax error at `==' expecting `=' or `<->'.
867 ip = 1;
868 Predicate symbol ip used where lvalue required.
869 ip.proto = 6;
870 Field ip.proto is not modifiable.
871 inport = {"a", "b"};
872 Syntax error at `{' expecting constant.
873 inport = {};
874 Syntax error at `{' expecting constant.
875 bad_prereq = 123;
876 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
877 self_recurse = 123;
878 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'.
879 vlan.present = 0;
880 Predicate symbol vlan.present used where lvalue required.
881
882 # Moving one field into another.
883 reg0=reg1;
884 formats as reg0 = reg1;
885 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
886 vlan.pcp = reg0[0..2];
887 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
888 has prereqs vlan.tci[12]
889 reg0[10] = vlan.pcp[1];
890 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
891 has prereqs vlan.tci[12]
892 outport = inport;
893 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
894
895 reg0[0] = vlan.present;
896 Predicate symbol vlan.present used where lvalue required.
897 reg0 = reg1[0..10];
898 Can't assign 11-bit value to 32-bit destination.
899 inport = reg0;
900 Can't assign integer field (reg0) to string field (inport).
901 inport = big_string;
902 String fields inport and big_string are incompatible for assignment.
903 ip.proto = reg0[0..7];
904 Field ip.proto is not modifiable.
905
906 # Exchanging fields.
907 reg0 <-> reg1;
908 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]
909 vlan.pcp <-> reg0[0..2];
910 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]
911 has prereqs vlan.tci[12]
912 reg0[10] <-> vlan.pcp[1];
913 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
914 has prereqs vlan.tci[12]
915 outport <-> inport;
916 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
917
918 reg0[0] <-> vlan.present;
919 Predicate symbol vlan.present used where lvalue required.
920 reg0 <-> reg1[0..10];
921 Can't exchange 32-bit field with 11-bit field.
922 inport <-> reg0;
923 Can't exchange string field (inport) with integer field (reg0).
924 inport <-> big_string;
925 String fields inport and big_string are incompatible for exchange.
926 ip.proto <-> reg0[0..7];
927 Field ip.proto is not modifiable.
928 reg0[0..7] <-> ip.proto;
929 Field ip.proto is not modifiable.
930
931 # TTL decrement.
932 ip.ttl--;
933 encodes as dec_ttl
934 has prereqs ip
935 ip.ttl
936 Syntax error at end of input expecting `--'.
937
938 # load balancing.
939 ct_lb;
940 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
941 has prereqs ip
942 ct_lb();
943 formats as ct_lb;
944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
945 has prereqs ip
946 ct_lb(192.168.1.2:80, 192.168.1.3:80);
947 encodes as group:1
948 has prereqs ip
949 ct_lb(192.168.1.2, 192.168.1.3, );
950 formats as ct_lb(192.168.1.2, 192.168.1.3);
951 encodes as group:2
952 has prereqs ip
953 ct_lb(fd0f::2, fd0f::3, );
954 formats as ct_lb(fd0f::2, fd0f::3);
955 encodes as group:3
956 has prereqs ip
957
958 ct_lb(192.168.1.2:);
959 Syntax error at `)' expecting port number.
960 ct_lb(192.168.1.2:123456);
961 Syntax error at `123456' expecting port number.
962 ct_lb(foo);
963 Syntax error at `foo' expecting IP address.
964 ct_lb([192.168.1.2]);
965 Syntax error at `192.168.1.2' expecting IPv6 address.
966
967 # ct_next
968 ct_next;
969 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
970 has prereqs ip
971
972 # ct_commit
973 ct_commit;
974 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
975 has prereqs ip
976 ct_commit();
977 formats as ct_commit;
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
979 has prereqs ip
980 ct_commit(ct_mark=1);
981 formats as ct_commit(ct_mark=0x1);
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
983 has prereqs ip
984 ct_commit(ct_mark=1/1);
985 formats as ct_commit(ct_mark=0x1/0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
987 has prereqs ip
988 ct_commit(ct_label=1);
989 formats as ct_commit(ct_label=0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
991 has prereqs ip
992 ct_commit(ct_label=1/1);
993 formats as ct_commit(ct_label=0x1/0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
995 has prereqs ip
996 ct_commit(ct_mark=1, ct_label=2);
997 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
999 has prereqs ip
1000
1001 ct_commit(ct_label=0x01020304050607080910111213141516);
1002 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1003 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1004 has prereqs ip
1005 ct_commit(ct_label=0x181716151413121110090807060504030201);
1006 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1008 has prereqs ip
1009 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1010 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1011 has prereqs ip
1012 ct_commit(ct_label=18446744073709551615);
1013 formats as ct_commit(ct_label=0xffffffffffffffff);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1015 has prereqs ip
1016 ct_commit(ct_label=18446744073709551616);
1017 Decimal constants must be less than 2**64.
1018
1019 # ct_dnat
1020 ct_dnat;
1021 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
1022 has prereqs ip
1023 ct_dnat(192.168.1.2);
1024 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
1025 has prereqs ip
1026
1027 ct_dnat(192.168.1.2, 192.168.1.3);
1028 Syntax error at `,' expecting `)'.
1029 ct_dnat(foo);
1030 Syntax error at `foo' expecting IPv4 address.
1031 ct_dnat(foo, bar);
1032 Syntax error at `foo' expecting IPv4 address.
1033 ct_dnat();
1034 Syntax error at `)' expecting IPv4 address.
1035
1036 # ct_snat
1037 ct_snat;
1038 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
1039 has prereqs ip
1040 ct_snat(192.168.1.2);
1041 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
1042 has prereqs ip
1043
1044 ct_snat(192.168.1.2, 192.168.1.3);
1045 Syntax error at `,' expecting `)'.
1046 ct_snat(foo);
1047 Syntax error at `foo' expecting IPv4 address.
1048 ct_snat(foo, bar);
1049 Syntax error at `foo' expecting IPv4 address.
1050 ct_snat();
1051 Syntax error at `)' expecting IPv4 address.
1052
1053 # ct_clear
1054 ct_clear;
1055 encodes as ct_clear
1056
1057 # clone
1058 clone { ip4.dst = 255.255.255.255; output; }; next;
1059 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
1060 has prereqs eth.type == 0x800
1061
1062 # arp
1063 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1064 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)
1065 has prereqs ip4
1066 arp { };
1067 formats as arp { drop; };
1068 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1069 has prereqs ip4
1070
1071 # get_arp
1072 get_arp(outport, ip4.dst);
1073 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[]
1074 has prereqs eth.type == 0x800
1075 get_arp(inport, reg0);
1076 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[]
1077
1078 get_arp;
1079 Syntax error at `;' expecting `('.
1080 get_arp();
1081 Syntax error at `)' expecting field name.
1082 get_arp(inport);
1083 Syntax error at `)' expecting `,'.
1084 get_arp(inport ip4.dst);
1085 Syntax error at `ip4.dst' expecting `,'.
1086 get_arp(inport, ip4.dst;
1087 Syntax error at `;' expecting `)'.
1088 get_arp(inport, eth.dst);
1089 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1090 get_arp(inport, outport);
1091 Cannot use string field outport where numeric field is required.
1092 get_arp(reg0, ip4.dst);
1093 Cannot use numeric field reg0 where string field is required.
1094
1095 # put_arp
1096 put_arp(inport, arp.spa, arp.sha);
1097 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[]
1098 has prereqs eth.type == 0x806 && eth.type == 0x806
1099
1100 # put_dhcp_opts
1101 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1102 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)
1103 reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
1104 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain = "ovn.org");
1105 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67,pause)
1106 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);
1107 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);
1108 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00,pause)
1109
1110 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1111 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1112 reg1[0] = put_dhcp_opts();
1113 put_dhcp_opts requires offerip to be specified.
1114 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1115 Syntax error at `x' expecting DHCPv4 option name.
1116 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1117 put_dhcp_opts requires offerip to be specified.
1118 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1119 Syntax error at `"hi"'.
1120 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1121 Syntax error at `xyzzy' expecting DHCPv4 option name.
1122 reg1[0] = put_dhcp_opts(offerip="xyzzy");
1123 DHCPv4 option offerip requires numeric value.
1124 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1125 DHCPv4 option domain requires string value.
1126
1127 # nd_ns
1128 nd_ns { nd.target = xxreg0; output; };
1129 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)
1130 has prereqs ip6
1131
1132 nd_ns { };
1133 formats as nd_ns { drop; };
1134 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1135 has prereqs ip6
1136
1137 # nd_na
1138 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; };
1139 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1140 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)
1141 has prereqs nd_ns
1142 # nd_na_router
1143 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; };
1144 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; };
1145 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)
1146 has prereqs nd_ns
1147
1148 # get_nd
1149 get_nd(outport, ip6.dst);
1150 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[]
1151 has prereqs eth.type == 0x86dd
1152 get_nd(inport, xxreg0);
1153 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[]
1154 get_nd;
1155 Syntax error at `;' expecting `('.
1156 get_nd();
1157 Syntax error at `)' expecting field name.
1158 get_nd(inport);
1159 Syntax error at `)' expecting `,'.
1160 get_nd(inport ip6.dst);
1161 Syntax error at `ip6.dst' expecting `,'.
1162 get_nd(inport, ip6.dst;
1163 Syntax error at `;' expecting `)'.
1164 get_nd(inport, eth.dst);
1165 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1166 get_nd(inport, outport);
1167 Cannot use string field outport where numeric field is required.
1168 get_nd(xxreg0, ip6.dst);
1169 Cannot use numeric field xxreg0 where string field is required.
1170
1171 # put_nd
1172 put_nd(inport, nd.target, nd.sll);
1173 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[]
1174 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)
1175
1176 # put_dhcpv6_opts
1177 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1178 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)
1179 reg1[0] = put_dhcpv6_opts();
1180 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1181 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1182 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1183 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)
1184 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1185 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1186 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)
1187 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1188 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)
1189 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1190 Syntax error at `x' expecting DHCPv6 option name.
1191 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1192 Syntax error at `"hi"'.
1193 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1194 Syntax error at `xyzzy' expecting DHCPv6 option name.
1195 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1196 DHCPv6 option ia_addr requires numeric value.
1197 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1198 DHCPv6 option domain_search requires string value.
1199
1200 # set_queue
1201 set_queue(0);
1202 encodes as set_queue:0
1203 set_queue(61440);
1204 encodes as set_queue:61440
1205 set_queue(65535);
1206 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1207
1208 # dns_lookup
1209 reg1[0] = dns_lookup();
1210 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1211 has prereqs udp
1212 reg1[0] = dns_lookup("foo");
1213 dns_lookup doesn't take any parameters
1214
1215 # set_meter
1216 set_meter(0);
1217 Rate 0 for set_meter is not in valid.
1218 set_meter(1);
1219 encodes as meter:1
1220 set_meter(100, 1000);
1221 encodes as meter:2
1222 set_meter(100, 1000, );
1223 Syntax error at `,' expecting `)'.
1224 set_meter(4294967295, 4294967295);
1225 encodes as meter:3
1226
1227 # put_nd_ra_opts
1228 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1229 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)
1230 has prereqs ip6
1231 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1232 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)
1233 has prereqs ip6
1234 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1235 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)
1236 has prereqs ip6
1237 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1238 slla option not present
1239 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);
1240 prefix option can't be set when address mode is dhcpv6_stateful.
1241 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);
1242 prefix option can't be set when address mode is dhcpv6_stateful.
1243 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1244 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1245 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1246 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1247 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1248 Syntax error at `dhcpv6_stateless' expecting constant.
1249 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1250 Invalid value for "prefix" option
1251 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1252 Invalid value for "addr_mode" option
1253 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1254 IPv6 ND RA option mtu requires numeric value.
1255 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1256 Invalid value for "mtu" option
1257
1258 # icmp4
1259 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1260 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)
1261 has prereqs ip4
1262
1263 icmp4 { };
1264 formats as icmp4 { drop; };
1265 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1266 has prereqs ip4
1267
1268 # icmp6
1269 icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1270 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)
1271 has prereqs ip6
1272
1273 icmp6 { };
1274 formats as icmp6 { drop; };
1275 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1276 has prereqs ip6
1277
1278 # tcp_reset
1279 tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1280 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)
1281 has prereqs tcp
1282
1283 tcp_reset { };
1284 formats as tcp_reset { drop; };
1285 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1286 has prereqs tcp
1287
1288 # Contradictionary prerequisites (allowed but not useful):
1289 ip4.src = ip6.src[0..31];
1290 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1291 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1292 ip4.src <-> ip6.src[0..31];
1293 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[]
1294 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1295
1296 # Miscellaneous negative tests.
1297 ;
1298 Syntax error at `;'.
1299 xyzzy;
1300 Syntax error at `xyzzy' expecting action.
1301 next; 123;
1302 Syntax error at `123'.
1303 next; xyzzy;
1304 Syntax error at `xyzzy' expecting action.
1305 next
1306 Syntax error at end of input expecting `;'.
1307 ]])
1308 sed '/^[[ ]]/d' test-cases.txt > input.txt
1309 cp test-cases.txt expout
1310 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1311 AT_CLEANUP
1312
1313 AT_BANNER([OVN end-to-end tests])
1314
1315 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1316 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1317 AT_KEYWORDS([ovnarp])
1318 AT_SKIP_IF([test $HAVE_PYTHON = no])
1319 ovn_start
1320
1321 # Create hypervisors hv[123].
1322 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1323 # Add all of the vifs to a single logical switch lsw0.
1324 # Turn on port security on all the vifs except vif[123]1.
1325 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1326 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1327 ovn-nbctl ls-add lsw0
1328 net_add n1
1329 for i in 1 2 3; do
1330 sim_add hv$i
1331 as hv$i
1332 ovs-vsctl add-br br-phys
1333 ovn_attach n1 br-phys 192.168.0.$i
1334
1335 for j in 1 2 3; do
1336 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
1337 ovn-nbctl lsp-add lsw0 lp$i$j
1338 if test $j = 1; then
1339 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1340 else
1341 if test $j = 3; then
1342 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1343 else
1344 ip_addrs="192.168.0.$i$j"
1345 fi
1346 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1347 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1348 fi
1349 done
1350 done
1351 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1352 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1353 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1354 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\"
1355 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1356
1357 get_lsp_uuid () {
1358 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1359 }
1360
1361 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1362 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1363
1364 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1365 # packets for ARP resolution (native tunneling doesn't queue packets
1366 # for ARP resolution).
1367 OVN_POPULATE_ARP
1368
1369 # Allow some time for ovn-northd and ovn-controller to catch up.
1370 # XXX This should be more systematic.
1371 sleep 1
1372
1373 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1374 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1375 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1376 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1377
1378 # Given the name of a logical port, prints the name of the hypervisor
1379 # on which it is located.
1380 vif_to_hv() {
1381 echo hv${1%?}
1382 }
1383
1384 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1385 #
1386 # This shell function causes a packet to be received on INPORT. The packet's
1387 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1388 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1389 # more) list the VIFs on which the packet should be received. INPORT and the
1390 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1391 for i in 1 2 3; do
1392 for j in 1 2 3; do
1393 : > $i$j.expected
1394 done
1395 done
1396 test_packet() {
1397 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1398 hv=`vif_to_hv $inport`
1399 vif=vif$inport
1400 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1401 for outport; do
1402 echo $packet >> $outport.expected
1403 done
1404 }
1405
1406 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1407 #
1408 # Causes a packet to be received on INPORT. The packet is an ARP
1409 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1410 # it should be the hardware address of the target to expect to receive in an
1411 # ARP reply; otherwise no reply is expected.
1412 #
1413 # INPORT is an logical switch port number, e.g. 11 for vif11.
1414 # SHA and REPLY_HA are each 12 hex digits.
1415 # SPA and TPA are each 8 hex digits.
1416 test_arp() {
1417 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1418 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1419 hv=`vif_to_hv $inport`
1420 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1421
1422 if test X$reply_ha = X; then
1423 # Expect to receive the broadcast ARP on the other logical switch ports
1424 # if no reply is expected.
1425 local i j
1426 for i in 1 2 3; do
1427 for j in 1 2 3; do
1428 if test $i$j != $inport; then
1429 echo $request >> $i$j.expected
1430 fi
1431 done
1432 done
1433 else
1434 # Expect to receive the reply, if any.
1435 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1436 echo $reply >> $inport.expected
1437 fi
1438 }
1439
1440 ip_to_hex() {
1441 printf "%02x%02x%02x%02x" "$@"
1442 }
1443
1444 # Send packets between all pairs of source and destination ports:
1445 #
1446 # 1. Unicast packets are delivered to exactly one logical switch port
1447 # (except that packets destined to their input ports are dropped).
1448 #
1449 # 2. Broadcast and multicast are delivered to all logical switch ports
1450 # except the input port.
1451 #
1452 # 3. When port security is turned on, the switch drops packets from the wrong
1453 # MAC address.
1454 #
1455 # 4. The switch drops all packets with a VLAN tag.
1456 #
1457 # 5. The switch drops all packets with a multicast source address. (This only
1458 # affects behavior when port security is turned off, since otherwise port
1459 # security would drop the packet anyway.)
1460 #
1461 # 6. The switch delivers packets with an unknown destination to logical
1462 # switch ports with "unknown" among their MAC addresses (and port
1463 # security disabled).
1464 #
1465 # 7. The switch drops unicast packets that violate an ACL.
1466 #
1467 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1468 #
1469 # 9. OVN generates responses to ARP requests for known IPs, except for
1470 # requests from a port for the port's own IP.
1471 #
1472 # 10. No response to ARP requests for unknown IPs.
1473
1474 for is in 1 2 3; do
1475 for js in 1 2 3; do
1476 s=$is$js
1477 bcast=
1478 unknown=
1479 bacl2=
1480 bacl3=
1481 for id in 1 2 3; do
1482 for jd in 1 2 3; do
1483 d=$id$jd
1484
1485 if test $d != $s; then unicast=$d; else unicast=; fi
1486 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1487
1488 if test $d != $s && test $js = 1; then
1489 impersonate=$d
1490 else
1491 impersonate=
1492 fi
1493 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1494
1495 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1496 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1497 if test $d = $s || (test $js = 1 && test $d = 33); then
1498 # Source of 11, 21, or 31 and dest of 33 should be dropped
1499 # due to the 4th ACL that uses address_set(set1).
1500 acl4=
1501 else
1502 acl4=$d
1503 fi
1504 if test $d = $s || test $d = 22 || test $d = 33; then
1505 # dest of 22 and 33 should be dropped
1506 # due to the 5th ACL that uses port_group(pg1).
1507 acl5=
1508 else
1509 acl5=$d
1510 fi
1511 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1512 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1513 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1514 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1515 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
1516
1517 test_packet $s f000000000$d f00000000055 810000091234 #4
1518 test_packet $s f000000000$d 0100000000$s $s$d #5
1519
1520 if test $d != $s && test $jd = 1; then
1521 unknown="$unknown $d"
1522 fi
1523 bcast="$bcast $unicast"
1524 bacl2="$bacl2 $acl2"
1525 bacl3="$bacl3 $acl3"
1526
1527 sip=`ip_to_hex 192 168 0 $is$js`
1528 tip=`ip_to_hex 192 168 0 $id$jd`
1529 tip_unknown=`ip_to_hex 11 11 11 11`
1530 if test $d != $s; then
1531 reply_ha=f000000000$d
1532 else
1533 reply_ha=
1534 fi
1535 test_arp $s f000000000$s $sip $tip $reply_ha #9
1536 test_arp $s f000000000$s $sip $tip_unknown #10
1537
1538 if test $jd = 3; then
1539 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1540 tip=`ip_to_hex 192 169 0 $id$jd`
1541 test_arp $s f000000000$s $sip $tip $reply_ha #9
1542 fi
1543 done
1544 done
1545
1546 # Broadcast and multicast.
1547 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1548 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1549 if test $js = 1; then
1550 bcast_impersonate=$bcast
1551 else
1552 bcast_impersonate=
1553 fi
1554 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1555
1556 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1557
1558 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1559 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1560 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1561 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1562 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1563 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1564 done
1565 done
1566
1567 # set address for lp13 with invalid characters.
1568 # lp13 should be configured with only 192.168.0.13.
1569 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1570
1571 # Allow some time for ovn-northd and ovn-controller to catch up.
1572 # XXX This should be more systematic.
1573 sleep 1
1574
1575 sip=`ip_to_hex 192 168 0 11`
1576 tip=`ip_to_hex 192 168 0 13`
1577 test_arp 11 f00000000011 $sip $tip f00000000013
1578
1579 tip=`ip_to_hex 192 169 0 13`
1580 #arp request for 192.169.0.13 should be flooded
1581 test_arp 11 f00000000011 $sip $tip
1582
1583 # dump information and flows with counters
1584 ovn-sbctl dump-flows -- list multicast_group
1585
1586 echo "------ hv1 dump ------"
1587 as hv1 ovs-vsctl show
1588 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1589
1590 echo "------ hv2 dump ------"
1591 as hv2 ovs-vsctl show
1592 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1593
1594 echo "------ hv3 dump ------"
1595 as hv3 ovs-vsctl show
1596 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1597
1598 # Now check the packets actually received against the ones expected.
1599 for i in 1 2 3; do
1600 for j in 1 2 3; do
1601 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1602 done
1603 done
1604
1605 OVN_CLEANUP([hv1],[hv2],[hv3])
1606
1607 AT_CLEANUP
1608
1609 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1610 AT_SKIP_IF([test $HAVE_PYTHON = no])
1611 ovn_start
1612
1613 # Create a logical switch and some logical ports.
1614 # Turn on port security on all lports except ls1.
1615 # Make ls1 a destination for unknown MACs.
1616 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1617 ovn-nbctl ls-add lsw0
1618 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1619 for i in 1 2 3; do
1620 ovn-nbctl lsp-add lsw0 lp$i
1621 done
1622 ovn-nbctl --wait=sb sync
1623 for i in 1 2 3; do
1624 ovn-sbctl lsp-bind lp$i hv0
1625 if test $i = 1; then
1626 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1627 else
1628 if test $i = 3; then
1629 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1630 else
1631 ip_addrs="192.168.0.$i"
1632 fi
1633 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1634 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1635 fi
1636 done
1637 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1638 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1639 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1640 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1641 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1642
1643 ovn-nbctl --wait=sb sync
1644 on_exit 'kill `cat ovn-trace.pid`'
1645 ovn-trace --detach --pidfile --no-chdir
1646
1647 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1648 #
1649 # This shell function causes a packet to be received on INPORT. The packet's
1650 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1651 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1652 # more) list the VIFs on which the packet should be received. INPORT and the
1653 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1654 test_packet() {
1655 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1656 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1657 while :; do
1658 case $1 in # (
1659 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1660 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1661 *) break ;;
1662 esac
1663 done
1664 for outport; do
1665 echo "output(\"lp$outport\");"
1666 done > expout
1667
1668 AT_CAPTURE_FILE([trace])
1669 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1670 }
1671
1672 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1673 #
1674 # Causes a packet to be received on INPORT. The packet is an ARP
1675 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1676 # it should be the hardware address of the target to expect to receive in an
1677 # ARP reply; otherwise no reply is expected.
1678 #
1679 # INPORT is an logical switch port number, e.g. 11 for vif11.
1680 # SHA and REPLY_HA are each 12 hex digits.
1681 # SPA and TPA are each 8 hex digits.
1682 test_arp() {
1683 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1684
1685 local request="inport == \"lp$inport\"
1686 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1687 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1688 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1689
1690 if test -z "$reply_ha"; then
1691 reply=
1692 local i
1693 for i in 1 2 3; do
1694 if test $i != $inport; then
1695 reply="${reply}output(\"lp$i\");
1696 "
1697 fi
1698 done
1699 else
1700 reply="\
1701 eth.dst = $sha;
1702 eth.src = $reply_ha;
1703 arp.op = 2;
1704 arp.tha = $sha;
1705 arp.sha = $reply_ha;
1706 arp.tpa = $spa;
1707 arp.spa = $tpa;
1708 output(\"lp$inport\");
1709 "
1710 fi
1711
1712 AT_CAPTURE_FILE([trace])
1713 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1714 }
1715
1716 # Send packets between all pairs of source and destination ports:
1717 #
1718 # 1. Unicast packets are delivered to exactly one logical switch port
1719 # (except that packets destined to their input ports are dropped).
1720 #
1721 # 2. Broadcast and multicast are delivered to all logical switch ports
1722 # except the input port.
1723 #
1724 # 3. When port security is turned on, the switch drops packets from the wrong
1725 # MAC address.
1726 #
1727 # 4. The switch drops all packets with a VLAN tag.
1728 #
1729 # 5. The switch drops all packets with a multicast source address. (This only
1730 # affects behavior when port security is turned off, since otherwise port
1731 # security would drop the packet anyway.)
1732 #
1733 # 6. The switch delivers packets with an unknown destination to logical
1734 # switch ports with "unknown" among their MAC addresses (and port
1735 # security disabled).
1736 #
1737 # 7. The switch drops unicast packets that violate an ACL.
1738 #
1739 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1740 #
1741 # 9. OVN generates responses to ARP requests for known IPs, except for
1742 # requests from a port for the port's own IP.
1743 #
1744 # 10. No response to ARP requests for unknown IPs.
1745
1746 for s in 1 2 3; do
1747 bcast=
1748 unknown=
1749 bacl2=
1750 bacl3=
1751 for d in 1 2 3; do
1752 echo
1753 echo "lp$s -> lp$d"
1754 if test $d != $s; then unicast=$d; else unicast=; fi
1755 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1756
1757 if test $d != $s && test $s = 1; then
1758 impersonate=$d
1759 else
1760 impersonate=
1761 fi
1762 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1763
1764 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1765 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1766 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1767 # Source of 1 or 2 and dest of 3 should be dropped
1768 # due to the 4th ACL that uses address_set(set1).
1769 acl4=
1770 else
1771 acl4=$d
1772 fi
1773
1774 #7, acl1 to acl4:
1775 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1776 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1777 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1778 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1779
1780 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1781 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1782
1783 if test $d != $s && test $d = 1; then
1784 unknown="$unknown $d"
1785 fi
1786 bcast="$bcast $unicast"
1787 bacl2="$bacl2 $acl2"
1788 bacl3="$bacl3 $acl3"
1789
1790 sip=192.168.0.$s
1791 tip=192.168.0.$d
1792 tip_unknown=11.11.11.11
1793 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1794 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1795 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1796
1797 if test $d = 3; then
1798 # lp3 has an additional ip 192.169.0.[123]3.
1799 tip=192.169.0.$d
1800 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1801 fi
1802 done
1803
1804 # Broadcast and multicast.
1805 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1806 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1807 if test $s = 1; then
1808 bcast_impersonate=$bcast
1809 else
1810 bcast_impersonate=
1811 fi
1812 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1813
1814 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1815
1816 #8, acl1 to acl3:
1817 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1818 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1819 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1820
1821 #8, acl1 to acl3:
1822 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1823 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1824 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1825 done
1826
1827 AT_CLEANUP
1828
1829 # 2 hypervisors, 4 logical ports per HV
1830 # 2 locally attached networks (one flat, one vlan tagged over same device)
1831 # 2 ports per HV on each network
1832 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1833 AT_SKIP_IF([test $HAVE_PYTHON = no])
1834 ovn_start
1835
1836 # In this test cases we create 3 switches, all connected to same
1837 # physical network (through br-phys on each HV). Each switch has
1838 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1839 # of VIF port name indicates the hypervisor it is bound to, e.g.
1840 # lp23 means VIF 3 on hv2.
1841 #
1842 # Each switch's VLAN tag and their logical switch ports are:
1843 # - ls1:
1844 # - untagged
1845 # - ports: lp11, lp12, lp21, lp22
1846 #
1847 # - ls2:
1848 # - tagged with VLAN 101
1849 # - ports: lp13, lp14, lp23, lp24
1850 # - ls3:
1851 # - untagged
1852 # - ports: lp15, lp25
1853 #
1854 # Note: a localnet port is created for each switch to connect to
1855 # physical network.
1856
1857 for i in 1 2 3; do
1858 ls_name=ls$i
1859 ovn-nbctl ls-add $ls_name
1860 ln_port_name=ln$i
1861 if test $i -eq 2; then
1862 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1863 else
1864 ovn-nbctl lsp-add $ls_name $ln_port_name
1865 fi
1866 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1867 ovn-nbctl lsp-set-type $ln_port_name localnet
1868 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1869 done
1870
1871 # lsp_to_ls LSP
1872 #
1873 # Prints the name of the logical switch that contains LSP.
1874 lsp_to_ls () {
1875 case $1 in dnl (
1876 lp?[[12]]) echo ls1 ;; dnl (
1877 lp?[[34]]) echo ls2 ;; dnl (
1878 lp?5) echo ls3 ;; dnl (
1879 *) AT_FAIL_IF([:]) ;;
1880 esac
1881 }
1882
1883 net_add n1
1884 for i in 1 2; do
1885 sim_add hv$i
1886 as hv$i
1887 ovs-vsctl add-br br-phys
1888 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1889 ovn_attach n1 br-phys 192.168.0.$i
1890
1891 for j in 1 2 3 4 5; do
1892 ovs-vsctl add-port br-int vif$i$j -- \
1893 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1894 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1895 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1896 ofport-request=$i$j
1897
1898 lsp_name=lp$i$j
1899 ls_name=$(lsp_to_ls $lsp_name)
1900
1901 ovn-nbctl lsp-add $ls_name $lsp_name
1902 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1903 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1904
1905 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1906 done
1907 done
1908 ovn-nbctl --wait=sb sync
1909 ovn-sbctl dump-flows
1910
1911 OVN_POPULATE_ARP
1912
1913 # XXX This is now the 3rd copy of these functions in this file ...
1914
1915 # Given the name of a logical port, prints the name of the hypervisor
1916 # on which it is located.
1917 vif_to_hv() {
1918 echo hv${1%?}
1919 }
1920 #
1921 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1922 #
1923 # This shell function causes a packet to be received on INPORT. The packet's
1924 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1925 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1926 # logical switch port numbers, e.g. 11 for vif11.
1927 #
1928 # EOUT is the end-to-end output port, that is, where the packet will end up
1929 # after possibly bouncing through one or more localnet ports. LOUT is the
1930 # logical output port, which might be a localnet port, as seen by ovn-trace
1931 # (which doesn't know what localnet ports are connected to and therefore can't
1932 # figure out the end-to-end answer).
1933 for i in 1 2; do
1934 for j in 1 2 3 4 5; do
1935 : > $i$j.expected
1936 done
1937 done
1938 test_packet() {
1939 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1940 echo "$@"
1941
1942 # First try tracing the packet.
1943 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1944 if test $lout != drop; then
1945 echo "output(\"$lout\");"
1946 fi > expout
1947 AT_CAPTURE_FILE([trace])
1948 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1949
1950 # Then actually send a packet, for an end-to-end test.
1951 local packet=$(echo $dst$src | sed 's/://g')${eth}
1952 hv=`vif_to_hv $inport`
1953 vif=vif$inport
1954 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1955 if test $eout != drop; then
1956 echo $packet >> ${eout#lp}.expected
1957 fi
1958 }
1959
1960 # lp11 and lp21 are on the same network (phys, untagged)
1961 # and on different hypervisors
1962 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1963 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1964
1965 # lp11 and lp12 are on the same network (phys, untagged)
1966 # and on the same hypervisor
1967 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1968 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1969
1970 # lp13 and lp23 are on the same network (phys, VLAN 101)
1971 # and on different hypervisors
1972 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1973 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1974
1975 # lp13 and lp14 are on the same network (phys, VLAN 101)
1976 # and on the same hypervisor
1977 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1978 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1979
1980 # lp11 and lp15 are on the same network (phys, untagged),
1981 # same hypervisor, and on different switches
1982 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1983 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1984
1985 # lp11 and lp25 are on the same network (phys, untagged),
1986 # different hypervisors, and on different switches
1987 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1988 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1989
1990 # Ports that should not be able to communicate
1991 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1992 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1993 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1994 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1995 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1996 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1997 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1998 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
1999
2000 # Dump a bunch of info helpful for debugging if there's a failure.
2001
2002 echo "------ OVN dump ------"
2003 ovn-nbctl show
2004 ovn-sbctl show
2005
2006 echo "------ hv1 dump ------"
2007 as hv1 ovs-vsctl show
2008 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2009
2010 echo "------ hv2 dump ------"
2011 as hv2 ovs-vsctl show
2012 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2013
2014 # Now check the packets actually received against the ones expected.
2015 for i in 1 2; do
2016 for j in 1 2 3 4 5; do
2017 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2018 done
2019 done
2020
2021 OVN_CLEANUP([hv1],[hv2])
2022
2023 AT_CLEANUP
2024
2025 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2026 AT_KEYWORDS([vtep])
2027 AT_SKIP_IF([test $HAVE_PYTHON = no])
2028 ovn_start
2029
2030 # Configure the Northbound database
2031 ovn-nbctl ls-add lsw0
2032
2033 ovn-nbctl lsp-add lsw0 lp1
2034 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2035
2036 ovn-nbctl lsp-add lsw0 lp2
2037 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2038
2039 ovn-nbctl lsp-add lsw0 lp-vtep
2040 ovn-nbctl lsp-set-type lp-vtep vtep
2041 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2042 ovn-nbctl lsp-set-addresses lp-vtep unknown
2043
2044 # lpr, lr and lrp1 are used for the ARP request handling test only.
2045 ovn-nbctl lsp-add lsw0 lpr
2046 ovn-nbctl lr-add lr
2047 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2048 ovn-nbctl set Logical_Switch_Port lpr type=router \
2049 options:router-port=lrp1 \
2050 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2051
2052
2053 net_add n1 # Network to connect hv1, hv2, and vtep
2054 net_add n2 # Network to connect vtep and hv3
2055
2056 # Create hypervisor hv1 connected to n1
2057 sim_add hv1
2058 as hv1
2059 ovs-vsctl add-br br-phys
2060 ovn_attach n1 br-phys 192.168.0.1
2061 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
2062
2063 # Create hypervisor hv2 connected to n1
2064 sim_add hv2
2065 as hv2
2066 ovs-vsctl add-br br-phys
2067 ovn_attach n1 br-phys 192.168.0.2
2068 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
2069
2070
2071 # Start the vtep emulator with a leg in both networks
2072 sim_add vtep
2073 as vtep
2074
2075 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2076 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2077
2078 ovs-vsctl add-br br-phys
2079 net_attach n1 br-phys
2080
2081 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2082 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2083 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2084 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2085
2086 ovs-vsctl add-br br-vtep
2087 net_attach n2 br-vtep
2088
2089 vtep-ctl add-ps br-vtep
2090 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2091 vtep-ctl add-ls lsw0
2092
2093 start_daemon ovs-vtep br-vtep
2094 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2095
2096 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
2097
2098 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2099 grep -- source`"])
2100 # It takes more time for the update to be processed by ovs-vtep.
2101 sleep 1
2102
2103 # Add hv3 on the other side of the vtep
2104 sim_add hv3
2105 as hv3
2106 ovs-vsctl add-br br-phys
2107 net_attach n2 br-phys
2108
2109 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
2110
2111 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2112 # packets for ARP resolution (native tunneling doesn't queue packets
2113 # for ARP resolution).
2114 OVN_POPULATE_ARP
2115
2116 # Allow some time for ovn-northd and ovn-controller to catch up.
2117 # XXX This should be more systematic.
2118 sleep 1
2119
2120 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2121 #
2122 # This shell function causes a packet to be received on INPORT. The packet's
2123 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2124 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2125 # more) list the VIFs on which the packet should be received. INPORT and the
2126 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
2127 for i in 1 2 3; do
2128 : > $i.expected
2129 done
2130 test_packet() {
2131 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2132 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2133 hv=hv$inport
2134 vif=vif$inport
2135 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2136 for outport; do
2137 echo $packet >> $outport.expected
2138 done
2139 }
2140
2141 # Send packets between all pairs of source and destination ports:
2142 #
2143 # 1. Unicast packets are delivered to exactly one logical switch port
2144 # (except that packets destined to their input ports are dropped).
2145 #
2146 # 2. Broadcast and multicast are delivered to all logical switch ports
2147 # except the input port.
2148 #
2149 # 3. The switch delivers packets with an unknown destination to logical
2150 # switch ports with "unknown" among their MAC addresses (and port
2151 # security disabled).
2152 for s in 1 2 3; do
2153 bcast=
2154 unknown=
2155 for d in 1 2 3; do
2156 if test $d != $s; then unicast=$d; else unicast=; fi
2157 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2158
2159 # The vtep (vif3) is the only one configured for "unknown"
2160 if test $d != $s && test $d = 3; then
2161 unknown="$unknown $d"
2162 fi
2163 bcast="$bcast $unicast"
2164 done
2165
2166 # Broadcast and multicast.
2167 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2168 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2169
2170 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2171 done
2172
2173 # ARP request should not be responded to by logical switch router
2174 # type arp responder on HV1 and HV2 and should reach directly to
2175 # vif1 and vif2
2176 ip_to_hex() {
2177 printf "%02x%02x%02x%02x" "$@"
2178 }
2179 sha=f00000000003
2180 spa=`ip_to_hex 192 168 1 2`
2181 tpa=`ip_to_hex 192 168 1 1`
2182 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2183 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2184 echo $request >> 1.expected
2185 echo $request >> 2.expected
2186
2187 # dump information with counters
2188 echo "------ OVN dump ------"
2189 ovn-nbctl show
2190 ovn-sbctl show
2191
2192 echo "---------SB dump-----"
2193 ovn-sbctl list datapath_binding
2194 echo "---------------------"
2195 ovn-sbctl list port_binding
2196 echo "---------------------"
2197 ovn-sbctl dump-flows
2198
2199 echo "------ hv1 dump ------"
2200 as hv1 ovs-vsctl show
2201 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2202 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2203
2204 echo "------ hv2 dump ------"
2205 as hv2 ovs-vsctl show
2206 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2207 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2208
2209 echo "------ hv3 dump ------"
2210 as hv3 ovs-vsctl show
2211 # note: hv3 has no logical port bind, thus it should not have br-int
2212 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2213 [ovs-ofctl: br-int is not a bridge or a socket
2214 ])
2215
2216 # Now check the packets actually received against the ones expected.
2217 for i in 1 2 3; do
2218 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2219 done
2220
2221 # Gracefully terminate daemons
2222 OVN_CLEANUP([hv1],[hv2],[vtep])
2223 OVN_CLEANUP_VSWITCH([hv3])
2224
2225 AT_CLEANUP
2226
2227 # Similar test to "hardware GW"
2228 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2229 AT_SKIP_IF([test $HAVE_PYTHON = no])
2230 ovn_start
2231
2232 # Configure the Northbound database
2233 ovn-nbctl ls-add lsw0
2234
2235 ovn-nbctl lsp-add lsw0 lp1
2236 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2237
2238 ovn-nbctl lsp-add lsw0 lp2
2239 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2240
2241 ovn-nbctl lsp-add lsw0 lp-gw
2242 ovn-nbctl lsp-set-type lp-gw l2gateway
2243 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2244 ovn-nbctl lsp-set-addresses lp-gw unknown
2245
2246 net_add n1 # Network to connect hv1, hv2, and gw
2247 net_add n2 # Network to connect gw and hv3
2248
2249 # Create hypervisor hv1 connected to n1
2250 sim_add hv1
2251 as hv1
2252 ovs-vsctl add-br br-phys
2253 ovn_attach n1 br-phys 192.168.0.1
2254 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
2255
2256 # Create hypervisor hv2 connected to n1
2257 sim_add hv2
2258 as hv2
2259 ovs-vsctl add-br br-phys
2260 ovn_attach n1 br-phys 192.168.0.2
2261 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
2262
2263 # Create hypervisor hv_gw connected to n1 and n2
2264 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2265 sim_add hv_gw
2266 as hv_gw
2267 ovs-vsctl add-br br-phys
2268 ovn_attach n1 br-phys 192.168.0.3
2269 ovs-vsctl add-br br-phys2
2270 net_attach n2 br-phys2
2271 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2272
2273 # Add hv3 on the other side of the GW
2274 sim_add hv3
2275 as hv3
2276 ovs-vsctl add-br br-phys
2277 net_attach n2 br-phys
2278 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
2279
2280
2281 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2282 # packets for ARP resolution (native tunneling doesn't queue packets
2283 # for ARP resolution).
2284 OVN_POPULATE_ARP
2285
2286 # Allow some time for ovn-northd and ovn-controller to catch up.
2287 # XXX This should be more systematic.
2288 sleep 1
2289
2290 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2291 #
2292 # This shell function causes a packet to be received on INPORT. The packet's
2293 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2294 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2295 # more) list the VIFs on which the packet should be received. INPORT and the
2296 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2297 for i in 1 2 3; do
2298 : > $i.expected
2299 done
2300 test_packet() {
2301 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2302 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2303 hv=hv$inport
2304 vif=vif$inport
2305 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2306 for outport; do
2307 echo $packet >> $outport.expected
2308 done
2309 }
2310
2311 # Send packets between all pairs of source and destination ports:
2312 #
2313 # 1. Unicast packets are delivered to exactly one lport (except that packets
2314 # destined to their input ports are dropped).
2315 #
2316 # 2. Broadcast and multicast are delivered to all lports except the input port.
2317 #
2318 # 3. The lswitch delivers packets with an unknown destination to lports with
2319 # "unknown" among their MAC addresses (and port security disabled).
2320 for s in 1 2 3 ; do
2321 bcast=
2322 unknown=
2323 for d in 1 2 3 ; do
2324 if test $d != $s; then unicast=$d; else unicast=; fi
2325 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2326
2327 # The vtep (vif3) is the only one configured for "unknown"
2328 if test $d != $s && test $d = 3; then
2329 unknown="$unknown $d"
2330 fi
2331 bcast="$bcast $unicast"
2332 done
2333
2334 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2335 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2336 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2337 done
2338
2339 echo "------ ovn-nbctl show ------"
2340 ovn-nbctl show
2341 echo "------ ovn-sbctl show ------"
2342 ovn-sbctl show
2343
2344 echo "------ hv1 ------"
2345 as hv1 ovs-vsctl show
2346 echo "------ hv1 br-int ------"
2347 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2348 echo "------ hv1 br-phys ------"
2349 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2350
2351 echo "------ hv2 ------"
2352 as hv2 ovs-vsctl show
2353 echo "------ hv2 br-int ------"
2354 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2355 echo "------ hv2 br-phys ------"
2356 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2357
2358 echo "------ hv_gw ------"
2359 as hv_gw ovs-vsctl show
2360 echo "------ hv_gw br-phys ------"
2361 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2362 echo "------ hv_gw br-phys2 ------"
2363 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2364
2365 echo "------ hv3 ------"
2366 as hv3 ovs-vsctl show
2367 echo "------ hv3 br-phys ------"
2368 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2369
2370 # Now check the packets actually received against the ones expected.
2371 for i in 1 2 3; do
2372 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2373 done
2374 AT_CLEANUP
2375
2376 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2377 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2378 AT_SKIP_IF([test $HAVE_PYTHON = no])
2379 ovn_start
2380
2381 # Logical network:
2382 #
2383 # Three logical switches ls1, ls2, ls3.
2384 # One logical router lr0 connected to ls[123],
2385 # with nine subnets, three per logical switch:
2386 #
2387 # lrp11 on ls1 for subnet 192.168.11.0/24
2388 # lrp12 on ls1 for subnet 192.168.12.0/24
2389 # lrp13 on ls1 for subnet 192.168.13.0/24
2390 # ...
2391 # lrp33 on ls3 for subnet 192.168.33.0/24
2392 #
2393 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2394 # digits are the subnet and the last digit distinguishes the VIF.
2395 for i in 1 2 3; do
2396 ovn-nbctl ls-add ls$i
2397 for j in 1 2 3; do
2398 for k in 1 2 3; do
2399 # Add "unknown" to MAC addresses for lp?11, so packets for
2400 # MAC-IP bindings discovered via ARP later have somewhere to go.
2401 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2402
2403 ovn-nbctl \
2404 -- lsp-add ls$i lp$i$j$k \
2405 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2406 192.168.$i$j.$k" $unknown
2407 done
2408 done
2409 done
2410
2411 ovn-nbctl lr-add lr0
2412 for i in 1 2 3; do
2413 for j in 1 2 3; do
2414 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2415 ovn-nbctl \
2416 -- lsp-add ls$i lrp$i$j-attachment \
2417 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2418 options:router-port=lrp$i$j \
2419 addresses='"00:00:00:00:ff:'$i$j'"'
2420 done
2421 done
2422
2423 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2424 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2425
2426 # Physical network:
2427 #
2428 # Three hypervisors hv[123].
2429 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2430 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2431 # lp?3[123] all on hv3.
2432
2433
2434 # Given the name of a logical port, prints the name of the hypervisor
2435 # on which it is located.
2436 vif_to_hv() {
2437 case $1 in dnl (
2438 ?11) echo 1 ;; dnl (
2439 ?12 | ?21 | ?22) echo 2 ;; dnl (
2440 ?13 | ?23 | ?3?) echo 3 ;;
2441 esac
2442 }
2443
2444 # Given the name of a logical port, prints the name of its logical router
2445 # port, e.g. "vif_to_lrp 123" yields 12.
2446 vif_to_lrp() {
2447 echo ${1%?}
2448 }
2449
2450 # Given the name of a logical port, prints the name of its logical
2451 # switch, e.g. "vif_to_ls 123" yields 1.
2452 vif_to_ls() {
2453 echo ${1%??}
2454 }
2455
2456 net_add n1
2457 for i in 1 2 3; do
2458 sim_add hv$i
2459 as hv$i
2460 ovs-vsctl add-br br-phys
2461 ovn_attach n1 br-phys 192.168.0.$i
2462 done
2463 for i in 1 2 3; do
2464 for j in 1 2 3; do
2465 for k in 1 2 3; do
2466 hv=`vif_to_hv $i$j$k`
2467 as hv$hv ovs-vsctl \
2468 -- add-port br-int vif$i$j$k \
2469 -- set Interface vif$i$j$k \
2470 external-ids:iface-id=lp$i$j$k \
2471 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2472 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2473 ofport-request=$i$j$k
2474 done
2475 done
2476 done
2477
2478 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2479 # packets for ARP resolution (native tunneling doesn't queue packets
2480 # for ARP resolution).
2481 OVN_POPULATE_ARP
2482
2483 # Allow some time for ovn-northd and ovn-controller to catch up.
2484 # XXX This should be more systematic.
2485 sleep 1
2486
2487 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2488 #
2489 # This shell function causes a packet to be received on INPORT. The packet's
2490 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2491 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2492 # more) list the VIFs on which the packet should be received. INPORT and the
2493 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2494 for i in 1 2 3; do
2495 for j in 1 2 3; do
2496 for k in 1 2 3; do
2497 : > $i$j$k.expected
2498 done
2499 done
2500 done
2501 test_ip() {
2502 # This packet has bad checksums but logical L3 routing doesn't check.
2503 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2504 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2505 shift; shift; shift; shift; shift
2506 hv=hv`vif_to_hv $inport`
2507 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2508 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2509 in_ls=`vif_to_ls $inport`
2510 in_lrp=`vif_to_lrp $inport`
2511 for outport; do
2512 out_ls=`vif_to_ls $outport`
2513 if test $in_ls = $out_ls; then
2514 # Ports on the same logical switch receive exactly the same packet.
2515 echo $packet
2516 else
2517 # Routing decrements TTL and updates source and dest MAC
2518 # (and checksum).
2519 out_lrp=`vif_to_lrp $outport`
2520 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2521 fi >> $outport.expected
2522 done
2523 }
2524
2525 as hv1 ovs-vsctl --columns=name,ofport list interface
2526 as hv1 ovn-sbctl list port_binding
2527 as hv1 ovn-sbctl list datapath_binding
2528 as hv1 ovn-sbctl dump-flows
2529 as hv1 ovs-ofctl dump-flows br-int
2530
2531 # Send IP packets between all pairs of source and destination ports:
2532 #
2533 # 1. Unicast IP packets are delivered to exactly one logical switch port
2534 # (except that packets destined to their input ports are dropped).
2535 #
2536 # 2. Broadcast IP packets are delivered to all logical switch ports
2537 # except the input port.
2538 ip_to_hex() {
2539 printf "%02x%02x%02x%02x" "$@"
2540 }
2541 for is in 1 2 3; do
2542 for js in 1 2 3; do
2543 for ks in 1 2 3; do
2544 bcast=
2545 s=$is$js$ks
2546 smac=f00000000$s
2547 sip=`ip_to_hex 192 168 $is$js $ks`
2548 for id in 1 2 3; do
2549 for jd in 1 2 3; do
2550 for kd in 1 2 3; do
2551 d=$id$jd$kd
2552 dip=`ip_to_hex 192 168 $id$jd $kd`
2553 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2554 if test $d != $s; then unicast=$d; else unicast=; fi
2555
2556 test_ip $s $smac $dmac $sip $dip $unicast #1
2557
2558 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2559 done
2560 done
2561 done
2562 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2563 done
2564 done
2565 done
2566
2567 # 3. Send an IP packet from every logical port to every other subnet,
2568 # to an IP address that does not have a static IP-MAC binding.
2569 # This should generate a broadcast ARP request for the destination
2570 # IP address in the destination subnet.
2571 for is in 1 2 3; do
2572 for js in 1 2 3; do
2573 for ks in 1 2 3; do
2574 s=$is$js$ks
2575 smac=f00000000$s
2576 sip=`ip_to_hex 192 168 $is$js $ks`
2577 for id in 1 2 3; do
2578 for jd in 1 2 3; do
2579 if test $is$js = $id$jd; then
2580 continue
2581 fi
2582
2583 # Send the packet.
2584 dmac=00000000ff$is$js
2585 # Calculate a 4th octet for the destination that is
2586 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2587 # that have static MAC bindings, and fits in the range
2588 # 0-255.
2589 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2590 dip=`ip_to_hex 192 168 $id$jd $o4`
2591 test_ip $s $smac $dmac $sip $dip
2592
2593 # Every LP on the destination subnet's lswitch should
2594 # receive the ARP request.
2595 lrmac=00000000ff$id$jd
2596 lrip=`ip_to_hex 192 168 $id$jd 254`
2597 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2598 for jd2 in 1 2 3; do
2599 for kd in 1 2 3; do
2600 echo $arp >> $id$jd2$kd.expected
2601 done
2602 done
2603 done
2604 done
2605 done
2606 done
2607 done
2608
2609 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2610 #
2611 # Causes a packet to be received on INPORT. The packet is an ARP
2612 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2613 # it should be the hardware address of the target to expect to receive in an
2614 # ARP reply; otherwise no reply is expected.
2615 #
2616 # INPORT is an logical switch port number, e.g. 11 for vif11.
2617 # SHA and REPLY_HA are each 12 hex digits.
2618 # SPA and TPA are each 8 hex digits.
2619 test_arp() {
2620 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2621 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2622 hv=hv`vif_to_hv $inport`
2623 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2624 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2625
2626 # Expect to receive the broadcast ARP on the other logical switch ports if
2627 # IP address is not configured to the switch patch port.
2628 local i=`vif_to_ls $inport`
2629 local j k
2630 for j in 1 2 3; do
2631 for k in 1 2 3; do
2632 # 192.168.33.254 is configured to the switch patch port for lrp33,
2633 # so no ARP flooding expected for it.
2634 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2635 echo $request >> $i$j$k.expected
2636 fi
2637 done
2638 done
2639
2640 # Expect to receive the reply, if any.
2641 if test X$reply_ha != X; then
2642 lrp=`vif_to_lrp $inport`
2643 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2644 echo $reply >> $inport.expected
2645 fi
2646 }
2647
2648 # Test router replies to ARP requests from all source ports:
2649 #
2650 # 4. Router replies to query for its MAC address from port's own IP address.
2651 #
2652 # 5. Router replies to query for its MAC address from any random IP address
2653 # in its subnet.
2654 #
2655 # 6. Router replies to query for its MAC address from another subnet.
2656 #
2657 # 7. No reply to query for IP address other than router IP.
2658 for i in 1 2 3; do
2659 for j in 1 2 3; do
2660 for k in 1 2 3; do
2661 smac=f00000000$i$j$k # Source MAC
2662 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2663 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2664 rmac=00000000ff$i$j # Router MAC
2665 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2666 test_arp $i$j$k $smac $sip $rip $rmac #4
2667 test_arp $i$j$k $smac $otherip $rip $rmac #5
2668 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2669 test_arp $i$j$k $smac $sip $otherip #7
2670 done
2671 done
2672 done
2673
2674 # Allow some time for packet forwarding.
2675 # XXX This can be improved.
2676 sleep 1
2677
2678 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2679 # earlier as #3.
2680 #
2681 # Here, the $s is the VIF that originated the ARP request and $d is
2682 # the VIF that sends the ARP reply, which is somewhat backward but
2683 # it means that $s and $d are the same as #3.
2684 : > mac_bindings.expected
2685 for is in 1 2 3; do
2686 for js in 1 2 3; do
2687 for ks in 1 2 3; do
2688 s=$is$js$ks
2689 for id in 1 2 3; do
2690 for jd in 1 2 3; do
2691 if test $is$js = $id$jd; then
2692 continue
2693 fi
2694
2695 kd=1
2696 d=$id$jd$kd
2697
2698 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2699 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2700 host_mac=8000000000$o4
2701
2702 lrmac=00000000ff$id$jd
2703 lrip=`ip_to_hex 192 168 $id$jd 254`
2704
2705 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2706
2707 echo
2708 echo
2709 echo
2710 hv=hv`vif_to_hv $d`
2711 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2712 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2713 #as $hv ovs-ofctl dump-flows br-int table=19
2714
2715 host_ip_pretty=192.168.$id$jd.$o4
2716 host_mac_pretty=80:00:00:00:00:$o4
2717 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2718 done
2719 done
2720 done
2721 done
2722 done
2723
2724 # Allow some time for packet forwarding.
2725 # XXX This can be improved.
2726 sleep 1
2727
2728 # 9. Send an IP packet from every logical port to every other subnet. These
2729 # are the same packets already sent as #3, but now the destinations' IP-MAC
2730 # bindings have been discovered via ARP, so instead of provoking an ARP
2731 # request, these packets now get routed to their destinations (which don't
2732 # have static MAC bindings, so they go to the port we've designated as
2733 # accepting "unknown" MACs.)
2734 for is in 1 2 3; do
2735 for js in 1 2 3; do
2736 for ks in 1 2 3; do
2737 s=$is$js$ks
2738 smac=f00000000$s
2739 sip=`ip_to_hex 192 168 $is$js $ks`
2740 for id in 1 2 3; do
2741 for jd in 1 2 3; do
2742 if test $is$js = $id$jd; then
2743 continue
2744 fi
2745
2746 # Send the packet.
2747 dmac=00000000ff$is$js
2748 # Calculate a 4th octet for the destination that is
2749 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2750 # that have static MAC bindings, and fits in the range
2751 # 0-255.
2752 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2753 dip=`ip_to_hex 192 168 $id$jd $o4`
2754 test_ip $s $smac $dmac $sip $dip
2755
2756 # Expect the packet egress.
2757 host_mac=8000000000$o4
2758 outport=${id}11
2759 out_lrp=$id$jd
2760 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2761 done
2762 done
2763 done
2764 done
2765 done
2766
2767 ovn-sbctl -f csv -d bare --no-heading \
2768 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2769
2770 # Now check the packets actually received against the ones expected.
2771 for i in 1 2 3; do
2772 for j in 1 2 3; do
2773 for k in 1 2 3; do
2774 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2775 [$i$j$k.expected])
2776 done
2777 done
2778 done
2779
2780 # Check the MAC bindings against those expected.
2781 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2782 ])
2783
2784 # Gracefully terminate daemons
2785 OVN_CLEANUP([hv1], [hv2], [hv3])
2786
2787 AT_CLEANUP
2788
2789 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2790 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2791 AT_SKIP_IF([test $HAVE_PYTHON = no])
2792 ovn_start
2793
2794 # Create hypervisors hv[123].
2795 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2796 # Add all of the vifs to a single logical switch lsw0.
2797 # Turn off port security on vifs vif[123]1
2798 # Turn on l2 port security on vifs vif[123]2
2799 # Turn of l2 and l3 port security on vifs vif[123]3
2800 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2801 ovn-nbctl ls-add lsw0
2802 net_add n1
2803 for i in 1 2 3; do
2804 sim_add hv$i
2805 as hv$i
2806 ovs-vsctl add-br br-phys
2807 ovn_attach n1 br-phys 192.168.0.$i
2808
2809 for j in 1 2 3; do
2810 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
2811 ovn-nbctl lsp-add lsw0 lp$i$j
2812 if test $j = 1; then
2813 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2814 elif test $j = 2; then
2815 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2816 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2817 else
2818 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2819 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2820 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2821 fi
2822 done
2823 done
2824
2825 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2826 # packets for ARP resolution (native tunneling doesn't queue packets
2827 # for ARP resolution).
2828 OVN_POPULATE_ARP
2829
2830 # Allow some time for ovn-northd and ovn-controller to catch up.
2831 # XXX This should be more systematic.
2832 sleep 1
2833
2834 # Given the name of a logical port, prints the name of the hypervisor
2835 # on which it is located.
2836 vif_to_hv() {
2837 echo hv${1%?}
2838 }
2839
2840 for i in 1 2 3; do
2841 for j in 1 2 3; do
2842 : > $i$j.expected
2843 done
2844 done
2845
2846 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2847 #
2848 # This shell function causes an ip packet to be received on INPORT.
2849 # The packet's content has Ethernet destination DST and source SRC
2850 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2851 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2852 # be received. INPORT and the OUTPORTs are specified as logical switch
2853 # port numbers, e.g. 11 for vif11.
2854 test_ip() {
2855 # This packet has bad checksums but logical L3 routing doesn't check.
2856 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2857 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2858 shift; shift; shift; shift; shift
2859 hv=`vif_to_hv $inport`
2860 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2861 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2862 for outport; do
2863 echo $packet >> $outport.expected
2864 done
2865 }
2866
2867 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2868 #
2869 # Causes a packet to be received on INPORT. The packet is an ARP
2870 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2871 # it should be the hardware address of the target to expect to receive in an
2872 # ARP reply; otherwise no reply is expected.
2873 #
2874 # INPORT is an logical switch port number, e.g. 11 for vif11.
2875 # SHA and REPLY_HA are each 12 hex digits.
2876 # SPA and TPA are each 8 hex digits.
2877 test_arp() {
2878 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2879 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2880 hv=`vif_to_hv $inport`
2881 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2882 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2883 if test $drop != 1; then
2884 if test X$reply_ha = X; then
2885 # Expect to receive the broadcast ARP on the other logical switch ports
2886 # if no reply is expected.
2887 local i j
2888 for i in 1 2 3; do
2889 for j in 1 2 3; do
2890 if test $i$j != $inport; then
2891 echo $request >> $i$j.expected
2892 fi
2893 done
2894 done
2895 else
2896 # Expect to receive the reply, if any.
2897 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2898 echo $reply >> $inport.expected
2899 fi
2900 fi
2901 }
2902
2903 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2904 # This function is similar to test_ip() except that it sends
2905 # ipv6 packet
2906 test_ipv6() {
2907 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2908 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2909 shift; shift; shift; shift; shift
2910 hv=`vif_to_hv $inport`
2911 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2912 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2913 for outport; do
2914 echo $packet >> $outport.expected
2915 done
2916 }
2917
2918 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2919 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2920 # of the test packet
2921 test_icmpv6() {
2922 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2923 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2924 shift; shift; shift; shift; shift; shift
2925 hv=`vif_to_hv $inport`
2926 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2927 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2928 for outport; do
2929 echo $packet >> $outport.expected
2930 done
2931 }
2932
2933 ip_to_hex() {
2934 printf "%02x%02x%02x%02x" "$@"
2935 }
2936
2937 # no port security
2938 sip=`ip_to_hex 192 168 0 12`
2939 tip=`ip_to_hex 192 168 0 13`
2940 # the arp packet should be allowed even if lp[123]1 is
2941 # not configured with mac f00000000023 and ip 192.168.0.12
2942 for i in 1 2 3; do
2943 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2944 for j in 1 2 3; do
2945 if test $i != $j; then
2946 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2947 fi
2948 done
2949 done
2950
2951 # l2 port security
2952 sip=`ip_to_hex 192 168 0 12`
2953 tip=`ip_to_hex 192 168 0 13`
2954
2955 # arp packet should be allowed since lp22 is configured with
2956 # mac f00000000022
2957 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2958
2959 # arp packet should not be allowed since lp32 is not configured with
2960 # mac f00000000021
2961 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2962
2963 # arp packet with sha set to f00000000021 should not be allowed
2964 # for lp12
2965 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2966
2967 # ip packets should be allowed and received since lp[123]2 do not
2968 # have l3 port security
2969 sip=`ip_to_hex 192 168 0 55`
2970 tip=`ip_to_hex 192 168 0 66`
2971 for i in 1 2 3; do
2972 for j in 1 2 3; do
2973 if test $i != $j; then
2974 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2975 fi
2976 done
2977 done
2978
2979 # ipv6 packets should be received by lp[123]2
2980 # lp[123]1 can send ipv6 traffic as there is no port security
2981 sip=fe800000000000000000000000000000
2982 tip=ff020000000000000000000000000000
2983
2984 for i in 1 2 3; do
2985 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2986 done
2987
2988
2989 # l2 and l3 port security
2990 sip=`ip_to_hex 192 168 0 13`
2991 tip=`ip_to_hex 192 168 0 22`
2992 # arp packet should be allowed since lp13 is configured with
2993 # f00000000013 and 192.168.0.13
2994 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2995
2996 # the arp packet should be dropped because lp23 is not configured
2997 # with mac f00000000022
2998 sip=`ip_to_hex 192 168 0 13`
2999 tip=`ip_to_hex 192 168 0 22`
3000 test_arp 23 f00000000022 f00000000022 $sip $tip 1
3001
3002 # the arp packet should be dropped because lp33 is not configured
3003 # with ip 192.168.0.55
3004 spa=`ip_to_hex 192 168 0 55`
3005 tpa=`ip_to_hex 192 168 0 22`
3006 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3007
3008 # ip packets should not be received by lp[123]3 since
3009 # l3 port security is enabled
3010 sip=`ip_to_hex 192 168 0 55`
3011 tip=`ip_to_hex 192 168 0 66`
3012 for i in 1 2 3; do
3013 for j in 1 2 3; do
3014 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3015 done
3016 done
3017
3018 # ipv6 packets should be dropped for lp[123]3 since
3019 # it is configured with only ipv4 address
3020 sip=fe800000000000000000000000000000
3021 tip=ff020000000000000000000000000000
3022
3023 for i in 1 2 3; do
3024 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3025 done
3026
3027 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3028 # lp[123]1 can send ipv6 traffic as there is no port security
3029 for i in 1 2 3; do
3030 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3031 done
3032
3033 # lp13 has extra port security with mac f0000000113 and ipv6 addr
3034 # fe80::ea2a:eaff:fe28:0012
3035
3036 # ipv4 packet should be dropped for lp13 with mac f0000000113
3037 sip=`ip_to_hex 192 168 0 13`
3038 tip=`ip_to_hex 192 168 0 23`
3039 test_ip 13 f00000000113 f00000000023 $sip $tip
3040
3041 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3042 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
3043 # lp11 can send ipv6 traffic as there is no port security
3044 sip=ee800000000000000000000000000000
3045 for i in 1 2 3; do
3046 tip=fe80000000000000ea2aeafffe2800${i}3
3047 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
3048 done
3049
3050
3051 # ipv6 packet should not be received by lp33 with mac f0000000333
3052 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3053 # configured with fe80::ea2a:eaff:fe28:0033
3054 # lp11 can send ipv6 traffic as there is no port security
3055
3056 sip=ee800000000000000000000000000000
3057 tip=fe80000000000000ea2aeafffe280023
3058 test_ipv6 11 f00000000011 f00000000333 $sip $tip
3059
3060 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3061 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
3062 # and should be dropped for any other ip6.src
3063 # lp21 can receive ipv6 traffic as there is no port security
3064
3065 tip=ee800000000000000000000000000000
3066 for i in 1 2 3; do
3067 sip=fe80000000000000ea2aeafffe2800${i}3
3068 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3069
3070 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
3071 sip=00000000000000000000000000000000
3072 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3073 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3074 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3075 # Traffic to non-multicast traffic should be dropped
3076 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3077 # Traffic of other ICMPv6 types should be dropped
3078 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
3079
3080 # should be dropped
3081 sip=ae80000000000000ea2aeafffe2800aa
3082 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3083 done
3084
3085 # configure lsp13 to send and received IPv4 packets with an address range
3086 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"
3087
3088 sleep 2
3089
3090 sip=`ip_to_hex 10 0 0 13`
3091 tip=`ip_to_hex 192 168 0 22`
3092 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
3093 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3094
3095 sip=`ip_to_hex 10 0 0 14`
3096 tip=`ip_to_hex 192 168 0 23`
3097 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
3098 # with dst ip 192.168.0.23 should be allowed
3099 test_ip 13 f00000000013 f00000000023 $sip $tip 23
3100
3101 sip=`ip_to_hex 192 168 0 33`
3102 tip=`ip_to_hex 10 0 0 15`
3103 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3104 # with dst ip 10.0.0.15 should be received by lsp13
3105 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3106
3107 sip=`ip_to_hex 192 168 0 33`
3108 tip=`ip_to_hex 20 0 0 4`
3109 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3110 # with dst ip 20.0.0.4 should be received by lsp13
3111 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3112
3113 sip=`ip_to_hex 192 168 0 33`
3114 tip=`ip_to_hex 20 0 0 5`
3115 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3116 # with dst ip 20.0.0.5 should not be received by lsp13
3117 test_ip 33 f00000000033 f00000000013 $sip $tip
3118
3119 sip=`ip_to_hex 192 168 0 33`
3120 tip=`ip_to_hex 20 0 0 255`
3121 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3122 # with dst ip 20.0.0.255 should be received by lsp13
3123 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3124
3125 sip=`ip_to_hex 192 168 0 33`
3126 tip=`ip_to_hex 192 168 0 255`
3127 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3128 # with dst ip 192.168.0.255 should not be received by lsp13
3129 test_ip 33 f00000000033 f00000000013 $sip $tip
3130
3131 sip=`ip_to_hex 192 168 0 33`
3132 tip=`ip_to_hex 224 0 0 4`
3133 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3134 # with dst ip 224.0.0.4 should be received by lsp13
3135 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3136
3137 #dump information including flow counters
3138 ovn-nbctl show
3139 ovn-sbctl dump-flows -- list multicast_group
3140
3141 echo "------ hv1 dump ------"
3142 as hv1 ovs-vsctl show
3143 as hv1 ovs-ofctl -O OpenFlow13 show br-int
3144 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3145
3146 echo "------ hv2 dump ------"
3147 as hv2 ovs-vsctl show
3148 as hv2 ovs-ofctl -O OpenFlow13 show br-int
3149 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3150
3151 echo "------ hv3 dump ------"
3152 as hv3 ovs-vsctl show
3153 as hv3 ovs-ofctl -O OpenFlow13 show br-int
3154 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3155
3156 # Now check the packets actually received against the ones expected.
3157 for i in 1 2 3; do
3158 for j in 1 2 3; do
3159 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3160 done
3161 done
3162
3163 OVN_CLEANUP([hv1],[hv2],[hv3])
3164
3165 AT_CLEANUP
3166
3167 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3168 AT_SKIP_IF([test $HAVE_PYTHON = no])
3169 ovn_start
3170
3171 # Logical network:
3172 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3173 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3174 # R2 has ls2 (172.16.1.0/24) connected to it.
3175
3176 ls1_lp1_mac="f0:00:00:01:02:03"
3177 rp_ls1_mac="00:00:00:01:02:03"
3178 rp_ls2_mac="00:00:00:01:02:04"
3179 ls2_lp1_mac="f0:00:00:01:02:04"
3180
3181 ls1_lp1_ip="192.168.1.2"
3182 ls2_lp1_ip="172.16.1.2"
3183
3184 ovn-nbctl lr-add R1
3185 ovn-nbctl lr-add R2
3186
3187 ovn-nbctl ls-add ls1
3188 ovn-nbctl ls-add ls2
3189
3190 # Connect ls1 to R1
3191 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3192
3193 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3194 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3195
3196 # Connect ls2 to R2
3197 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3198
3199 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3200 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3201
3202 # Connect R1 to R2
3203 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3204 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3205
3206 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3207 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3208
3209 # Create logical port ls1-lp1 in ls1
3210 ovn-nbctl lsp-add ls1 ls1-lp1 \
3211 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3212
3213 # Create logical port ls2-lp1 in ls2
3214 ovn-nbctl lsp-add ls2 ls2-lp1 \
3215 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3216
3217 # Create two hypervisor and create OVS ports corresponding to logical ports.
3218 net_add n1
3219
3220 sim_add hv1
3221 as hv1
3222 ovs-vsctl add-br br-phys
3223 ovn_attach n1 br-phys 192.168.0.1
3224 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3225 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3226 options:tx_pcap=hv1/vif1-tx.pcap \
3227 options:rxq_pcap=hv1/vif1-rx.pcap \
3228 ofport-request=1
3229
3230 sim_add hv2
3231 as hv2
3232 ovs-vsctl add-br br-phys
3233 ovn_attach n1 br-phys 192.168.0.2
3234 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3235 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3236 options:tx_pcap=hv2/vif1-tx.pcap \
3237 options:rxq_pcap=hv2/vif1-rx.pcap \
3238 ofport-request=1
3239
3240
3241 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3242 # packets for ARP resolution (native tunneling doesn't queue packets
3243 # for ARP resolution).
3244 OVN_POPULATE_ARP
3245
3246 # Allow some time for ovn-northd and ovn-controller to catch up.
3247 # XXX This should be more systematic.
3248 sleep 1
3249
3250 # Packet to send.
3251 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3252 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3253 udp && udp.src==53 && udp.dst==4369"
3254 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3255
3256
3257 echo "---------NB dump-----"
3258 ovn-nbctl show
3259 echo "---------------------"
3260 ovn-nbctl list logical_router
3261 echo "---------------------"
3262 ovn-nbctl list logical_router_port
3263 echo "---------------------"
3264
3265 echo "---------SB dump-----"
3266 ovn-sbctl list datapath_binding
3267 echo "---------------------"
3268 ovn-sbctl list port_binding
3269 echo "---------------------"
3270
3271 echo "------ hv1 dump ----------"
3272 as hv1 ovs-ofctl show br-int
3273 as hv1 ovs-ofctl dump-flows br-int
3274 echo "------ hv2 dump ----------"
3275 as hv2 ovs-ofctl show br-int
3276 as hv2 ovs-ofctl dump-flows br-int
3277
3278 # Packet to Expect
3279 # The TTL should be decremented by 2.
3280 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3281 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3282 udp && udp.src==53 && udp.dst==4369"
3283 echo $packet | ovstest test-ovn expr-to-packets > expected
3284
3285 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3286
3287 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3288 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3289 ])
3290
3291 # Disable the ls2-lp1 port.
3292 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3293
3294 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3295 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3296 ])
3297
3298 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3299 # Packet to send.
3300 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3301 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3302 udp && udp.src==53 && udp.dst==4369"
3303
3304 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3305 # The 2nd packet sent shound not be received.
3306 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3307
3308 OVN_CLEANUP([hv1],[hv2])
3309
3310 AT_CLEANUP
3311
3312
3313 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3314 AT_KEYWORDS([router-admin-state])
3315 AT_SKIP_IF([test $HAVE_PYTHON = no])
3316 ovn_start
3317
3318 # Logical network:
3319 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3320 # and 172.16.1.0/24) connected to it.
3321
3322 ovn-nbctl lr-add R1
3323
3324 ovn-nbctl ls-add ls1
3325
3326 # Connect ls1 to R1
3327 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3328 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3329 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3330
3331 # Create logical port ls1-lp1 in ls1
3332 ovn-nbctl lsp-add ls1 ls1-lp1 \
3333 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3334
3335 # Create logical port ls1-lp2 in ls1
3336 ovn-nbctl lsp-add ls1 ls1-lp2 \
3337 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3338
3339 # Create one hypervisor and create OVS ports corresponding to logical ports.
3340 net_add n1
3341
3342 sim_add hv1
3343 as hv1
3344 ovs-vsctl add-br br-phys
3345 ovn_attach n1 br-phys 192.168.0.1
3346 ovs-vsctl -- add-port br-int vif1 -- \
3347 set interface vif1 external-ids:iface-id=ls1-lp1 \
3348 options:tx_pcap=hv1/vif1-tx.pcap \
3349 options:rxq_pcap=hv1/vif1-rx.pcap \
3350 ofport-request=1
3351
3352 ovs-vsctl -- add-port br-int vif2 -- \
3353 set interface vif2 external-ids:iface-id=ls1-lp2 \
3354 options:tx_pcap=hv1/vif2-tx.pcap \
3355 options:rxq_pcap=hv1/vif2-rx.pcap \
3356 ofport-request=1
3357
3358
3359 # Allow some time for ovn-northd and ovn-controller to catch up.
3360 # XXX This should be more systematic.
3361 sleep 1
3362
3363 # Send ip packets between the two ports.
3364 ip_to_hex() {
3365 printf "%02x%02x%02x%02x" "$@"
3366 }
3367
3368 # Packet to send.
3369 src_mac="f00000010203"
3370 dst_mac="000000010203"
3371 src_ip=`ip_to_hex 192 168 1 2`
3372 dst_ip=`ip_to_hex 172 16 1 2`
3373 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3374 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3375
3376
3377 echo "---------NB dump-----"
3378 ovn-nbctl show
3379 echo "---------------------"
3380 ovn-nbctl list logical_router
3381 echo "---------------------"
3382 ovn-nbctl list logical_router_port
3383 echo "---------------------"
3384
3385 echo "---------SB dump-----"
3386 ovn-sbctl list datapath_binding
3387 echo "---------------------"
3388 ovn-sbctl list logical_flow
3389 echo "---------------------"
3390
3391 echo "------ hv1 dump ----------"
3392 as hv1 ovs-ofctl dump-flows br-int
3393
3394
3395 #Disable router R1
3396 ovn-nbctl set Logical_Router R1 enabled=false
3397
3398 # Allow some time for ovn-northd and ovn-controller to catch up.
3399 # XXX This should be more systematic.
3400 sleep 1
3401
3402 echo "---------SB dump-----"
3403 ovn-sbctl list datapath_binding
3404 echo "---------------------"
3405 ovn-sbctl list logical_flow
3406 echo "---------------------"
3407
3408 echo "------ hv1 dump ----------"
3409 as hv1 ovs-ofctl dump-flows br-int
3410
3411 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3412
3413 # Packet to Expect
3414 expect_src_mac="000000010203"
3415 expect_dst_mac="f00000010204"
3416 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3417
3418 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3419
3420
3421 as hv1
3422 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3423 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3424 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3425
3426 as ovn-sb
3427 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3428
3429 as ovn-nb
3430 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3431
3432 as northd
3433 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3434
3435 as main
3436 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3437 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3438
3439 AT_CLEANUP
3440
3441
3442 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3443 AT_KEYWORDS([router-admin-state])
3444 AT_SKIP_IF([test $HAVE_PYTHON = no])
3445 ovn_start
3446
3447 # Logical network:
3448 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3449 # and has switch ls2 (172.16.1.0/24) connected to it.
3450
3451 ovn-nbctl lr-add R1
3452
3453 ovn-nbctl ls-add ls1
3454 ovn-nbctl ls-add ls2
3455
3456 # Connect ls1 to R1
3457 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3458 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3459 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3460
3461 # Connect ls2 to R1
3462 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3463 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3464 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3465
3466 # Create logical port ls1-lp1 in ls1
3467 ovn-nbctl lsp-add ls1 ls1-lp1 \
3468 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3469
3470 # Create logical port ls2-lp1 in ls2
3471 ovn-nbctl lsp-add ls2 ls2-lp1 \
3472 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3473
3474 # Create one hypervisor and create OVS ports corresponding to logical ports.
3475 net_add n1
3476
3477 sim_add hv1
3478 as hv1
3479 ovs-vsctl add-br br-phys
3480 ovn_attach n1 br-phys 192.168.0.1
3481 ovs-vsctl -- add-port br-int vif1 -- \
3482 set interface vif1 external-ids:iface-id=ls1-lp1 \
3483 options:tx_pcap=hv1/vif1-tx.pcap \
3484 options:rxq_pcap=hv1/vif1-rx.pcap \
3485 ofport-request=1
3486
3487 ovs-vsctl -- add-port br-int vif2 -- \
3488 set interface vif2 external-ids:iface-id=ls2-lp1 \
3489 options:tx_pcap=hv1/vif2-tx.pcap \
3490 options:rxq_pcap=hv1/vif2-rx.pcap \
3491 ofport-request=1
3492
3493
3494 # Allow some time for ovn-northd and ovn-controller to catch up.
3495 # XXX This should be more systematic.
3496 sleep 1
3497
3498 # Send ip packets between the two ports.
3499 ip_to_hex() {
3500 printf "%02x%02x%02x%02x" "$@"
3501 }
3502
3503 # Packet to send.
3504 src_mac="f00000010203"
3505 dst_mac="000000010203"
3506 src_ip=`ip_to_hex 192 168 1 2`
3507 dst_ip=`ip_to_hex 172 16 1 2`
3508 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3509 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3510
3511
3512 echo "---------NB dump-----"
3513 ovn-nbctl show
3514 echo "---------------------"
3515 ovn-nbctl list logical_router
3516 echo "---------------------"
3517 ovn-nbctl list logical_router_port
3518 echo "---------------------"
3519
3520 echo "---------SB dump-----"
3521 ovn-sbctl list datapath_binding
3522 echo "---------------------"
3523 ovn-sbctl list logical_flow
3524 echo "---------------------"
3525
3526 echo "------ hv1 dump ----------"
3527 as hv1 ovs-ofctl dump-flows br-int
3528
3529 #Disable router R1
3530 ovn-nbctl set Logical_Router R1 enabled=false
3531
3532 echo "---------SB dump-----"
3533 ovn-sbctl list datapath_binding
3534 echo "---------------------"
3535 ovn-sbctl list logical_flow
3536 echo "---------------------"
3537
3538 echo "------ hv1 dump ----------"
3539 as hv1 ovs-ofctl dump-flows br-int
3540
3541 # Allow some time for the disabling of logical router R1 to propagate.
3542 # XXX This should be more systematic.
3543 sleep 1
3544
3545 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3546
3547 # Packet to Expect
3548 expect_src_mac="000000010204"
3549 expect_dst_mac="f00000010204"
3550 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3551
3552 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3553
3554 OVN_CLEANUP([hv1])
3555
3556 AT_CLEANUP
3557
3558 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3559 AT_SKIP_IF([test $HAVE_PYTHON = no])
3560 ovn_start
3561
3562 # Logical network:
3563 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3564 # network. R1 has switchess foo (192.168.1.0/24)
3565 # connected to it.
3566 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3567
3568 ovn-nbctl lr-add R1
3569 ovn-nbctl lr-add R2
3570
3571 ovn-nbctl ls-add foo
3572 ovn-nbctl ls-add alice
3573 ovn-nbctl ls-add bob
3574
3575 # Connect foo to R1
3576 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3577 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3578 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3579
3580 # Connect alice to R2
3581 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3582 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3583 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3584
3585 # Connect bob to R2
3586 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3587 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3588 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3589
3590 # Connect R1 to R2
3591 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3592 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3593
3594 #install static routes
3595 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3596 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3597 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3598
3599 # Create logical port foo1 in foo
3600 ovn-nbctl lsp-add foo foo1 \
3601 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3602
3603 # Create logical port alice1 in alice
3604 ovn-nbctl lsp-add alice alice1 \
3605 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3606
3607 # Create logical port bob1 in bob
3608 ovn-nbctl lsp-add bob bob1 \
3609 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3610
3611 # Create two hypervisor and create OVS ports corresponding to logical ports.
3612 net_add n1
3613
3614 sim_add hv1
3615 as hv1
3616 ovs-vsctl add-br br-phys
3617 ovn_attach n1 br-phys 192.168.0.1
3618 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3619 set interface hv1-vif1 external-ids:iface-id=foo1 \
3620 options:tx_pcap=hv1/vif1-tx.pcap \
3621 options:rxq_pcap=hv1/vif1-rx.pcap \
3622 ofport-request=1
3623
3624 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3625 set interface hv1-vif2 external-ids:iface-id=alice1 \
3626 options:tx_pcap=hv1/vif2-tx.pcap \
3627 options:rxq_pcap=hv1/vif2-rx.pcap \
3628 ofport-request=2
3629
3630 sim_add hv2
3631 as hv2
3632 ovs-vsctl add-br br-phys
3633 ovn_attach n1 br-phys 192.168.0.2
3634 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3635 set interface hv2-vif1 external-ids:iface-id=bob1 \
3636 options:tx_pcap=hv2/vif1-tx.pcap \
3637 options:rxq_pcap=hv2/vif1-rx.pcap \
3638 ofport-request=1
3639
3640
3641 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3642 # packets for ARP resolution (native tunneling doesn't queue packets
3643 # for ARP resolution).
3644 OVN_POPULATE_ARP
3645
3646 # Allow some time for ovn-northd and ovn-controller to catch up.
3647 # XXX This should be more systematic.
3648 sleep 1
3649
3650 ip_to_hex() {
3651 printf "%02x%02x%02x%02x" "$@"
3652 }
3653
3654 # Send ip packets between foo1 and alice1
3655 src_mac="f00000010203"
3656 dst_mac="000000010203"
3657 src_ip=`ip_to_hex 192 168 1 2`
3658 dst_ip=`ip_to_hex 172 16 1 2`
3659 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3660 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3661
3662 # Send ip packets between foo1 and bob1
3663 src_mac="f00000010203"
3664 dst_mac="000000010203"
3665 src_ip=`ip_to_hex 192 168 1 2`
3666 dst_ip=`ip_to_hex 172 16 2 2`
3667 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3668 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3669
3670 echo "---------NB dump-----"
3671 ovn-nbctl show
3672 echo "---------------------"
3673 ovn-nbctl list logical_router
3674 echo "---------------------"
3675 ovn-nbctl list logical_router_port
3676 echo "---------------------"
3677
3678 echo "---------SB dump-----"
3679 ovn-sbctl list datapath_binding
3680 echo "---------------------"
3681 ovn-sbctl list port_binding
3682 echo "---------------------"
3683
3684 echo "------ hv1 dump ----------"
3685 as hv1 ovs-ofctl dump-flows br-int
3686 echo "------ hv2 dump ----------"
3687 as hv2 ovs-ofctl dump-flows br-int
3688
3689 # Packet to Expect at bob1
3690 src_mac="000000010205"
3691 dst_mac="f00000010205"
3692 src_ip=`ip_to_hex 192 168 1 2`
3693 dst_ip=`ip_to_hex 172 16 2 2`
3694 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3695
3696 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3697
3698 # Packet to Expect at alice1
3699 src_mac="000000010204"
3700 dst_mac="f00000010204"
3701 src_ip=`ip_to_hex 192 168 1 2`
3702 dst_ip=`ip_to_hex 172 16 1 2`
3703 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3704
3705 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3706
3707 OVN_CLEANUP([hv1],[hv2])
3708
3709 AT_CLEANUP
3710
3711 AT_SETUP([ovn -- send gratuitous arp on localnet])
3712 AT_SKIP_IF([test $HAVE_PYTHON = no])
3713 ovn_start
3714 ovn-nbctl ls-add lsw0
3715 net_add n1
3716 sim_add hv
3717 as hv
3718 ovs-vsctl \
3719 -- add-br br-phys \
3720 -- add-br br-eth0
3721
3722 ovn_attach n1 br-phys 192.168.0.1
3723
3724 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3725 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])
3726
3727 # Create a vif.
3728 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3729 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3730 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3731
3732 # Create a localnet port.
3733 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3734 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3735 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3736 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3737
3738 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3739
3740 # Wait for packet to be received.
3741 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3742 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3743
3744 # Check GARP packet when restart openflow connection.
3745 as hv
3746 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3747
3748 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3749
3750 as hv
3751 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3752
3753 # Wait for packet to be received.
3754 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3755 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3756
3757 # Delete the localnet ports.
3758 AT_CHECK([ovs-vsctl del-port localvif1])
3759 AT_CHECK([ovn-nbctl lsp-del ln_port])
3760
3761 OVN_CLEANUP([hv])
3762
3763 AT_CLEANUP
3764
3765 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3766 AT_SKIP_IF([test $HAVE_PYTHON = no])
3767 ovn_start
3768
3769 # Logical network:
3770 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3771 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3772 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3773 # connected to it.
3774
3775 ovn-nbctl lr-add R1
3776 ovn-nbctl lr-add R2
3777 ovn-nbctl lr-add R3
3778
3779 ovn-nbctl ls-add foo
3780 ovn-nbctl ls-add alice
3781 ovn-nbctl ls-add bob
3782 ovn-nbctl ls-add join
3783
3784 # Connect foo to R1
3785 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3786 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3787 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3788
3789 # Connect alice to R2
3790 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3791 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3792 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3793
3794 # Connect bob to R3
3795 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3796 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3797 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3798
3799 # Connect R1 to join
3800 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3801 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3802 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3803
3804 # Connect R2 to join
3805 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3806 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3807 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3808
3809 # Connect R3 to join
3810 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3811 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3812 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3813
3814 #install static routes
3815 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3816 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3817
3818 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3819 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3820
3821 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3822 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3823
3824 # Create logical port foo1 in foo
3825 ovn-nbctl lsp-add foo foo1 \
3826 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3827
3828 # Create logical port alice1 in alice
3829 ovn-nbctl lsp-add alice alice1 \
3830 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3831
3832 # Create logical port bob1 in bob
3833 ovn-nbctl lsp-add bob bob1 \
3834 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3835
3836 # Create two hypervisor and create OVS ports corresponding to logical ports.
3837 net_add n1
3838
3839 sim_add hv1
3840 as hv1
3841 ovs-vsctl add-br br-phys
3842 ovn_attach n1 br-phys 192.168.0.1
3843 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3844 set interface hv1-vif1 external-ids:iface-id=foo1 \
3845 options:tx_pcap=hv1/vif1-tx.pcap \
3846 options:rxq_pcap=hv1/vif1-rx.pcap \
3847 ofport-request=1
3848
3849 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3850 set interface hv1-vif2 external-ids:iface-id=alice1 \
3851 options:tx_pcap=hv1/vif2-tx.pcap \
3852 options:rxq_pcap=hv1/vif2-rx.pcap \
3853 ofport-request=2
3854
3855 sim_add hv2
3856 as hv2
3857 ovs-vsctl add-br br-phys
3858 ovn_attach n1 br-phys 192.168.0.2
3859 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3860 set interface hv2-vif1 external-ids:iface-id=bob1 \
3861 options:tx_pcap=hv2/vif1-tx.pcap \
3862 options:rxq_pcap=hv2/vif1-rx.pcap \
3863 ofport-request=1
3864
3865
3866 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3867 # packets for ARP resolution (native tunneling doesn't queue packets
3868 # for ARP resolution).
3869 OVN_POPULATE_ARP
3870
3871 # Allow some time for ovn-northd and ovn-controller to catch up.
3872 # XXX This should be more systematic.
3873 sleep 1
3874
3875 ip_to_hex() {
3876 printf "%02x%02x%02x%02x" "$@"
3877 }
3878
3879 # Send ip packets between foo1 and alice1
3880 src_mac="f00000010203"
3881 dst_mac="000001010203"
3882 src_ip=`ip_to_hex 192 168 1 2`
3883 dst_ip=`ip_to_hex 172 16 1 2`
3884 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3885 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3886 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3887
3888 # Send ip packets between foo1 and bob1
3889 src_mac="f00000010203"
3890 dst_mac="000001010203"
3891 src_ip=`ip_to_hex 192 168 1 2`
3892 dst_ip=`ip_to_hex 10 32 1 2`
3893 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3894 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3895
3896 echo "---------NB dump-----"
3897 ovn-nbctl show
3898 echo "---------------------"
3899 ovn-nbctl list logical_router
3900 echo "---------------------"
3901 ovn-nbctl list logical_router_port
3902 echo "---------------------"
3903
3904 echo "---------SB dump-----"
3905 ovn-sbctl list datapath_binding
3906 echo "---------------------"
3907 ovn-sbctl list port_binding
3908 echo "---------------------"
3909 ovn-sbctl dump-flows
3910 echo "---------------------"
3911
3912 echo "------ hv1 dump ----------"
3913 as hv1 ovs-ofctl show br-int
3914 as hv1 ovs-ofctl dump-flows br-int
3915 echo "------ hv2 dump ----------"
3916 as hv2 ovs-ofctl show br-int
3917 as hv2 ovs-ofctl dump-flows br-int
3918 echo "----------------------------"
3919
3920 # Packet to Expect at bob1
3921 src_mac="000003010203"
3922 dst_mac="f00000010205"
3923 src_ip=`ip_to_hex 192 168 1 2`
3924 dst_ip=`ip_to_hex 10 32 1 2`
3925 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3926
3927 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3928
3929 # Packet to Expect at alice1
3930 src_mac="000002010203"
3931 dst_mac="f00000010204"
3932 src_ip=`ip_to_hex 192 168 1 2`
3933 dst_ip=`ip_to_hex 172 16 1 2`
3934 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3935
3936 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3937
3938 OVN_CLEANUP([hv1],[hv2])
3939
3940 AT_CLEANUP
3941
3942 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3943 AT_SKIP_IF([test $HAVE_PYTHON = no])
3944 ovn_start
3945
3946 ovn-nbctl ls-add ls1
3947
3948 ovn-nbctl lsp-add ls1 ls1-lp1 \
3949 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3950
3951 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3952
3953 ovn-nbctl lsp-add ls1 ls1-lp2 \
3954 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3955
3956 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3957
3958 ovn-nbctl ls-add ls2
3959 ovn-nbctl lsp-add ls2 ls2-lp1 \
3960 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3961 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3962 ovn-nbctl lsp-add ls2 ls2-lp2 \
3963 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3964 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3965
3966 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
3967 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3968 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
3969
3970 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3971 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3972
3973 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
3974 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3975 \"lease_time\"=\"3600\"")"
3976
3977 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
3978
3979 net_add n1
3980 sim_add hv1
3981
3982 as hv1
3983 ovs-vsctl add-br br-phys
3984 ovn_attach n1 br-phys 192.168.0.1
3985 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3986 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3987 options:tx_pcap=hv1/vif1-tx.pcap \
3988 options:rxq_pcap=hv1/vif1-rx.pcap \
3989 ofport-request=1
3990
3991 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3992 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3993 options:tx_pcap=hv1/vif2-tx.pcap \
3994 options:rxq_pcap=hv1/vif2-rx.pcap \
3995 ofport-request=2
3996
3997 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3998 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3999 options:tx_pcap=hv1/vif3-tx.pcap \
4000 options:rxq_pcap=hv1/vif3-rx.pcap \
4001 ofport-request=3
4002
4003 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4004 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4005 options:tx_pcap=hv1/vif4-tx.pcap \
4006 options:rxq_pcap=hv1/vif4-rx.pcap \
4007 ofport-request=4
4008
4009 OVN_POPULATE_ARP
4010
4011 sleep 2
4012
4013 as hv1 ovs-vsctl show
4014
4015 # This shell function sends a DHCP request packet
4016 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
4017 test_dhcp() {
4018 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
4019 shift; shift; shift; shift; shift;
4020 if test $use_ip != 0; then
4021 src_ip=$1
4022 dst_ip=$2
4023 shift; shift;
4024 else
4025 src_ip=`ip_to_hex 0 0 0 0`
4026 dst_ip=`ip_to_hex 255 255 255 255`
4027 fi
4028 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
4029 # udp header and dhcp header
4030 request=${request}0044004300fc0000
4031 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
4032 # client hardware padding
4033 request=${request}00000000000000000000
4034 # server hostname
4035 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4036 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4037 # boot file name
4038 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4039 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4040 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4041 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4042 # dhcp magic cookie
4043 request=${request}63825363
4044 # dhcp message type
4045 request=${request}3501${dhcp_type}ff
4046
4047 if test $offer_ip != 0; then
4048 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
4049 # total IP length will be the IP length of the request packet
4050 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4051 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4052 udp_len=`expr $ip_len - 20`
4053 ip_len=$(printf "%x" $ip_len)
4054 udp_len=$(printf "%x" $udp_len)
4055 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4056 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4057 # udp header and dhcp header.
4058 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
4059 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
4060 # your ip address
4061 reply=${reply}${offer_ip}
4062 # next server ip address, relay agent ip address, client mac address
4063 reply=${reply}0000000000000000${src_mac}
4064 # client hardware padding
4065 reply=${reply}00000000000000000000
4066 # server hostname
4067 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4068 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4069 # boot file name
4070 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4071 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4072 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4073 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4074 # dhcp magic cookie
4075 reply=${reply}63825363
4076 # dhcp message type
4077 local dhcp_reply_type=02
4078 if test $dhcp_type = 03; then
4079 dhcp_reply_type=05
4080 fi
4081 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
4082 echo $reply >> $inport.expected
4083 else
4084 for outport; do
4085 echo $request >> $outport.expected
4086 done
4087 fi
4088 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4089 }
4090
4091 reset_pcap_file() {
4092 local iface=$1
4093 local pcap_file=$2
4094 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4095 options:rxq_pcap=dummy-rx.pcap
4096 rm -f ${pcap_file}*.pcap
4097 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4098 options:rxq_pcap=${pcap_file}-rx.pcap
4099 }
4100
4101 ip_to_hex() {
4102 printf "%02x%02x%02x%02x" "$@"
4103 }
4104
4105 AT_CAPTURE_FILE([ofctl_monitor0.log])
4106 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4107 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4108
4109 echo "---------NB dump-----"
4110 ovn-nbctl show
4111 echo "---------------------"
4112 echo "---------SB dump-----"
4113 ovn-sbctl list datapath_binding
4114 echo "---------------------"
4115 ovn-sbctl list logical_flow
4116 echo "---------------------"
4117
4118 echo "---------------------"
4119 ovn-sbctl dump-flows
4120 echo "---------------------"
4121
4122 echo "------ hv1 dump ----------"
4123 as hv1 ovs-ofctl dump-flows br-int
4124
4125 # Send DHCPDISCOVER.
4126 offer_ip=`ip_to_hex 10 0 0 4`
4127 server_ip=`ip_to_hex 10 0 0 1`
4128 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4129 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4130
4131 # NXT_RESUMEs should be 1.
4132 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4133
4134 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4135 cat 1.expected | cut -c -48 > expout
4136 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4137 # Skipping the IPv4 checksum.
4138 cat 1.expected | cut -c 53- > expout
4139 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4140
4141 # ovs-ofctl also resumes the packets and this causes other ports to receive
4142 # the DHCP request packet. So reset the pcap files so that its easier to test.
4143 reset_pcap_file hv1-vif1 hv1/vif1
4144 reset_pcap_file hv1-vif2 hv1/vif2
4145 rm -f 1.expected
4146 rm -f 2.expected
4147
4148 # Send DHCPREQUEST.
4149 offer_ip=`ip_to_hex 10 0 0 6`
4150 server_ip=`ip_to_hex 10 0 0 1`
4151 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4152 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4153
4154 # NXT_RESUMEs should be 2.
4155 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4156
4157 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4158 cat 2.expected | cut -c -48 > expout
4159 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4160 # Skipping the IPv4 checksum.
4161 cat 2.expected | cut -c 53- > expout
4162 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4163
4164 reset_pcap_file hv1-vif1 hv1/vif1
4165 reset_pcap_file hv1-vif2 hv1/vif2
4166 rm -f 1.expected
4167 rm -f 2.expected
4168
4169 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4170 # but should be resumed without the reply.
4171 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4172 # one from ovn-controller and the other from "ovs-ofctl resume."
4173 offer_ip=0
4174 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
4175
4176 # NXT_RESUMEs should be 3.
4177 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4178
4179 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4180 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4181
4182 reset_pcap_file hv1-vif1 hv1/vif1
4183 reset_pcap_file hv1-vif2 hv1/vif2
4184 rm -f 1.expected
4185 rm -f 2.expected
4186
4187 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4188 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4189
4190 test_dhcp 3 f00000000003 01 0 4 0
4191
4192 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4193 # this lport.
4194 test_dhcp 4 f00000000004 01 0 3 0
4195
4196 # NXT_RESUMEs should be 3.
4197 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4198
4199 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4200 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4201
4202 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4203 offer_ip=`ip_to_hex 10 0 0 6`
4204 server_ip=`ip_to_hex 10 0 0 1`
4205 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4206 src_ip=$offer_ip
4207 dst_ip=$server_ip
4208 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4209
4210 # NXT_RESUMEs should be 4.
4211 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4212
4213 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4214 cat 2.expected | cut -c -48 > expout
4215 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4216 # Skipping the IPv4 checksum.
4217 cat 2.expected | cut -c 53- > expout
4218 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4219
4220 reset_pcap_file hv1-vif1 hv1/vif1
4221 reset_pcap_file hv1-vif2 hv1/vif2
4222 rm -f 1.expected
4223 rm -f 2.expected
4224
4225 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4226 offer_ip=`ip_to_hex 10 0 0 6`
4227 server_ip=`ip_to_hex 10 0 0 1`
4228 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4229 src_ip=$offer_ip
4230 dst_ip=`ip_to_hex 255 255 255 255`
4231 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4232
4233 # NXT_RESUMEs should be 5.
4234 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4235
4236 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4237 cat 2.expected | cut -c -48 > expout
4238 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4239 # Skipping the IPv4 checksum.
4240 cat 2.expected | cut -c 53- > expout
4241 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4242
4243 reset_pcap_file hv1-vif1 hv1/vif1
4244 reset_pcap_file hv1-vif2 hv1/vif2
4245 rm -f 1.expected
4246 rm -f 2.expected
4247
4248 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4249 # The packet should not be received by ovn-controller.
4250 src_ip=`ip_to_hex 10 0 0 6`
4251 dst_ip=`ip_to_hex 10 0 0 4`
4252 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4253
4254 # NXT_RESUMEs should be 5.
4255 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4256
4257 # vif1-tx.pcap should have received the DHCPv4 request packet
4258 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4259
4260 as hv1
4261 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4262 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4263 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4264
4265 as ovn-sb
4266 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4267
4268 as ovn-nb
4269 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4270
4271 as northd
4272 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4273
4274 as main
4275 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4276 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4277
4278 AT_CLEANUP
4279
4280 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4281 AT_SKIP_IF([test $HAVE_PYTHON = no])
4282 ovn_start
4283
4284 ovn-nbctl ls-add ls1
4285 ovn-nbctl lsp-add ls1 ls1-lp1 \
4286 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4287
4288 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4289
4290 ovn-nbctl lsp-add ls1 ls1-lp2 \
4291 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4292
4293 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4294
4295 ovn-nbctl lsp-add ls1 ls1-lp3 \
4296 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4297
4298 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4299
4300 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4301 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4302
4303 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4304 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4305
4306 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4307 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4308
4309 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4310
4311 ovn-nbctl ls-add ls2
4312 ovn-nbctl lsp-add ls2 ls2-lp1 \
4313 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4314 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4315 ovn-nbctl lsp-add ls2 ls2-lp2 \
4316 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4317 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4318
4319 net_add n1
4320 sim_add hv1
4321
4322 as hv1
4323 ovs-vsctl add-br br-phys
4324 ovn_attach n1 br-phys 192.168.0.1
4325 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4326 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4327 options:tx_pcap=hv1/vif1-tx.pcap \
4328 options:rxq_pcap=hv1/vif1-rx.pcap \
4329 ofport-request=1
4330
4331 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4332 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4333 options:tx_pcap=hv1/vif2-tx.pcap \
4334 options:rxq_pcap=hv1/vif2-rx.pcap \
4335 ofport-request=2
4336
4337 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4338 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4339 options:tx_pcap=hv1/vif3-tx.pcap \
4340 options:rxq_pcap=hv1/vif3-rx.pcap \
4341 ofport-request=3
4342
4343 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4344 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4345 options:tx_pcap=hv1/vif4-tx.pcap \
4346 options:rxq_pcap=hv1/vif4-rx.pcap \
4347 ofport-request=4
4348
4349 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4350 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4351 options:tx_pcap=hv1/vif5-tx.pcap \
4352 options:rxq_pcap=hv1/vif5-rx.pcap \
4353 ofport-request=5
4354
4355 OVN_POPULATE_ARP
4356
4357 sleep 2
4358
4359 trim_zeros() {
4360 sed 's/\(00\)\{1,\}$//'
4361 }
4362
4363 # This shell function sends a DHCPv6 request packet
4364 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4365 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4366 # packet should be received twice (one from ovn-controller and the other
4367 # from the "ovs-ofctl monitor br-int resume"
4368 test_dhcpv6() {
4369 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4370 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4371 # dst ip ff02::1:2
4372 request=${request}ff020000000000000000000000010002
4373 # udp header and dhcpv6 header
4374 request=${request}02220223002affff${msg_code}010203
4375 # Client identifier
4376 request=${request}0001000a00030001${src_mac}
4377 # IA-NA (Identity Association for Non Temporary Address)
4378 request=${request}0003000c0102030400000e1000001518
4379 shift; shift; shift; shift; shift;
4380 if test $offer_ip != 0; then
4381 local server_mac=000000100001
4382 local server_lla=fe80000000000000020000fffe100001
4383 local reply_code=07
4384 if test $msg_code = 01; then
4385 reply_code=02
4386 fi
4387 local msg_len=54
4388 if test $offer_ip = 1; then
4389 msg_len=28
4390 fi
4391 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4392 # udp header and dhcpv6 header
4393 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4394 # Client identifier
4395 reply=${reply}0001000a00030001${src_mac}
4396 # IA-NA
4397 if test $offer_ip != 1; then
4398 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4399 fi
4400 # Server identifier
4401 reply=${reply}0002000a00030001${server_mac}
4402 echo $reply | trim_zeros >> $inport.expected
4403 else
4404 for outport; do
4405 echo $request | trim_zeros >> $outport.expected
4406 done
4407 fi
4408
4409 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4410 }
4411
4412 reset_pcap_file() {
4413 local iface=$1
4414 local pcap_file=$2
4415 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4416 options:rxq_pcap=dummy-rx.pcap
4417 rm -f ${pcap_file}*.pcap
4418 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4419 options:rxq_pcap=${pcap_file}-rx.pcap
4420 }
4421
4422 AT_CAPTURE_FILE([ofctl_monitor0.log])
4423 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4424 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4425
4426 echo "---------NB dump-----"
4427 ovn-nbctl show
4428 echo "---------------------"
4429 echo "---------SB dump-----"
4430 ovn-sbctl list datapath_binding
4431 echo "---------------------"
4432 ovn-sbctl list logical_flow
4433 echo "---------------------"
4434
4435 echo "---------------------"
4436 ovn-sbctl dump-flows
4437 echo "---------------------"
4438
4439 echo "------ hv1 dump ----------"
4440 as hv1 ovs-ofctl dump-flows br-int
4441
4442 src_mac=f00000000001
4443 src_lla=fe80000000000000f20000fffe000001
4444 offer_ip=ae700000000000000000000000000004
4445 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4446
4447 # NXT_RESUMEs should be 1.
4448 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4449
4450 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4451 # cat 1.expected | trim_zeros > expout
4452 cat 1.expected | cut -c -120 > expout
4453 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4454 # Skipping the UDP checksum
4455 cat 1.expected | cut -c 125- > expout
4456 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4457
4458 rm 1.expected
4459
4460 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4461 # without any modifications and the packet should be received by ls1-lp1.
4462 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4463 # resume and the other from ovs-ofctl monitor resume.
4464
4465 reset_pcap_file hv1-vif1 hv1/vif1
4466 reset_pcap_file hv1-vif2 hv1/vif2
4467
4468 src_mac=f00000000002
4469 src_lla=fe80000000000000f20000fffe000002
4470 offer_ip=ae700000000000000000000000000005
4471 # Set invalid msg_type
4472
4473 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4474
4475 # NXT_RESUMEs should be 2.
4476 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4477
4478 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4479 rm 2.packets
4480 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4481 AT_CHECK([cat 2.packets], [0], [])
4482
4483 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4484 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4485 cat 1.expected > expout
4486 AT_CHECK([cat 1.packets], [0], [expout])
4487
4488 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4489 # There should be no DHCPv6 reply from ovn-controller and the request packet
4490 # should be received by ls2-lp2.
4491
4492 src_mac=f00000000003
4493 src_lla=fe80000000000000f20000fffe000003
4494 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4495
4496 # NXT_RESUMEs should be 2 only.
4497 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4498
4499 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4500 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4501 AT_CHECK([cat 3.packets], [0], [])
4502
4503 # vif4-tx.pcap should have received the DHCPv6 request packet
4504 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4505 cat 4.expected > expout
4506 AT_CHECK([cat 4.packets], [0], [expout])
4507
4508 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4509 # The DHCPv6 reply should doesn't contian offer_ip.
4510 src_mac=f00000000022
4511 src_lla=fe80000000000000f20000fffe000022
4512 reset_pcap_file hv1-vif5 hv1/vif5
4513 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4514
4515 # NXT_RESUMEs should be 3.
4516 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4517
4518 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4519 # Skipping the UDP checksum
4520 cat 5.expected | cut -c 1-120,125- > expout
4521 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4522
4523 as hv1
4524 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4525 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4526 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4527
4528 as ovn-sb
4529 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4530
4531 as ovn-nb
4532 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4533
4534 as northd
4535 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4536
4537 as main
4538 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4539 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4540
4541 AT_CLEANUP
4542
4543 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4544 AT_SKIP_IF([test $HAVE_PYTHON = no])
4545 ovn_start
4546
4547 # Logical network:
4548 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4549 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4550 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4551 # R2 is a gateway router.
4552
4553
4554
4555 # Create two hypervisor and create OVS ports corresponding to logical ports.
4556 net_add n1
4557
4558 sim_add hv1
4559 as hv1
4560 ovs-vsctl add-br br-phys
4561 ovn_attach n1 br-phys 192.168.0.1
4562 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4563 set interface hv1-vif1 external-ids:iface-id=foo1 \
4564 options:tx_pcap=hv1/vif1-tx.pcap \
4565 options:rxq_pcap=hv1/vif1-rx.pcap \
4566 ofport-request=1
4567
4568
4569 sim_add hv2
4570 as hv2
4571 ovs-vsctl add-br br-phys
4572 ovn_attach n1 br-phys 192.168.0.2
4573 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4574 set interface hv2-vif1 external-ids:iface-id=alice1 \
4575 options:tx_pcap=hv2/vif1-tx.pcap \
4576 options:rxq_pcap=hv2/vif1-rx.pcap \
4577 ofport-request=1
4578
4579 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4580 # packets for ARP resolution (native tunneling doesn't queue packets
4581 # for ARP resolution).
4582 OVN_POPULATE_ARP
4583
4584 ovn-nbctl create Logical_Router name=R1
4585 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4586
4587 ovn-nbctl ls-add foo
4588 ovn-nbctl ls-add alice
4589 ovn-nbctl ls-add join
4590
4591 # Connect foo to R1
4592 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4593 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4594 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4595
4596 # Connect alice to R2
4597 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4598 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4599 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4600
4601 # Connect R1 to join
4602 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4603 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4604 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4605
4606 # Connect R2 to join
4607 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4608 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4609 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4610
4611
4612 #install static routes
4613 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4614 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4615 R1 static_routes @lrt
4616
4617 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4618 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4619 R2 static_routes @lrt
4620
4621 # Create logical port foo1 in foo
4622 ovn-nbctl lsp-add foo foo1 \
4623 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4624
4625 # Create logical port alice1 in alice
4626 ovn-nbctl lsp-add alice alice1 \
4627 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4628
4629
4630 # Allow some time for ovn-northd and ovn-controller to catch up.
4631 # XXX This should be more systematic.
4632 sleep 2
4633
4634 ip_to_hex() {
4635 printf "%02x%02x%02x%02x" "$@"
4636 }
4637
4638 # Send ip packets between foo1 and alice1
4639 src_mac="f00000010203"
4640 dst_mac="000001010203"
4641 src_ip=`ip_to_hex 192 168 1 2`
4642 dst_ip=`ip_to_hex 172 16 1 2`
4643 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4644
4645 echo "---------NB dump-----"
4646 ovn-nbctl show
4647 echo "---------------------"
4648 ovn-nbctl list logical_router
4649 echo "---------------------"
4650 ovn-nbctl list logical_router_port
4651 echo "---------------------"
4652
4653 echo "---------SB dump-----"
4654 ovn-sbctl list datapath_binding
4655 echo "---------------------"
4656 ovn-sbctl list port_binding
4657 echo "---------------------"
4658 ovn-sbctl dump-flows
4659 echo "---------------------"
4660 ovn-sbctl list chassis
4661 ovn-sbctl list encap
4662 echo "---------------------"
4663
4664 # Packet to Expect at alice1
4665 src_mac="000002010203"
4666 dst_mac="f00000010204"
4667 src_ip=`ip_to_hex 192 168 1 2`
4668 dst_ip=`ip_to_hex 172 16 1 2`
4669 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4670
4671
4672 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4673 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4674
4675 echo "------ hv1 dump after packet 1 ----------"
4676 as hv1 ovs-ofctl show br-int
4677 as hv1 ovs-ofctl dump-flows br-int
4678 echo "------ hv2 dump after packet 1 ----------"
4679 as hv2 ovs-ofctl show br-int
4680 as hv2 ovs-ofctl dump-flows br-int
4681 echo "----------------------------"
4682
4683 echo $expected > expected
4684 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4685
4686 # Delete the router and re-create it. Things should work as before.
4687 ovn-nbctl lr-del R2
4688 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4689 # Connect alice to R2
4690 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4691 # Connect R2 to join
4692 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4693
4694 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4695 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4696 R2 static_routes @lrt
4697
4698 # Wait for ovn-controller to catch up.
4699 sleep 1
4700
4701 # Send the packet again.
4702 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4703
4704 echo "------ hv1 dump after packet 2 ----------"
4705 as hv1 ovs-ofctl show br-int
4706 as hv1 ovs-ofctl dump-flows br-int
4707 echo "------ hv2 dump after packet 2 ----------"
4708 as hv2 ovs-ofctl show br-int
4709 as hv2 ovs-ofctl dump-flows br-int
4710 echo "----------------------------"
4711
4712 echo $expected >> expected
4713 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4714
4715 OVN_CLEANUP([hv1],[hv2])
4716
4717 AT_CLEANUP
4718
4719 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4720 AT_KEYWORDS([router-icmp-reply])
4721 AT_SKIP_IF([test $HAVE_PYTHON = no])
4722 ovn_start
4723
4724 # Logical network:
4725 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4726 # and has switch ls2 (172.16.1.0/24) connected to it.
4727
4728 ovn-nbctl lr-add R1
4729
4730 ovn-nbctl ls-add ls1
4731 ovn-nbctl ls-add ls2
4732
4733 # Connect ls1 to R1
4734 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4735 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4736 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4737
4738 # Connect ls2 to R1
4739 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4740 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4741 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4742
4743 # Create logical port ls1-lp1 in ls1
4744 ovn-nbctl lsp-add ls1 ls1-lp1 \
4745 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4746
4747 # Create logical port ls2-lp1 in ls2
4748 ovn-nbctl lsp-add ls2 ls2-lp1 \
4749 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4750
4751 # Create one hypervisor and create OVS ports corresponding to logical ports.
4752 net_add n1
4753
4754 sim_add hv1
4755 as hv1
4756 ovs-vsctl add-br br-phys
4757 ovn_attach n1 br-phys 192.168.0.1
4758 ovs-vsctl -- add-port br-int vif1 -- \
4759 set interface vif1 external-ids:iface-id=ls1-lp1 \
4760 options:tx_pcap=hv1/vif1-tx.pcap \
4761 options:rxq_pcap=hv1/vif1-rx.pcap \
4762 ofport-request=1
4763
4764 ovs-vsctl -- add-port br-int vif2 -- \
4765 set interface vif2 external-ids:iface-id=ls2-lp1 \
4766 options:tx_pcap=hv1/vif2-tx.pcap \
4767 options:rxq_pcap=hv1/vif2-rx.pcap \
4768 ofport-request=1
4769
4770
4771 # Allow some time for ovn-northd and ovn-controller to catch up.
4772 # XXX This should be more systematic.
4773 sleep 1
4774
4775
4776 ip_to_hex() {
4777 printf "%02x%02x%02x%02x" "$@"
4778 }
4779 for i in 1 2; do
4780 : > vif$i.expected
4781 done
4782 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4783 #
4784 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4785 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4786 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4787 # provided, then it should be the ip and icmp checksums of the packet
4788 # responded; otherwise, no reply is expected.
4789 # In the absence of an ip checksum calculation helpers, this relies
4790 # on the caller to provide the checksums for the ip and icmp headers.
4791 # XXX This should be more systematic.
4792 #
4793 # INPORT is an lport number, e.g. 11 for vif11.
4794 # ETH_SRC and ETH_DST are each 12 hex digits.
4795 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4796 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4797 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4798 test_ipv4_icmp_request() {
4799 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4800 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4801 shift; shift; shift; shift; shift; shift; shift
4802 shift; shift
4803
4804 # Use ttl to exercise section 4.2.2.9 of RFC1812
4805 local ip_ttl=01
4806 local icmp_id=5fbf
4807 local icmp_seq=0001
4808 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4809 local icmp_type_code_request=0800
4810 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4811 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4812
4813 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4814 if test X$exp_icmp_chksum != X; then
4815 # Expect to receive the reply, if any. In same port where packet was sent.
4816 # Note: src and dst fields are expected to be reversed.
4817 local icmp_type_code_response=0000
4818 local reply_icmp_ttl=fe
4819 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4820 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4821 echo $reply >> vif$inport.expected
4822 fi
4823 }
4824
4825 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4826 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4827 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4828 l1_ip=$(ip_to_hex 192 168 1 2)
4829 l2_ip=$(ip_to_hex 172 16 1 2)
4830
4831 # Ping router ip address that is on same subnet as the logical port
4832 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4833 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4834
4835 # Ping router ip address that is on the other side of the logical ports
4836 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4837 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4838
4839 echo "---------NB dump-----"
4840 ovn-nbctl show
4841 echo "---------------------"
4842 ovn-nbctl list logical_router
4843 echo "---------------------"
4844 ovn-nbctl list logical_router_port
4845 echo "---------------------"
4846
4847 echo "---------SB dump-----"
4848 ovn-sbctl list datapath_binding
4849 echo "---------------------"
4850 ovn-sbctl list logical_flow
4851 echo "---------------------"
4852
4853 echo "------ hv1 dump ----------"
4854 as hv1 ovs-ofctl dump-flows br-int
4855
4856 # Now check the packets actually received against the ones expected.
4857 for inport in 1 2; do
4858 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4859 done
4860
4861 OVN_CLEANUP([hv1])
4862
4863 AT_CLEANUP
4864
4865 # 1 hypervisor, 1 port
4866 # make sure that the port state is properly set to up and back down
4867 # when created and deleted.
4868 AT_SETUP([ovn -- port state up and down])
4869 ovn_start
4870
4871 ovn-nbctl ls-add ls1
4872 ovn-nbctl lsp-add ls1 lp1
4873 ovn-nbctl lsp-set-addresses lp1 unknown
4874
4875 net_add n1
4876 sim_add hv1
4877 as hv1 ovs-vsctl add-br br-phys
4878 as hv1 ovn_attach n1 br-phys 192.168.0.1
4879
4880 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4881 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4882
4883 as hv1 ovs-vsctl del-port br-int vif1
4884 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4885
4886 OVN_CLEANUP([hv1])
4887
4888 AT_CLEANUP
4889
4890 # 1 hypervisor, 1 port
4891 # make sure that the OF rules created to support a datapath are added/cleared
4892 # when logical switch is created and removed.
4893 AT_SETUP([ovn -- datapath rules added/removed])
4894 AT_KEYWORDS([cleanup])
4895 ovn_start
4896
4897 net_add n1
4898 sim_add hv1
4899 as hv1 ovs-vsctl add-br br-phys
4900 as hv1 ovn_attach n1 br-phys 192.168.0.1
4901
4902 # This shell function checks if OF rules in br-int have clauses
4903 # related to OVN datapaths. The caller determines if it should find
4904 # a match in the output, or not.
4905 #
4906 # EXPECT_DATAPATH param determines whether flows that refer to
4907 # datapath to should be present or not. 0 means
4908 # they should not be.
4909 # STAGE_INFO param is a simple string to help identify the stage
4910 # in the test when this function was invoked.
4911 test_datapath_in_of_rules() {
4912 local expect_datapath=$1 stage_info=$2
4913 echo "------ ovn-nbctl show ${stage_info} ------"
4914 ovn-nbctl show
4915 echo "------ ovn-sbctl show ${stage_info} ------"
4916 ovn-sbctl show
4917 echo "------ OF rules ${stage_info} ------"
4918 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4919 # if there is a datapath mentioned in the output, check for the
4920 # magic keyword that represents one, based on the exit status of
4921 # a quiet grep
4922 if test $expect_datapath != 0; then
4923 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4924 else
4925 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4926 fi
4927 }
4928
4929 test_datapath_in_of_rules 0 "before ls+port create"
4930
4931 ovn-nbctl ls-add ls1
4932 ovn-nbctl lsp-add ls1 lp1
4933 ovn-nbctl lsp-set-addresses lp1 unknown
4934
4935 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4936 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4937
4938 test_datapath_in_of_rules 1 "after port is bound"
4939
4940 as hv1 ovs-vsctl del-port br-int vif1
4941 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4942
4943 ovn-nbctl lsp-set-addresses lp1
4944 ovn-nbctl lsp-del lp1
4945 ovn-nbctl ls-del ls1
4946
4947 # wait for earlier changes to take effect
4948 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4949
4950 # ensure OF rules are no longer present. There used to be a bug here.
4951 test_datapath_in_of_rules 0 "after lport+ls removal"
4952
4953 OVN_CLEANUP([hv1])
4954
4955 AT_CLEANUP
4956
4957 AT_SETUP([ovn -- nd_na ])
4958 AT_SKIP_IF([test $HAVE_PYTHON = no])
4959 ovn_start
4960
4961 #TODO: since patch port for IPv6 logical router port is not ready not,
4962 # so we are not going to test vifs on different lswitches cases. Try
4963 # to update for that once relevant stuff implemented.
4964
4965 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4966 # with. NS packet we test, from one VIF for another VIF, will be replied
4967 # by local ovn-controller, but not by target VIF.
4968
4969 # Create hypervisors and logical switch lsw0.
4970 ovn-nbctl ls-add lsw0
4971 net_add n1
4972 sim_add hv1
4973 as hv1
4974 ovs-vsctl add-br br-phys
4975 ovn_attach n1 br-phys 192.168.0.2
4976
4977 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4978 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
4979 ovn-nbctl lsp-add lsw0 lp1
4980 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4981 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"
4982
4983 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4984 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
4985 ovn-nbctl lsp-add lsw0 lp2
4986 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4987 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"
4988
4989 # Add ACL rule for ICMPv6 on lsw0
4990 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4991 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4992 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4993
4994 # Allow some time for ovn-northd and ovn-controller to catch up.
4995 # XXX This should be more systematic.
4996 sleep 1
4997
4998 # Given the name of a logical port, prints the name of the hypervisor
4999 # on which it is located.
5000 vif_to_hv() {
5001 echo hv1${1%?}
5002 }
5003 for i in 1 2; do
5004 : > $i.expected
5005 done
5006
5007 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5008 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5009 # vif2 will not receive NS packet, since ovn-controller will reply for it.
5010 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5011 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5012
5013 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
5014 echo $na_packet >> 1.expected
5015
5016 echo "------ hv1 dump ------"
5017 as hv1 ovs-vsctl show
5018 as hv1 ovs-ofctl -O OpenFlow13 show br-int
5019 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5020
5021 for i in 1 2; do
5022 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
5023 done
5024
5025 OVN_CLEANUP([hv1])
5026
5027 AT_CLEANUP
5028
5029 AT_SETUP([ovn -- address sets modification/removal smoke test])
5030 ovn_start
5031
5032 net_add n1
5033
5034 sim_add hv1
5035 as hv1
5036 ovs-vsctl add-br br-phys
5037 ovn_attach n1 br-phys 192.168.0.1
5038
5039 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5040 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5041 ovn-nbctl destroy Address_Set $row
5042
5043 sleep 1
5044
5045 # A bug previously existed in the address set support code
5046 # that caused ovn-controller to crash after an address set
5047 # was updated and then removed. This test case ensures
5048 # that ovn-controller is at least still running after
5049 # creating, updating, and deleting an address set.
5050 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5051
5052 OVN_CLEANUP([hv1])
5053
5054 AT_CLEANUP
5055
5056 AT_SETUP([ovn -- ipam])
5057 AT_SKIP_IF([test $HAVE_PYTHON = no])
5058 ovn_start
5059
5060 # Add a port to a switch that does not have a subnet set, then set the
5061 # subnet which should result in an address being allocated for the port.
5062 ovn-nbctl ls-add sw0
5063 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
5064 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
5065 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5066 ["0a:00:00:00:00:01 192.168.1.2"
5067 ])
5068
5069 # Add 9 more ports to sw0, addresses should all be unique.
5070 for n in `seq 1 9`; do
5071 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
5072 done
5073 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5074 ["0a:00:00:00:00:02 192.168.1.3"
5075 ])
5076 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5077 ["0a:00:00:00:00:03 192.168.1.4"
5078 ])
5079 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5080 ["0a:00:00:00:00:04 192.168.1.5"
5081 ])
5082 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5083 ["0a:00:00:00:00:05 192.168.1.6"
5084 ])
5085 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5086 ["0a:00:00:00:00:06 192.168.1.7"
5087 ])
5088 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5089 ["0a:00:00:00:00:07 192.168.1.8"
5090 ])
5091 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5092 ["0a:00:00:00:00:08 192.168.1.9"
5093 ])
5094 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5095 ["0a:00:00:00:00:09 192.168.1.10"
5096 ])
5097 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5098 ["0a:00:00:00:00:0a 192.168.1.11"
5099 ])
5100
5101 # Trying similar tests with a second switch. MAC addresses should be unique
5102 # across both switches but IP's only need to be unique within the same switch.
5103 ovn-nbctl ls-add sw1
5104 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
5105 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
5106 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
5107 ["0a:00:00:00:00:0b 192.168.1.2"
5108 ])
5109
5110 for n in `seq 11 19`; do
5111 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
5112 done
5113 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5114 ["0a:00:00:00:00:0c 192.168.1.3"
5115 ])
5116 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5117 ["0a:00:00:00:00:0d 192.168.1.4"
5118 ])
5119 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5120 ["0a:00:00:00:00:0e 192.168.1.5"
5121 ])
5122 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5123 ["0a:00:00:00:00:0f 192.168.1.6"
5124 ])
5125 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5126 ["0a:00:00:00:00:10 192.168.1.7"
5127 ])
5128 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5129 ["0a:00:00:00:00:11 192.168.1.8"
5130 ])
5131 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5132 ["0a:00:00:00:00:12 192.168.1.9"
5133 ])
5134 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5135 ["0a:00:00:00:00:13 192.168.1.10"
5136 ])
5137 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5138 ["0a:00:00:00:00:14 192.168.1.11"
5139 ])
5140
5141 # Change a port's address to test for multiple ip's for a single address entry
5142 # and addresses set by the user.
5143 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
5144 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
5145 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5146 ["0a:00:00:00:00:16 192.168.1.13"
5147 ])
5148
5149 # Test for logical router port address management.
5150 ovn-nbctl create Logical_Router name=R1
5151 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5152 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5153 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5154 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
5155 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
5156 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5157 ["0a:00:00:00:00:18 192.168.1.15"
5158 ])
5159
5160 # Test for address reuse after logical port is deleted.
5161 ovn-nbctl lsp-del p0
5162 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
5163 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5164 ["0a:00:00:00:00:19 192.168.1.2"
5165 ])
5166
5167 # Test for multiple addresses to one logical port.
5168 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5169 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
5170 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
5171 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5172 ["0a:00:00:00:00:1c 192.168.1.16"
5173 ])
5174
5175 # Test for exhausting subnet address space.
5176 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
5177 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
5178 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5179 ["0a:00:00:00:00:1d 172.16.1.2"
5180 ])
5181
5182 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
5183 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
5184 ["0a:00:00:00:00:1e"
5185 ])
5186
5187 # Test that address management does not add duplicate MAC for lsp/lrp peers.
5188 ovn-nbctl create Logical_Router name=R2
5189 ovn-nbctl ls-add sw3
5190 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
5191 "0a:00:00:00:00:1f"
5192 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5193 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5194 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5195 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
5196 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
5197 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5198 ["0a:00:00:00:00:20 192.168.1.17"
5199 ])
5200
5201 # Test static MAC address with dynamically allocated IP
5202 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5203 "fe:dc:ba:98:76:54 dynamic"
5204 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5205 ["fe:dc:ba:98:76:54 192.168.1.18"
5206 ])
5207
5208 # Update the static MAC address with dynamically allocated IP and check
5209 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5210 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5211 ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5212
5213 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5214 ["fe:dc:ba:98:76:55 192.168.1.18"
5215 ])
5216
5217 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5218 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5219 ["fe:dc:ba:98:76:55 192.168.1.18"
5220 ])
5221
5222 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5223 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5224 ["fe:dc:ba:98:76:56 192.168.1.18"
5225 ])
5226
5227
5228 # Test the exclude_ips from the IPAM list
5229 ovn-nbctl --wait=sb set logical_switch sw0 \
5230 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5231
5232 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5233 "dynamic"
5234 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5235 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5236 ["0a:00:00:00:00:21 192.168.1.20"
5237 ])
5238
5239 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5240 "dynamic"
5241 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5242 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5243 ["0a:00:00:00:00:22 192.168.1.22"
5244 ])
5245
5246 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5247 "dynamic"
5248 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5249 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5250 ["0a:00:00:00:00:23 192.168.1.51"
5251 ])
5252
5253 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5254 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5255 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5256 "dynamic"
5257 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5258 ["0a:00:00:00:00:24 192.168.1.19"
5259 ])
5260
5261 # Set invalid data in exclude_ips list. It should be ignored.
5262 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5263 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5264 "dynamic"
5265 # 192.168.1.21 should be assigned as that's the next free one.
5266 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5267 ["0a:00:00:00:00:25 192.168.1.21"
5268 ])
5269
5270 # Clear the dynamic addresses assignment request.
5271 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5272 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5273 [[[]]
5274 ])
5275
5276 # Set IPv6 prefix
5277 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5278 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5279 "dynamic"
5280
5281 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5282 # - aef0::800:ff:fe00:26 (EUI64)
5283 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5284 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5285 ])
5286
5287 ovn-nbctl --wait=sb ls-add sw4
5288 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5289 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5290 "dynamic"
5291
5292 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5293 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5294 ])
5295
5296 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5297 "f0:00:00:00:10:12 dynamic"
5298
5299 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5300 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5301 ])
5302
5303 # Clear the other_config for sw4. No dynamic ip should be assigned.
5304 ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5305 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5306 "dynamic"
5307
5308 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5309 [[[]]
5310 ])
5311
5312 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5313 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5314 -- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5315
5316 # Now p40 should be assigned with dynamic addresses.
5317 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5318 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5319 ])
5320
5321 ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5322 "dynamic"
5323 # p41 should not have IPv4 address (as the pool is exhausted).
5324 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5325 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5326 ])
5327
5328 as ovn-sb
5329 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5330
5331 as ovn-nb
5332 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5333
5334 as northd
5335 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5336
5337 AT_CLEANUP
5338
5339 AT_SETUP([ovn -- ipam connectivity])
5340 AT_SKIP_IF([test $HAVE_PYTHON = no])
5341 ovn_start
5342
5343 ovn-nbctl lr-add R1
5344
5345 # Test for a ping using dynamically allocated addresses.
5346 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5347 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5348
5349 # Connect foo to R1
5350 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5351 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5352 options:router-port=foo \
5353 -- lsp-set-addresses rp-foo router
5354
5355 # Connect alice to R1
5356 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5357 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5358 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5359
5360 # Create logical port foo1 in foo
5361 ovn-nbctl --wait=sb lsp-add foo foo1 \
5362 -- lsp-set-addresses foo1 "dynamic"
5363 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:00:00:01 192.168.1.2"'], [0])
5364
5365 # Create logical port alice1 in alice
5366 ovn-nbctl --wait=sb lsp-add alice alice1 \
5367 -- lsp-set-addresses alice1 "dynamic"
5368 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5369
5370 # Create logical port foo2 in foo
5371 ovn-nbctl --wait=sb lsp-add foo foo2 \
5372 -- lsp-set-addresses foo2 "dynamic"
5373 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5374
5375 # Create a hypervisor and create OVS ports corresponding to logical ports.
5376 net_add n1
5377
5378 sim_add hv1
5379 as hv1
5380 ovs-vsctl add-br br-phys
5381 ovn_attach n1 br-phys 192.168.0.1
5382 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5383 set interface hv1-vif1 external-ids:iface-id=foo1 \
5384 options:tx_pcap=hv1/vif1-tx.pcap \
5385 options:rxq_pcap=hv1/vif1-rx.pcap \
5386 ofport-request=1
5387
5388 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5389 set interface hv1-vif2 external-ids:iface-id=foo2 \
5390 options:tx_pcap=hv1/vif2-tx.pcap \
5391 options:rxq_pcap=hv1/vif2-rx.pcap \
5392 ofport-request=2
5393
5394 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5395 set interface hv1-vif3 external-ids:iface-id=alice1 \
5396 options:tx_pcap=hv1/vif3-tx.pcap \
5397 options:rxq_pcap=hv1/vif3-rx.pcap \
5398 ofport-request=3
5399
5400 # Allow some time for ovn-northd and ovn-controller to catch up.
5401 # XXX This should be more systematic.
5402 sleep 1
5403
5404 ip_to_hex() {
5405 printf "%02x%02x%02x%02x" "$@"
5406 }
5407
5408 # Send ip packets between foo1 and foo2
5409 src_mac="0a0000000001"
5410 dst_mac="0a0000000003"
5411 src_ip=`ip_to_hex 192 168 1 2`
5412 dst_ip=`ip_to_hex 192 168 1 3`
5413 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5414 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5415
5416 # Send ip packets between foo1 and alice1
5417 src_mac="0a0000000001"
5418 dst_mac="000000010203"
5419 src_ip=`ip_to_hex 192 168 1 2`
5420 dst_ip=`ip_to_hex 192 168 2 2`
5421 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5422 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5423
5424 echo "---------NB dump-----"
5425 ovn-nbctl show
5426 echo "---------------------"
5427 ovn-nbctl list logical_router
5428 echo "---------------------"
5429 ovn-nbctl list logical_router_port
5430 echo "---------------------"
5431
5432 echo "---------SB dump-----"
5433 ovn-sbctl list datapath_binding
5434 echo "---------------------"
5435 ovn-sbctl list port_binding
5436 echo "---------------------"
5437
5438 echo "------ hv1 dump ----------"
5439 as hv1 ovs-ofctl dump-flows br-int
5440
5441 # Packet to Expect at foo2
5442 src_mac="0a0000000001"
5443 dst_mac="0a0000000003"
5444 src_ip=`ip_to_hex 192 168 1 2`
5445 dst_ip=`ip_to_hex 192 168 1 3`
5446 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5447
5448 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5449 echo $expected > expout
5450 AT_CHECK([cat received1.packets], [0], [expout])
5451
5452 # Packet to Expect at alice1
5453 src_mac="000000010204"
5454 dst_mac="0a0000000002"
5455 src_ip=`ip_to_hex 192 168 1 2`
5456 dst_ip=`ip_to_hex 192 168 2 2`
5457 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5458
5459 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5460 echo $expected > expout
5461 AT_CHECK([cat received2.packets], [0], [expout])
5462
5463 OVN_CLEANUP([hv1])
5464
5465 AT_CLEANUP
5466
5467 AT_SETUP([ovn -- ovs-vswitchd restart])
5468 AT_KEYWORDS([vswitchd])
5469 AT_SKIP_IF([test $HAVE_PYTHON = no])
5470 ovn_start
5471
5472 ovn-nbctl ls-add ls1
5473
5474 ovn-nbctl lsp-add ls1 ls1-lp1 \
5475 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5476
5477 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5478
5479 net_add n1
5480 sim_add hv1
5481
5482 as hv1
5483 ovs-vsctl add-br br-phys
5484 ovn_attach n1 br-phys 192.168.0.1
5485 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5486 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5487 options:tx_pcap=hv1/vif1-tx.pcap \
5488 options:rxq_pcap=hv1/vif1-rx.pcap \
5489 ofport-request=1
5490
5491 OVN_POPULATE_ARP
5492 sleep 2
5493
5494 as hv1 ovs-vsctl show
5495
5496 echo "---------------------"
5497 ovn-sbctl dump-flows
5498 echo "---------------------"
5499
5500 echo "------ hv1 dump ----------"
5501 as hv1 ovs-ofctl dump-flows br-int
5502 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5503
5504 echo "Total flows before vswitchd restart = " $total_flows
5505
5506 # Code taken from ovs-save utility
5507 save_flows () {
5508 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5509 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5510 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5511 echo "EOF" >> restore_flows.sh
5512 }
5513
5514 restart_vswitchd () {
5515 restore_flows=$1
5516
5517 if test $restore_flows = true; then
5518 save_flows
5519 fi
5520
5521 as hv1
5522 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5523
5524 if test $restore_flows = true; then
5525 as hv1
5526 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5527 fi
5528
5529 as hv1
5530 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5531 ovs-ofctl dump-flows br-int
5532
5533 if test $restore_flows = true; then
5534 sh ./restore_flows.sh
5535 echo "Flows after restore"
5536 as hv1
5537 ovs-ofctl dump-flows br-int
5538 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5539 flow-restore-wait="true"
5540 fi
5541 }
5542
5543 # Save the flows, restart vswitchd and restore the flows
5544 restart_vswitchd true
5545 OVS_WAIT_UNTIL([
5546 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5547 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5548 test "${total_flows}" = "${total_flows_after_restart}"
5549 ])
5550
5551 # Restart vswitchd without restoring
5552 restart_vswitchd false
5553 OVS_WAIT_UNTIL([
5554 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5555 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5556 test "${total_flows}" = "${total_flows_after_restart}"
5557 ])
5558
5559 OVN_CLEANUP([hv1])
5560 AT_CLEANUP
5561
5562 AT_SETUP([ovn -- send arp for nexthop])
5563 AT_SKIP_IF([test $HAVE_PYTHON = no])
5564 ovn_start
5565
5566 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5567
5568 # Create logical switches
5569 ovn-nbctl ls-add ls1
5570 ovn-nbctl ls-add ls2
5571
5572 # Create router
5573 ovn-nbctl create Logical_Router name=lr0
5574
5575 # Add router ls1p1 port to gateway router
5576 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5577 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5578 type=router options:router-port=lrp-ls1lp1 \
5579 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5580
5581 # Add router ls2p2 port to gateway router
5582 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5583 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5584 type=router options:router-port=lrp-ls2lp1 \
5585 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5586
5587 # Set default gateway (nexthop) to 192.168.1.254
5588 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5589
5590 # Create logical port ls1lp2 in ls1
5591 ovn-nbctl lsp-add ls1 ls1lp2 \
5592 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5593
5594 # Create logical port ls2lp2 in ls2
5595 ovn-nbctl lsp-add ls2 ls2lp2 \
5596 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5597
5598 net_add n1
5599 sim_add hv1
5600 as hv1
5601 ovs-vsctl add-br br-phys
5602 ovn_attach n1 br-phys 192.168.0.1
5603 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5604 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5605 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5606 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5607 ofport-request=1
5608 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5609 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5610 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5611 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5612 ofport-request=2
5613
5614 # Allow some time for ovn-northd and ovn-controller to catch up.
5615 # XXX This should be more systematic.
5616 sleep 1
5617
5618 echo "---------NB dump-----"
5619 ovn-nbctl show
5620 echo "---------------------"
5621 ovn-nbctl list logical_router
5622 echo "---------------------"
5623 ovn-nbctl list logical_router_port
5624 echo "---------------------"
5625
5626 echo "---------SB dump-----"
5627 ovn-sbctl list datapath_binding
5628 echo "---------------------"
5629 ovn-sbctl list port_binding
5630 echo "---------------------"
5631 ovn-sbctl dump-flows
5632 echo "---------------------"
5633 ovn-sbctl list chassis
5634 ovn-sbctl list encap
5635 echo "---------------------"
5636
5637 echo "------Flows dump-----"
5638 as hv1
5639 ovs-ofctl dump-flows
5640 echo "---------------------"
5641
5642 ip_to_hex() {
5643 printf "%02x%02x%02x%02x" "$@"
5644 }
5645
5646 src_mac="f00000000003"
5647 dst_mac="f00000000001"
5648 src_ip=`ip_to_hex 192 168 0 2`
5649 dst_ip=`ip_to_hex 8 8 8 8`
5650 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5651
5652 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5653 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5654
5655 trim_zeros() {
5656 sed 's/\(00\)\{1,\}$//'
5657 }
5658
5659 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5660 # not 8.8.8.8
5661
5662 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5663 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5664 echo $expected > expout
5665 AT_CHECK([cat packets], [0], [expout])
5666 cat packets
5667
5668 OVN_CLEANUP([hv1])
5669
5670 AT_CLEANUP
5671
5672 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5673 AT_SKIP_IF([test $HAVE_PYTHON = no])
5674 ovn_start
5675 # Create logical switch
5676 ovn-nbctl ls-add ls0
5677 # Create gateway router
5678 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5679 # Add router port to gateway router
5680 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5681 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5682 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5683 # Add nat-address option
5684 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5685
5686 net_add n1
5687 sim_add hv1
5688 as hv1
5689 ovs-vsctl \
5690 -- add-br br-phys \
5691 -- add-br br-eth0
5692
5693 ovn_attach n1 br-phys 192.168.0.1
5694
5695 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5696 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])
5697
5698 # Create a localnet port.
5699 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5700 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5701 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5702 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5703
5704
5705 # Wait for packet to be received.
5706 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5707 trim_zeros() {
5708 sed 's/\(00\)\{1,\}$//'
5709 }
5710 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5711 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5712 echo $expected > expout
5713 AT_CHECK([sort packets], [0], [expout])
5714 cat packets
5715
5716 OVN_CLEANUP([hv1])
5717
5718 AT_CLEANUP
5719
5720 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5721 AT_SKIP_IF([test $HAVE_PYTHON = no])
5722 ovn_start
5723 # Create logical switch
5724 ovn-nbctl ls-add ls0
5725 # Create gateway router
5726 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5727 # Add router port to gateway router
5728 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5729 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5730 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5731 # Add nat-address option
5732 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5733 # Add NAT rules
5734 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5735 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5736 # Add load balancers
5737 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5738 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5739 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5740 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5741
5742 net_add n1
5743 sim_add hv1
5744 as hv1
5745 ovs-vsctl \
5746 -- add-br br-phys \
5747 -- add-br br-eth0
5748
5749 ovn_attach n1 br-phys 192.168.0.1
5750
5751 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5752 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])
5753
5754 # Create a localnet port.
5755 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5756 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5757 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5758 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5759
5760
5761 # Wait for packet to be received.
5762 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5763 trim_zeros() {
5764 sed 's/\(00\)\{1,\}$//'
5765 }
5766 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5767 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5768 echo $expected > expout
5769 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5770 echo $expected >> expout
5771 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5772 echo $expected >> expout
5773 AT_CHECK([sort packets], [0], [expout])
5774 cat packets
5775
5776 OVN_CLEANUP([hv1])
5777
5778 AT_CLEANUP
5779
5780 AT_SETUP([ovn -- delete mac bindings])
5781 ovn_start
5782 net_add n1
5783 sim_add hv1
5784 as hv1
5785 ovs-vsctl -- add-br br-phys
5786 ovn_attach n1 br-phys 192.168.0.1
5787 # Create logical switch ls0
5788 ovn-nbctl ls-add ls0
5789 # Create ports lp0, lp1 in ls0
5790 ovn-nbctl lsp-add ls0 lp0
5791 ovn-nbctl lsp-add ls0 lp1
5792 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5793 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5794 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5795 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5796 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5797 ovn-sbctl find MAC_Binding
5798 # Delete port lp0 and check that its MAC_Binding is deleted.
5799 ovn-nbctl lsp-del lp0
5800 ovn-sbctl find MAC_Binding
5801 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5802 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5803 ovn-nbctl ls-del ls0
5804 ovn-sbctl find MAC_Binding
5805 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5806
5807 OVN_CLEANUP([hv1])
5808
5809 AT_CLEANUP
5810
5811 AT_SETUP([ovn -- conntrack zone allocation])
5812 AT_SKIP_IF([test $HAVE_PYTHON = no])
5813 ovn_start
5814
5815 # Logical network:
5816 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5817 # connected to a router R1.
5818 # foo has foo1 to act as a client.
5819 # bar has bar1, bar2, bar3 to act as servers.
5820
5821 net_add n1
5822
5823 sim_add hv1
5824 as hv1
5825 ovs-vsctl add-br br-phys
5826 ovn_attach n1 br-phys 192.168.0.1
5827 for i in foo1 bar1 bar2 bar3; do
5828 ovs-vsctl -- add-port br-int $i -- \
5829 set interface $i external-ids:iface-id=$i \
5830 options:tx_pcap=hv1/$i-tx.pcap \
5831 options:rxq_pcap=hv1/$i-rx.pcap
5832 done
5833
5834 ovn-nbctl create Logical_Router name=R1
5835 ovn-nbctl ls-add foo
5836 ovn-nbctl ls-add bar
5837
5838 # Connect foo to R1
5839 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5840 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5841 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5842
5843 # Connect bar to R1
5844 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5845 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5846 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5847
5848 # Create logical port foo1 in foo
5849 ovn-nbctl lsp-add foo foo1 \
5850 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5851
5852 # Create logical port bar1, bar2 and bar3 in bar
5853 for i in `seq 1 3`; do
5854 ip=`expr $i + 1`
5855 ovn-nbctl lsp-add bar bar$i \
5856 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5857 done
5858
5859 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5860
5861 OVN_CLEANUP([hv1])
5862
5863 AT_CLEANUP
5864
5865 AT_SETUP([ovn -- tag allocation])
5866 ovn_start
5867
5868 AT_CHECK([ovn-nbctl ls-add ls0])
5869 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5870 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5871 AT_CHECK([ovn-nbctl ls-add ls1])
5872
5873 dnl When a tag is provided, no allocation is done
5874 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5875 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5876 ])
5877 dnl The same 'tag' gets created in southbound database.
5878 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5879 logical_port="c0"], [0], [3
5880 ])
5881
5882 dnl Allocate tags and see it getting created in both NB and SB
5883 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5884 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5885 ])
5886 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5887 logical_port="c1"], [0], [1
5888 ])
5889
5890 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5891 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5892 ])
5893 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5894 logical_port="c2"], [0], [2
5895 ])
5896 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5897 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5898 ])
5899 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5900 logical_port="c3"], [0], [4
5901 ])
5902
5903 dnl A different parent.
5904 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5905 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5906 ])
5907 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5908 logical_port="c4"], [0], [1
5909 ])
5910
5911 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5912 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5913 ])
5914 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5915 logical_port="c5"], [0], [2
5916 ])
5917
5918 dnl Delete a logical port and create a new one.
5919 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5920 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5921 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5922 ])
5923 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5924 logical_port="c6"], [0], [1
5925 ])
5926
5927 dnl Restart northd to see that the same allocation remains.
5928 as northd
5929 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5930 start_daemon ovn-northd \
5931 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5932 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5933
5934 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5935 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5936 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5937 ])
5938 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5939 ])
5940 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5941 ])
5942 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5943 ])
5944 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5945 ])
5946 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5947 ])
5948
5949 dnl Create a switch port with a tag that has already been allocated.
5950 dnl It should go through fine with a duplicate tag.
5951 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5952 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5953 ])
5954 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5955 logical_port="c7"], [0], [2
5956 ])
5957 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5958 ])
5959
5960 AT_CHECK([ovn-nbctl ls-add ls2])
5961 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5962 dnl gets copied to 'tag'
5963 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5964 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5965 ])
5966 dnl The same 'tag' gets created in southbound database.
5967 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5968 logical_port="local0"], [0], [25
5969 ])
5970 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5971 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5972 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5973 dnl change the tag_request.
5974 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5975 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5976 ])
5977
5978 AT_CLEANUP
5979
5980 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5981 ovn_start
5982 ovn-nbctl ls-add lsw0
5983 net_add n1
5984 for i in 1 2; do
5985 sim_add hv$i
5986 as hv$i
5987 ovs-vsctl add-br br-phys
5988 ovn_attach n1 br-phys 192.168.0.$i
5989 ovs-vsctl add-br br-eth0
5990 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5991 done
5992
5993 # Create a localnet port.
5994 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5995 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5996 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5997 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5998
5999
6000 # Create 3 vifs.
6001 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6002 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6003 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6004 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
6005 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
6006 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6007 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6008 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6009 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6010
6011 # Bind the localvif1 to hv1.
6012 as hv1
6013 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6014
6015 # On hv1, check that there are no flows outputting bcast to tunnel
6016 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6017
6018 # On hv2, check that no flow outputs bcast to tunnel to hv1.
6019 as hv2
6020 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6021
6022 # Now bind vif2 on hv2.
6023 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6024
6025 # At this point, the broadcast flow on vif2 should be deleted.
6026 # because, there is now a localnet vif bound (table=32 programming logic)
6027 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6028
6029 # Verify that the local net patch port exists on hv2.
6030 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6031
6032 # Now bind vif3 on hv2.
6033 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6034
6035 # Verify that the local net patch port still exists on hv2
6036 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6037
6038 # Delete localvif2
6039 AT_CHECK([ovn-nbctl lsp-del localvif2])
6040
6041 # Verify that the local net patch port still exists on hv2,
6042 # because, localvif3 is still bound.
6043 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6044
6045 OVN_CLEANUP([hv1],[hv2])
6046
6047 AT_CLEANUP
6048
6049
6050 AT_SETUP([ovn -- ACL logging])
6051 AT_KEYWORDS([ovn])
6052 ovn_start
6053
6054 net_add n1
6055
6056 sim_add hv
6057 as hv
6058 ovs-vsctl add-br br-phys
6059 ovn_attach n1 br-phys 192.168.0.1
6060 for i in lp1 lp2; do
6061 ovs-vsctl -- add-port br-int $i -- \
6062 set interface $i external-ids:iface-id=$i \
6063 options:tx_pcap=hv/$i-tx.pcap \
6064 options:rxq_pcap=hv/$i-rx.pcap
6065 done
6066
6067 lp1_mac="f0:00:00:00:00:01"
6068 lp1_ip="192.168.1.2"
6069
6070 lp2_mac="f0:00:00:00:00:02"
6071 lp2_ip="192.168.1.3"
6072
6073 ovn-nbctl ls-add lsw0
6074 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6075 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6076 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6077 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6078 ovn-nbctl --wait=sb sync
6079
6080 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6081 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6082
6083 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6084 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6085
6086 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6087 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6088
6089 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6090 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6091
6092 ovn-sbctl dump-flows
6093
6094
6095 # Send packet that should be dropped without logging.
6096 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6097 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6098 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6099 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6100
6101 # Send packet that should be dropped with logging.
6102 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6103 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6104 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6105 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6106
6107 # Send packet that should be allowed without logging.
6108 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6109 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6110 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6111 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6112
6113 # Send packet that should be allowed with logging.
6114 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6115 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6116 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6117 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6118
6119 # Send packet that should allow related flows without logging.
6120 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6121 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6122 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6123 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6124
6125 # Send packet that should allow related flows with logging.
6126 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6127 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6128 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6129 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6130
6131 # Send packet that should be rejected without logging.
6132 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6133 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6134 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6135 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6136
6137 # Send packet that should be rejected with logging.
6138 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6139 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6140 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6141 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6142
6143 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6144
6145 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6146 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
6147 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
6148 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
6149 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
6150 ])
6151
6152 OVN_CLEANUP([hv])
6153 AT_CLEANUP
6154
6155
6156 AT_SETUP([ovn -- DSCP marking and meter check])
6157 AT_KEYWORDS([ovn])
6158 ovn_start
6159
6160 ovn-nbctl ls-add lsw0
6161 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6162 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6163 ovn-nbctl --wait=sb lsp-add lsw0 lp3
6164 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6165 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
6166 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
6167 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6168 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6169 ovn-nbctl --wait=sb sync
6170 net_add n1
6171 sim_add hv
6172 as hv
6173 ovs-vsctl add-br br-phys
6174 ovn_attach n1 br-phys 192.168.0.1
6175 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
6176 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
6177
6178 AT_CAPTURE_FILE([trace])
6179 ovn_trace () {
6180 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6181 }
6182
6183 # Extracts nw_tos from the final flow from ofproto/trace output and prints
6184 # it on stdout. Prints "none" if no nw_tos was included.
6185 get_final_nw_tos() {
6186 if flow=$(grep '^Final flow:' stdout); then :; else
6187 # The output didn't have a final flow.
6188 return 99
6189 fi
6190
6191 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6192 case $tos in
6193 '') echo none ;;
6194 *) echo $tos ;;
6195 esac
6196 }
6197
6198 # check_tos TOS
6199 #
6200 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6201 check_tos() {
6202 # First check with ovn-trace for logical flows.
6203 echo "checking for tos $1"
6204 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6205 echo 'output("lp2");') > expout
6206 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])
6207
6208 # Then re-check with ofproto/trace for a physical packet.
6209 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])
6210 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6211 ])
6212 }
6213
6214 # check at L2
6215 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");
6216 ])
6217 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])
6218 AT_CHECK([get_final_nw_tos], [0], [none
6219 ])
6220
6221 # check at L3 without dscp marking
6222 check_tos 0
6223
6224 # Mark DSCP with a valid value
6225 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)
6226 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6227 ])
6228 check_tos 48
6229
6230 # check at hv without qos meter
6231 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6232 ])
6233
6234 # Update the meter rate
6235 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6236
6237 # check at hv with a qos meter table
6238 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6239 ])
6240 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6241 ])
6242
6243 # Update the DSCP marking
6244 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6245 check_tos 63
6246
6247 # Update the meter rate
6248 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6249
6250 # check at hv with a qos meter table
6251 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6252 ])
6253 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6254 ])
6255
6256 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6257 check_tos 63
6258
6259 # Disable DSCP marking
6260 ovn-nbctl --wait=hv qos-del lsw0
6261 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6262 ])
6263 check_tos 0
6264
6265 # check at hv without qos meter
6266 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6267 ])
6268
6269 # check meter with chassis not resident
6270 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6271 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6272 ])
6273
6274 # check no meter table
6275 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6276 ])
6277 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6278 ])
6279
6280 OVN_CLEANUP([hv])
6281 AT_CLEANUP
6282
6283 AT_SETUP([ovn -- read-only sb db:ptcp access])
6284 AT_SKIP_IF([test $HAVE_PYTHON = no])
6285
6286 : > .$1.db.~lock~
6287 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6288
6289 # Add read-only remote to sb ovsdb-server
6290 AT_CHECK(
6291 [ovsdb-tool transact ovn-sb.db \
6292 ['["OVN_Southbound",
6293 {"op": "insert",
6294 "table": "SB_Global",
6295 "row": {
6296 "connections": ["set", [["named-uuid", "xyz"]]]}},
6297 {"op": "insert",
6298 "table": "Connection",
6299 "uuid-name": "xyz",
6300 "row": {"target": "ptcp:0:127.0.0.1",
6301 "read_only": true}}]']], [0], [ignore], [ignore])
6302
6303 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6304
6305 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6306
6307 # read-only accesses should succeed
6308 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6309 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6310
6311 # write access should fail
6312 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6313 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6314 ])
6315
6316 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6317 AT_CLEANUP
6318
6319 AT_SETUP([ovn -- read-only sb db:pssl access])
6320 AT_SKIP_IF([test $HAVE_PYTHON = no])
6321 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6322 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6323 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6324 \\]"])
6325
6326 : > .$1.db.~lock~
6327 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6328
6329 # Add read-only remote to sb ovsdb-server
6330 AT_CHECK(
6331 [ovsdb-tool transact ovn-sb.db \
6332 ['["OVN_Southbound",
6333 {"op": "insert",
6334 "table": "SB_Global",
6335 "row": {
6336 "connections": ["set", [["named-uuid", "xyz"]]]}},
6337 {"op": "insert",
6338 "table": "Connection",
6339 "uuid-name": "xyz",
6340 "row": {"target": "pssl:0:127.0.0.1",
6341 "read_only": true}}]']], [0], [ignore], [ignore])
6342
6343 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6344 --remote=db:OVN_Southbound,SB_Global,connections \
6345 --private-key="$PKIDIR/testpki-privkey2.pem" \
6346 --certificate="$PKIDIR/testpki-cert2.pem" \
6347 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6348 ovn-sb.db
6349
6350 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6351
6352 # read-only accesses should succeed
6353 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6354 --private-key=$PKIDIR/testpki-privkey.pem \
6355 --certificate=$PKIDIR/testpki-cert.pem \
6356 --ca-cert=$PKIDIR/testpki-cacert.pem \
6357 list SB_Global], [0], [stdout], [ignore])
6358 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6359 --private-key=$PKIDIR/testpki-privkey.pem \
6360 --certificate=$PKIDIR/testpki-cert.pem \
6361 --ca-cert=$PKIDIR/testpki-cacert.pem \
6362 list Connection], [0], [stdout], [ignore])
6363
6364 # write access should fail
6365 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6366 --private-key=$PKIDIR/testpki-privkey.pem \
6367 --certificate=$PKIDIR/testpki-cert.pem \
6368 --ca-cert=$PKIDIR/testpki-cacert.pem \
6369 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6370 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6371 ])
6372
6373 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6374 AT_CLEANUP
6375
6376 AT_SETUP([ovn -- nb connection/ssl commands])
6377 AT_SKIP_IF([test $HAVE_PYTHON = no])
6378 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6379 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6380 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6381 \\]"])
6382
6383 : > .$1.db.~lock~
6384 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6385
6386 # Start nb db server using db connection/ssl entries (unpopulated initially)
6387 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6388 --remote=db:OVN_Northbound,NB_Global,connections \
6389 --private-key=db:OVN_Northbound,SSL,private_key \
6390 --certificate=db:OVN_Northbound,SSL,certificate \
6391 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6392 ovn-nb.db
6393
6394 # Populate SSL configuration entries in nb db
6395 AT_CHECK(
6396 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6397 $PKIDIR/testpki-cert.pem \
6398 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6399
6400 # Populate a passive SSL connection in nb db
6401 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6402
6403 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6404
6405 # Verify SSL connetivity to nb db server
6406 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6407 --private-key=$PKIDIR/testpki-privkey.pem \
6408 --certificate=$PKIDIR/testpki-cert.pem \
6409 --ca-cert=$PKIDIR/testpki-cacert.pem \
6410 list NB_Global],
6411 [0], [stdout], [ignore])
6412 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6413 --private-key=$PKIDIR/testpki-privkey.pem \
6414 --certificate=$PKIDIR/testpki-cert.pem \
6415 --ca-cert=$PKIDIR/testpki-cacert.pem \
6416 list Connection],
6417 [0], [stdout], [ignore])
6418 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6419 --private-key=$PKIDIR/testpki-privkey.pem \
6420 --certificate=$PKIDIR/testpki-cert.pem \
6421 --ca-cert=$PKIDIR/testpki-cacert.pem \
6422 get-connection],
6423 [0], [stdout], [ignore])
6424
6425 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6426 AT_CLEANUP
6427
6428 AT_SETUP([ovn -- sb connection/ssl commands])
6429 AT_SKIP_IF([test $HAVE_PYTHON = no])
6430 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6431 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6432 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6433 \\]"])
6434
6435 : > .$1.db.~lock~
6436 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6437
6438 # Start sb db server using db connection/ssl entries (unpopulated initially)
6439 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6440 --remote=db:OVN_Southbound,SB_Global,connections \
6441 --private-key=db:OVN_Southbound,SSL,private_key \
6442 --certificate=db:OVN_Southbound,SSL,certificate \
6443 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6444 ovn-sb.db
6445
6446 # Populate SSL configuration entries in sb db
6447 AT_CHECK(
6448 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6449 $PKIDIR/testpki-cert.pem \
6450 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6451
6452 # Populate a passive SSL connection in sb db
6453 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6454
6455 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6456
6457 # Verify SSL connetivity to sb db server
6458 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6459 --private-key=$PKIDIR/testpki-privkey.pem \
6460 --certificate=$PKIDIR/testpki-cert.pem \
6461 --ca-cert=$PKIDIR/testpki-cacert.pem \
6462 list SB_Global],
6463 [0], [stdout], [ignore])
6464 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6465 --private-key=$PKIDIR/testpki-privkey.pem \
6466 --certificate=$PKIDIR/testpki-cert.pem \
6467 --ca-cert=$PKIDIR/testpki-cacert.pem \
6468 list Connection],
6469 [0], [stdout], [ignore])
6470 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6471 --private-key=$PKIDIR/testpki-privkey.pem \
6472 --certificate=$PKIDIR/testpki-cert.pem \
6473 --ca-cert=$PKIDIR/testpki-cacert.pem \
6474 get-connection],
6475 [0], [stdout], [ignore])
6476
6477 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6478 AT_CLEANUP
6479
6480 AT_SETUP([ovn -- nested containers])
6481 ovn_start
6482
6483 # Physical network:
6484 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6485
6486 # Logical network:
6487 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6488 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6489
6490 ovn-nbctl lr-add R1
6491 ovn-nbctl ls-add mgmt
6492 ovn-nbctl ls-add foo
6493 ovn-nbctl ls-add bar
6494
6495 # Connect mgmt to R1
6496 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6497 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6498 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6499
6500 # Connect foo to R1
6501 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6502 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6503 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6504
6505 # Connect bar to R1
6506 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6507 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6508 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6509
6510 # "mgmt" has VM1 and VM2 connected
6511 ovn-nbctl lsp-add mgmt vm1 \
6512 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6513
6514 ovn-nbctl lsp-add mgmt vm2 \
6515 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6516
6517 # "foo1" and "foo2" are containers belonging to switch "foo"
6518 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6519 ovn-nbctl lsp-add foo foo1 vm1 1 \
6520 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6521
6522 ovn-nbctl lsp-add foo foo2 vm2 2 \
6523 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6524
6525 # "bar1" and "bar2" are containers belonging to switch "bar"
6526 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6527 ovn-nbctl lsp-add bar bar1 vm1 2 \
6528 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6529
6530 ovn-nbctl lsp-add bar bar2 vm2 1 \
6531 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6532
6533 # bar3 is a standalone VM belonging to switch "bar"
6534 ovn-nbctl lsp-add bar bar3 \
6535 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6536
6537 # Create two hypervisor and create OVS ports corresponding to logical ports.
6538 net_add n1
6539
6540 sim_add hv1
6541 as hv1
6542 ovs-vsctl add-br br-phys
6543 ovn_attach n1 br-phys 192.168.0.1
6544 ovs-vsctl -- add-port br-int vm1 -- \
6545 set interface vm1 external-ids:iface-id=vm1 \
6546 options:tx_pcap=hv1/vm1-tx.pcap \
6547 options:rxq_pcap=hv1/vm1-rx.pcap \
6548 ofport-request=1
6549
6550 ovs-vsctl -- add-port br-int bar3 -- \
6551 set interface bar3 external-ids:iface-id=bar3 \
6552 options:tx_pcap=hv1/bar3-tx.pcap \
6553 options:rxq_pcap=hv1/bar3-rx.pcap \
6554 ofport-request=2
6555
6556 sim_add hv2
6557 as hv2
6558 ovs-vsctl add-br br-phys
6559 ovn_attach n1 br-phys 192.168.0.2
6560 ovs-vsctl -- add-port br-int vm2 -- \
6561 set interface vm2 external-ids:iface-id=vm2 \
6562 options:tx_pcap=hv2/vm2-tx.pcap \
6563 options:rxq_pcap=hv2/vm2-rx.pcap \
6564 ofport-request=1
6565
6566 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6567 # packets for ARP resolution (native tunneling doesn't queue packets
6568 # for ARP resolution).
6569 OVN_POPULATE_ARP
6570
6571 # Allow some time for ovn-northd and ovn-controller to catch up.
6572 # XXX This should be more systematic.
6573 sleep 1
6574
6575 ip_to_hex() {
6576 printf "%02x%02x%02x%02x" "$@"
6577 }
6578
6579 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6580 # different VLAN tags).
6581 src_mac="f00000010205"
6582 dst_mac="f00000010206"
6583 src_ip=`ip_to_hex 192 168 1 2`
6584 dst_ip=`ip_to_hex 192 168 1 3`
6585 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6586 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6587
6588 # expected packet at foo2
6589 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6590 echo $packet > expected
6591 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6592
6593 # Send ip packets between foo1 and bar2 (different switch, different HV)
6594 src_mac="f00000010205"
6595 dst_mac="000000010203"
6596 src_ip=`ip_to_hex 192 168 1 2`
6597 dst_ip=`ip_to_hex 192 168 2 3`
6598 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6599 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6600
6601 # expected packet at bar2
6602 src_mac="000000010204"
6603 dst_mac="f00000010208"
6604 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6605 echo $packet >> expected
6606 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6607
6608 # Send ip packets between foo1 and bar1
6609 # (different switch, loopback to same vm but different tag)
6610 src_mac="f00000010205"
6611 dst_mac="000000010203"
6612 src_ip=`ip_to_hex 192 168 1 2`
6613 dst_ip=`ip_to_hex 192 168 2 2`
6614 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6615 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6616
6617 # expected packet at bar1
6618 src_mac="000000010204"
6619 dst_mac="f00000010207"
6620 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6621 echo $packet > expected1
6622 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6623
6624 # Send ip packets between bar1 and bar3
6625 # (same switch. But one is container and another is a standalone VM)
6626 src_mac="f00000010207"
6627 dst_mac="f00000010209"
6628 src_ip=`ip_to_hex 192 168 2 2`
6629 dst_ip=`ip_to_hex 192 168 2 3`
6630 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6631 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6632
6633 # expected packet at bar3
6634 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6635 echo $packet > expected
6636 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6637
6638 # Send ip packets between foo1 and vm1.
6639 (different switch, container to the VM hosting it.)
6640 src_mac="f00000010205"
6641 dst_mac="000000010203"
6642 src_ip=`ip_to_hex 192 168 1 2`
6643 dst_ip=`ip_to_hex 172 16 1 2`
6644 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6645 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6646
6647 # expected packet at vm1
6648 src_mac="000000010202"
6649 dst_mac="f00000010203"
6650 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6651 echo $packet >> expected1
6652 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6653
6654 # Send packets from vm1 to bar1.
6655 (different switch, A hosting VM to a container inside it)
6656 src_mac="f00000010203"
6657 dst_mac="000000010202"
6658 src_ip=`ip_to_hex 172 16 1 2`
6659 dst_ip=`ip_to_hex 192 168 2 2`
6660 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6661 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6662
6663 # expected packet at vm1
6664 src_mac="000000010204"
6665 dst_mac="f00000010207"
6666 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6667 echo $packet >> expected1
6668 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6669
6670 OVN_CLEANUP([hv1],[hv2])
6671
6672 AT_CLEANUP
6673
6674 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6675 AT_SKIP_IF([test $HAVE_PYTHON = no])
6676 ovn_start
6677
6678 # Logical network:
6679 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6680 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6681 # (192.168.2.0/24) connected to it.
6682 #
6683 # R2 and R3 are gateway routers.
6684 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6685 # connected to it. Note how both alice and bob have the same subnet behind it.
6686 # We are trying to simulate external network via those 2 switches. In real
6687 # world the switch ports of these switches will have addresses set as "unknown"
6688 # to make them learning switches. Or those switches will be "localnet" ones.
6689
6690 # Create three hypervisors and create OVS ports corresponding to logical ports.
6691 net_add n1
6692
6693 sim_add hv1
6694 as hv1
6695 ovs-vsctl add-br br-phys
6696 ovn_attach n1 br-phys 192.168.0.1
6697 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6698 set interface hv1-vif1 external-ids:iface-id=foo1 \
6699 options:tx_pcap=hv1/vif1-tx.pcap \
6700 options:rxq_pcap=hv1/vif1-rx.pcap \
6701 ofport-request=1
6702
6703 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6704 set interface hv1-vif2 external-ids:iface-id=bar1 \
6705 options:tx_pcap=hv1/vif2-tx.pcap \
6706 options:rxq_pcap=hv1/vif2-rx.pcap \
6707 ofport-request=2
6708
6709 sim_add hv2
6710 as hv2
6711 ovs-vsctl add-br br-phys
6712 ovn_attach n1 br-phys 192.168.0.2
6713 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6714 set interface hv2-vif1 external-ids:iface-id=alice1 \
6715 options:tx_pcap=hv2/vif1-tx.pcap \
6716 options:rxq_pcap=hv2/vif1-rx.pcap \
6717 ofport-request=1
6718
6719 sim_add hv3
6720 as hv3
6721 ovs-vsctl add-br br-phys
6722 ovn_attach n1 br-phys 192.168.0.3
6723 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6724 set interface hv3-vif1 external-ids:iface-id=bob1 \
6725 options:tx_pcap=hv3/vif1-tx.pcap \
6726 options:rxq_pcap=hv3/vif1-rx.pcap \
6727 ofport-request=1
6728
6729
6730 ovn-nbctl create Logical_Router name=R1
6731 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6732 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6733
6734 ovn-nbctl ls-add foo
6735 ovn-nbctl ls-add bar
6736 ovn-nbctl ls-add alice
6737 ovn-nbctl ls-add bob
6738 ovn-nbctl ls-add join
6739
6740 # Connect foo to R1
6741 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6742 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6743 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6744
6745 # Connect bar to R1
6746 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6747 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6748 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6749
6750 # Connect alice to R2
6751 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6752 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6753 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6754
6755 # Connect bob to R3
6756 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6757 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6758 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6759
6760 # Connect R1 to join
6761 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6762 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6763 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6764
6765 # Connect R2 to join
6766 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6767 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6768 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6769
6770 # Connect R3 to join
6771 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6772 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6773 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6774
6775 # Install static routes with source ip address as the policy for routing.
6776 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6777 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6778 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6779
6780 # Install static routes with destination ip address as the policy for routing.
6781 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6782
6783 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6784
6785 # Create logical port foo1 in foo
6786 ovn-nbctl lsp-add foo foo1 \
6787 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6788
6789 # Create logical port bar1 in bar
6790 ovn-nbctl lsp-add bar bar1 \
6791 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6792
6793 # Create logical port alice1 in alice
6794 ovn-nbctl lsp-add alice alice1 \
6795 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6796
6797 # Create logical port bob1 in bob
6798 ovn-nbctl lsp-add bob bob1 \
6799 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6800
6801 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6802 # packets for ARP resolution (native tunneling doesn't queue packets
6803 # for ARP resolution).
6804 OVN_POPULATE_ARP
6805
6806 # Allow some time for ovn-northd and ovn-controller to catch up.
6807 # XXX This should be more systematic.
6808 sleep 1
6809
6810 ip_to_hex() {
6811 printf "%02x%02x%02x%02x" "$@"
6812 }
6813 trim_zeros() {
6814 sed 's/\(00\)\{1,\}$//'
6815 }
6816
6817 # Send ip packets between foo1 and bar1
6818 # (East-west traffic should flow normally)
6819 src_mac="f00000010203"
6820 dst_mac="000001010203"
6821 src_ip=`ip_to_hex 192 168 1 2`
6822 dst_ip=`ip_to_hex 192 168 2 2`
6823 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6824 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6825
6826 # Send ip packets between foo1 and alice1
6827 src_mac="f00000010203"
6828 dst_mac="000001010203"
6829 src_ip=`ip_to_hex 192 168 1 2`
6830 dst_ip=`ip_to_hex 172 16 1 3`
6831 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6832 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6833 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6834
6835 # Send ip packets between bar1 and bob1
6836 src_mac="f00000010204"
6837 dst_mac="000001010204"
6838 src_ip=`ip_to_hex 192 168 2 2`
6839 dst_ip=`ip_to_hex 172 16 1 4`
6840 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6841 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6842 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6843
6844 # Packet to expect at bar1
6845 src_mac="000001010204"
6846 dst_mac="f00000010204"
6847 src_ip=`ip_to_hex 192 168 1 2`
6848 dst_ip=`ip_to_hex 192 168 2 2`
6849 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6850 echo $expected > expected
6851 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6852
6853 # Packet to Expect at alice1
6854 src_mac="000002010203"
6855 dst_mac="f00000010205"
6856 src_ip=`ip_to_hex 192 168 1 2`
6857 dst_ip=`ip_to_hex 172 16 1 3`
6858 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6859 echo $expected > expected
6860 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6861
6862 # Packet to Expect at bob1
6863 src_mac="000003010203"
6864 dst_mac="f00000010206"
6865 src_ip=`ip_to_hex 192 168 2 2`
6866 dst_ip=`ip_to_hex 172 16 1 4`
6867 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6868 echo $expected > expected
6869 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6870
6871 for sim in hv1 hv2 hv3; do
6872 as $sim
6873 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6874 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6875 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6876 done
6877
6878 as ovn-sb
6879 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6880
6881 as ovn-nb
6882 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6883
6884 as northd
6885 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6886
6887 as main
6888 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6889 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6890
6891 AT_CLEANUP
6892
6893 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6894 AT_SKIP_IF([test $HAVE_PYTHON = no])
6895 ovn_start
6896
6897 ovn-nbctl ls-add ls1
6898
6899 ovn-nbctl lsp-add ls1 ls1-lp1 \
6900 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6901
6902 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6903
6904 ovn-nbctl lsp-add ls1 ls1-lp2 \
6905 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6906
6907 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6908
6909 DNS1=`ovn-nbctl create DNS records={}`
6910 DNS2=`ovn-nbctl create DNS records={}`
6911
6912 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6913 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6914 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6915
6916 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6917
6918 net_add n1
6919 sim_add hv1
6920
6921 as hv1
6922 ovs-vsctl add-br br-phys
6923 ovn_attach n1 br-phys 192.168.0.1
6924 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6925 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6926 options:tx_pcap=hv1/vif1-tx.pcap \
6927 options:rxq_pcap=hv1/vif1-rx.pcap \
6928 ofport-request=1
6929
6930 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6931 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6932 options:tx_pcap=hv1/vif2-tx.pcap \
6933 options:rxq_pcap=hv1/vif2-rx.pcap \
6934 ofport-request=2
6935
6936 OVN_POPULATE_ARP
6937 sleep 2
6938 as hv1 ovs-vsctl show
6939
6940 echo "*************************"
6941 ovn-sbctl list DNS
6942 echo "*************************"
6943
6944 ip_to_hex() {
6945 printf "%02x%02x%02x%02x" "$@"
6946 }
6947
6948 reset_pcap_file() {
6949 local iface=$1
6950 local pcap_file=$2
6951 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6952 options:rxq_pcap=dummy-rx.pcap
6953 rm -f ${pcap_file}*.pcap
6954 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6955 options:rxq_pcap=${pcap_file}-rx.pcap
6956 }
6957
6958 # set_dns_params host_name
6959 # Sets the dns_req_data and dns_resp_data
6960 set_dns_params() {
6961 local hname=$1
6962 local ttl=00000e10
6963 an_count=0001
6964 type=0001
6965 case $hname in
6966 vm1)
6967 # vm1.ovn.org
6968 query_name=03766d31036f766e036f726700
6969 # IPv4 address - 10.0.0.4
6970 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6971 ;;
6972 vm2)
6973 # vm2.ovn.org
6974 query_name=03766d32036f766e036f726700
6975 # IPv4 address - 10.0.0.6
6976 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6977 # IPv4 address - 20.0.0.4
6978 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6979 an_count=0002
6980 ;;
6981 vm3)
6982 # vm3.ovn.org
6983 query_name=03766d33036f766e036f726700
6984 # IPv4 address - 40.0.0.4
6985 expected_dns_answer=${query_name}00010001${ttl}000428000004
6986 ;;
6987 vm1_ipv6_only)
6988 # vm1.ovn.org
6989 query_name=03766d31036f766e036f726700
6990 # IPv6 address - aef0::4
6991 type=001c
6992 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6993 ;;
6994 vm1_ipv4_v6)
6995 # vm1.ovn.org
6996 query_name=03766d31036f766e036f726700
6997 type=00ff
6998 an_count=0002
6999 # IPv4 address - 10.0.0.4
7000 # IPv6 address - aef0::4
7001 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7002 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7003 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7004 ;;
7005 vm1_invalid_type)
7006 # vm1.ovn.org
7007 query_name=03766d31036f766e036f726700
7008 # IPv6 address - aef0::4
7009 type=0002
7010 ;;
7011 vm1_incomplete)
7012 # set type to none
7013 type=''
7014 esac
7015 # TTL - 3600
7016 local dns_req_header=010201200001000000000000
7017 local dns_resp_header=010281200001${an_count}00000000
7018 dns_req_data=${dns_req_header}${query_name}${type}0001
7019 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7020 }
7021
7022 # This shell function sends a DNS request packet
7023 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7024 test_dns() {
7025 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7026 local dns_query_data=$7
7027 shift; shift; shift; shift; shift; shift; shift;
7028 # Packet size => IPv4 header (20) + UDP header (8) +
7029 # DNS data (header + query)
7030 ip_len=`expr 28 + ${#dns_query_data} / 2`
7031 udp_len=`expr $ip_len - 20`
7032 ip_len=$(printf "%x" $ip_len)
7033 udp_len=$(printf "%x" $udp_len)
7034 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7035 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7036 # dns data
7037 request=${request}${dns_query_data}
7038
7039 if test $dns_reply != 0; then
7040 local dns_reply=$1
7041 ip_len=`expr 28 + ${#dns_reply} / 2`
7042 udp_len=`expr $ip_len - 20`
7043 ip_len=$(printf "%x" $ip_len)
7044 udp_len=$(printf "%x" $udp_len)
7045 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7046 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7047 echo $reply >> $inport.expected
7048 else
7049 for outport; do
7050 echo $request >> $outport.expected
7051 done
7052 fi
7053 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7054 }
7055
7056 test_dns6() {
7057 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7058 local dns_query_data=$7
7059 shift; shift; shift; shift; shift; shift; shift;
7060 # Packet size => UDP header (8) +
7061 # DNS data (header + query)
7062 ip_len=`expr 8 + ${#dns_query_data} / 2`
7063 udp_len=$ip_len
7064 ip_len=$(printf "%x" $ip_len)
7065 udp_len=$(printf "%x" $udp_len)
7066 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7067 request=${request}9234003500${udp_len}0000
7068 #dns data
7069 request=${request}${dns_query_data}
7070
7071 if test $dns_reply != 0; then
7072 local dns_reply=$1
7073 ip_len=`expr 8 + ${#dns_reply} / 2`
7074 udp_len=$ip_len
7075 ip_len=$(printf "%x" $ip_len)
7076 udp_len=$(printf "%x" $udp_len)
7077 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7078 reply=${reply}0035923400${udp_len}0000${dns_reply}
7079 echo $reply >> $inport.expected
7080 else
7081 for outport; do
7082 echo $request >> $outport.expected
7083 done
7084 fi
7085 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7086 }
7087
7088 AT_CAPTURE_FILE([ofctl_monitor0.log])
7089 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7090 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7091
7092 set_dns_params vm2
7093 src_ip=`ip_to_hex 10 0 0 4`
7094 dst_ip=`ip_to_hex 10 0 0 1`
7095 dns_reply=1
7096 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7097
7098 # NXT_RESUMEs should be 1.
7099 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7100
7101 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7102 cat 1.expected | cut -c -48 > expout
7103 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7104 # Skipping the IPv4 checksum.
7105 cat 1.expected | cut -c 53- > expout
7106 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7107
7108 reset_pcap_file hv1-vif1 hv1/vif1
7109 reset_pcap_file hv1-vif2 hv1/vif2
7110 rm -f 1.expected
7111 rm -f 2.expected
7112
7113 set_dns_params vm1
7114 src_ip=`ip_to_hex 10 0 0 6`
7115 dst_ip=`ip_to_hex 10 0 0 1`
7116 dns_reply=1
7117 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7118
7119 # NXT_RESUMEs should be 2.
7120 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7121
7122 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7123 cat 2.expected | cut -c -48 > expout
7124 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7125 # Skipping the IPv4 checksum.
7126 cat 2.expected | cut -c 53- > expout
7127 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7128
7129 reset_pcap_file hv1-vif1 hv1/vif1
7130 reset_pcap_file hv1-vif2 hv1/vif2
7131 rm -f 1.expected
7132 rm -f 2.expected
7133
7134 # Clear the query name options for ls1-lp2
7135 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7136
7137 set_dns_params vm2
7138 src_ip=`ip_to_hex 10 0 0 4`
7139 dst_ip=`ip_to_hex 10 0 0 1`
7140 dns_reply=0
7141 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7142
7143 # NXT_RESUMEs should be 3.
7144 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7145
7146 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7147 AT_CHECK([cat 1.packets], [0], [])
7148
7149 reset_pcap_file hv1-vif1 hv1/vif1
7150 reset_pcap_file hv1-vif2 hv1/vif2
7151 rm -f 1.expected
7152 rm -f 2.expected
7153
7154 # Clear the query name for ls1-lp1
7155 # Since ls1 has no query names configued,
7156 # ovn-northd should not add the DNS flows.
7157 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7158
7159 set_dns_params vm1
7160 src_ip=`ip_to_hex 10 0 0 6`
7161 dst_ip=`ip_to_hex 10 0 0 1`
7162 dns_reply=0
7163 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7164
7165 # NXT_RESUMEs should be 3 only.
7166 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7167
7168 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7169 AT_CHECK([cat 2.packets], [0], [])
7170
7171 reset_pcap_file hv1-vif1 hv1/vif1
7172 reset_pcap_file hv1-vif2 hv1/vif2
7173 rm -f 1.expected
7174 rm -f 2.expected
7175
7176 # Test IPv6 (AAAA records) using IPv4 packet.
7177 # Add back the DNS options for ls1-lp1.
7178 ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7179
7180 set_dns_params vm1_ipv6_only
7181 src_ip=`ip_to_hex 10 0 0 6`
7182 dst_ip=`ip_to_hex 10 0 0 1`
7183 dns_reply=1
7184 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7185
7186 # NXT_RESUMEs should be 4.
7187 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7188
7189 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7190 cat 2.expected | cut -c -48 > expout
7191 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7192 # Skipping the IPv4 checksum.
7193 cat 2.expected | cut -c 53- > expout
7194 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7195
7196 reset_pcap_file hv1-vif1 hv1/vif1
7197 reset_pcap_file hv1-vif2 hv1/vif2
7198 rm -f 1.expected
7199 rm -f 2.expected
7200
7201 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7202 set_dns_params vm1_ipv4_v6
7203 src_ip=`ip_to_hex 10 0 0 6`
7204 dst_ip=`ip_to_hex 10 0 0 1`
7205 dns_reply=1
7206 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7207
7208 # NXT_RESUMEs should be 5.
7209 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7210
7211 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7212 cat 2.expected | cut -c -48 > expout
7213 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7214 # Skipping the IPv4 checksum.
7215 cat 2.expected | cut -c 53- > expout
7216 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7217
7218 reset_pcap_file hv1-vif1 hv1/vif1
7219 reset_pcap_file hv1-vif2 hv1/vif2
7220 rm -f 1.expected
7221 rm -f 2.expected
7222
7223 # Invalid type.
7224 set_dns_params vm1_invalid_type
7225 src_ip=`ip_to_hex 10 0 0 6`
7226 dst_ip=`ip_to_hex 10 0 0 1`
7227 dns_reply=0
7228 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7229
7230 # NXT_RESUMEs should be 6.
7231 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7232
7233 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7234 AT_CHECK([cat 2.packets], [0], [])
7235
7236 reset_pcap_file hv1-vif1 hv1/vif1
7237 reset_pcap_file hv1-vif2 hv1/vif2
7238 rm -f 1.expected
7239 rm -f 2.expected
7240
7241 # Incomplete DNS packet.
7242 set_dns_params vm1_incomplete
7243 src_ip=`ip_to_hex 10 0 0 6`
7244 dst_ip=`ip_to_hex 10 0 0 1`
7245 dns_reply=0
7246 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7247
7248 # NXT_RESUMEs should be 7.
7249 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7250
7251 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7252 AT_CHECK([cat 2.packets], [0], [])
7253
7254 reset_pcap_file hv1-vif1 hv1/vif1
7255 reset_pcap_file hv1-vif2 hv1/vif2
7256 rm -f 1.expected
7257 rm -f 2.expected
7258
7259 # Add one more DNS record to the ls1.
7260 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7261
7262 set_dns_params vm3
7263 src_ip=`ip_to_hex 10 0 0 4`
7264 dst_ip=`ip_to_hex 10 0 0 1`
7265 dns_reply=1
7266 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7267
7268 # NXT_RESUMEs should be 8.
7269 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7270
7271 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7272 cat 1.expected | cut -c -48 > expout
7273 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7274 # Skipping the IPv4 checksum.
7275 cat 1.expected | cut -c 53- > expout
7276 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7277
7278 reset_pcap_file hv1-vif1 hv1/vif1
7279 reset_pcap_file hv1-vif2 hv1/vif2
7280 rm -f 1.expected
7281 rm -f 2.expected
7282
7283 # Try DNS query over IPv6
7284 set_dns_params vm1
7285 src_ip=aef00000000000000000000000000004
7286 dst_ip=aef00000000000000000000000000001
7287 dns_reply=1
7288 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7289
7290 # NXT_RESUMEs should be 9.
7291 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7292
7293 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7294 # Skipping the UDP checksum.
7295 cat 1.expected | cut -c 1-120,125- > expout
7296 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
7297
7298 reset_pcap_file hv1-vif1 hv1/vif1
7299 reset_pcap_file hv1-vif2 hv1/vif2
7300 rm -f 1.expected
7301 rm -f 2.expected
7302
7303 as hv1
7304 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7305 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7306 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7307
7308 as ovn-sb
7309 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7310
7311 as ovn-nb
7312 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7313
7314 as northd
7315 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7316
7317 as main
7318 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7319 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7320 AT_CLEANUP
7321
7322 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
7323 AT_SKIP_IF([test $HAVE_PYTHON = no])
7324 ovn_start
7325
7326 net_add n1
7327
7328 sim_add hv1
7329 as hv1
7330 ovs-vsctl add-br br-phys
7331 ovn_attach n1 br-phys 192.168.0.1
7332 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7333 set interface hv1-vif1 external-ids:iface-id=foo1 \
7334 options:tx_pcap=hv1/vif1-tx.pcap \
7335 options:rxq_pcap=hv1/vif1-rx.pcap \
7336 ofport-request=1
7337
7338 sim_add gw1
7339 as gw1
7340 ovs-vsctl add-br br-phys
7341 ovn_attach n1 br-phys 192.168.0.2
7342
7343 sim_add gw2
7344 as gw2
7345 ovs-vsctl add-br br-phys
7346 ovn_attach n1 br-phys 192.168.0.4
7347
7348 sim_add ext1
7349 as ext1
7350 ovs-vsctl add-br br-phys
7351 ovn_attach n1 br-phys 192.168.0.3
7352 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7353 set interface ext1-vif1 external-ids:iface-id=outside1 \
7354 options:tx_pcap=ext1/vif1-tx.pcap \
7355 options:rxq_pcap=ext1/vif1-rx.pcap \
7356 ofport-request=1
7357
7358 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7359 # packets for ARP resolution (native tunneling doesn't queue packets
7360 # for ARP resolution).
7361 OVN_POPULATE_ARP
7362
7363 ovn-nbctl create Logical_Router name=R1
7364
7365 ovn-nbctl ls-add foo
7366 ovn-nbctl ls-add alice
7367 ovn-nbctl ls-add outside
7368
7369 # Connect foo to R1
7370 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7371 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7372 type=router options:router-port=foo \
7373 -- lsp-set-addresses rp-foo router
7374
7375 # Connect alice to R1 as distributed router gateway port on gw1
7376 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7377
7378 ovn-nbctl \
7379 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7380 chassis_name=gw1 \
7381 priority=20 -- \
7382 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7383 chassis_name=gw2 \
7384 priority=10 -- \
7385 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7386
7387 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7388 type=router options:router-port=alice \
7389 -- lsp-set-addresses rp-alice router
7390
7391 # Create logical port foo1 in foo
7392 ovn-nbctl lsp-add foo foo1 \
7393 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7394
7395 # Create logical port outside1 in outside
7396 ovn-nbctl lsp-add outside outside1 \
7397 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7398
7399 # Create localnet port in alice
7400 ovn-nbctl lsp-add alice ln-alice
7401 ovn-nbctl lsp-set-addresses ln-alice unknown
7402 ovn-nbctl lsp-set-type ln-alice localnet
7403 ovn-nbctl lsp-set-options ln-alice network_name=phys
7404
7405 # Create localnet port in outside
7406 ovn-nbctl lsp-add outside ln-outside
7407 ovn-nbctl lsp-set-addresses ln-outside unknown
7408 ovn-nbctl lsp-set-type ln-outside localnet
7409 ovn-nbctl lsp-set-options ln-outside network_name=phys
7410
7411 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7412 # mapping to the external network, is the one generating packets
7413 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7414 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7415 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7416
7417 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7418
7419 # Allow some time for ovn-northd and ovn-controller to catch up.
7420 # XXX This should be more systematic.
7421 sleep 2
7422
7423 ip_to_hex() {
7424 printf "%02x%02x%02x%02x" "$@"
7425 }
7426
7427 reset_pcap_file() {
7428 local iface=$1
7429 local pcap_file=$2
7430 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7431 options:rxq_pcap=dummy-rx.pcap
7432 rm -f ${pcap_file}*.pcap
7433 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7434 options:rxq_pcap=${pcap_file}-rx.pcap
7435 }
7436
7437 test_ip_packet()
7438 {
7439 local active_gw=$1
7440 local backup_gw=$2
7441
7442 # Send ip packet between foo1 and outside1
7443 src_mac="f00000010203" # foo1 mac
7444 dst_mac="000001010203" # rp-foo mac (internal router leg)
7445 src_ip=`ip_to_hex 192 168 1 2`
7446 dst_ip=`ip_to_hex 172 16 1 3`
7447 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7448
7449 # ARP request packet to expect at outside1
7450 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7451
7452 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7453
7454 # Send ARP reply from outside1 back to the router
7455 # XXX: note, we could avoid this if we plug this port into a netns
7456 # and setup the IP address into the port, so the kernel would simply reply
7457 src_mac="000002010203"
7458 reply_mac="f00000010204"
7459 dst_ip=`ip_to_hex 172 16 1 3`
7460 src_ip=`ip_to_hex 172 16 1 1`
7461 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7462
7463 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7464
7465 OVS_WAIT_UNTIL([
7466 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7467 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7468 ])
7469
7470 # Packet to Expect at ext1 chassis, outside1 port
7471 src_mac="000002010203"
7472 dst_mac="f00000010204"
7473 src_ip=`ip_to_hex 192 168 1 2`
7474 dst_ip=`ip_to_hex 172 16 1 3`
7475 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7476 echo $expected > ext1-vif1.expected
7477
7478 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7479 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7480 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7481
7482 # Resend packet from foo1 to outside1
7483 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7484
7485 sleep 1
7486
7487 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7488 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7489 AT_CHECK([grep $expected packets | sort], [0], [expout])
7490 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7491 AT_CHECK([grep $expected packets | sort], [0], [])
7492 }
7493
7494 test_ip_packet gw1 gw2
7495
7496 ovn-nbctl --timeout=3 --wait=hv \
7497 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7498 chassis_name=gw1 \
7499 priority=10 -- \
7500 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7501 chassis_name=gw2 \
7502 priority=20 -- \
7503 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7504
7505 test_ip_packet gw2 gw1
7506
7507 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7508 AT_CLEANUP
7509
7510 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7511 AT_SKIP_IF([test $HAVE_PYTHON = no])
7512 ovn_start
7513
7514 net_add n1
7515
7516 sim_add hv1
7517 as hv1
7518 ovs-vsctl add-br br-phys
7519 ovn_attach n1 br-phys 192.168.0.1
7520 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7521 set interface hv1-vif1 external-ids:iface-id=foo1 \
7522 options:tx_pcap=hv1/vif1-tx.pcap \
7523 options:rxq_pcap=hv1/vif1-rx.pcap \
7524 ofport-request=1
7525
7526 sim_add gw1
7527 as gw1
7528 ovs-vsctl add-br br-phys
7529 ovn_attach n1 br-phys 192.168.0.2
7530
7531 sim_add gw2
7532 as gw2
7533 ovs-vsctl add-br br-phys
7534 ovn_attach n1 br-phys 192.168.0.4
7535
7536 sim_add ext1
7537 as ext1
7538 ovs-vsctl add-br br-phys
7539 ovn_attach n1 br-phys 192.168.0.3
7540 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7541 set interface ext1-vif1 external-ids:iface-id=outside1 \
7542 options:tx_pcap=ext1/vif1-tx.pcap \
7543 options:rxq_pcap=ext1/vif1-rx.pcap \
7544 ofport-request=1
7545
7546 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7547 # packets for ARP resolution (native tunneling doesn't queue packets
7548 # for ARP resolution).
7549 OVN_POPULATE_ARP
7550
7551 ovn-nbctl create Logical_Router name=R0
7552 ovn-nbctl create Logical_Router name=R1
7553
7554 ovn-nbctl ls-add foo
7555 ovn-nbctl ls-add join
7556 ovn-nbctl ls-add alice
7557 ovn-nbctl ls-add outside
7558
7559 #Connect foo to R0
7560 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7561 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7562 type=router options:router-port=R0-foo \
7563 -- lsp-set-addresses foo-R0 router
7564
7565 #Connect R0 to join
7566 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7567 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7568 type=router options:router-port=R0-join \
7569 -- lsp-set-addresses join-R0 router
7570
7571 #Connect join to R1
7572 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7573 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7574 type=router options:router-port=R1-join \
7575 -- lsp-set-addresses join-R1 router
7576
7577 #add route rules
7578 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7579 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7580
7581 # Connect alice to R1 as distributed router gateway port on gw1
7582 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7583
7584 ovn-nbctl \
7585 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7586 chassis_name=gw1 \
7587 priority=20 -- \
7588 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7589 chassis_name=gw2 \
7590 priority=10 -- \
7591 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7592
7593 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7594 type=router options:router-port=alice \
7595 -- lsp-set-addresses rp-alice router
7596
7597 # Create logical port foo1 in foo
7598 ovn-nbctl lsp-add foo foo1 \
7599 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7600
7601 # Create logical port outside1 in outside
7602 ovn-nbctl lsp-add outside outside1 \
7603 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7604
7605 # Create localnet port in alice
7606 ovn-nbctl lsp-add alice ln-alice
7607 ovn-nbctl lsp-set-addresses ln-alice unknown
7608 ovn-nbctl lsp-set-type ln-alice localnet
7609 ovn-nbctl lsp-set-options ln-alice network_name=phys
7610
7611 # Create localnet port in outside
7612 ovn-nbctl lsp-add outside ln-outside
7613 ovn-nbctl lsp-set-addresses ln-outside unknown
7614 ovn-nbctl lsp-set-type ln-outside localnet
7615 ovn-nbctl lsp-set-options ln-outside network_name=phys
7616
7617 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7618 # mapping to the external network, is the one generating packets
7619 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7620 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7621 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7622
7623 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7624
7625 # Allow some time for ovn-northd and ovn-controller to catch up.
7626 # XXX This should be more systematic.
7627 sleep 2
7628
7629 ip_to_hex() {
7630 printf "%02x%02x%02x%02x" "$@"
7631 }
7632
7633 reset_pcap_file() {
7634 local iface=$1
7635 local pcap_file=$2
7636 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7637 options:rxq_pcap=dummy-rx.pcap
7638 rm -f ${pcap_file}*.pcap
7639 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7640 options:rxq_pcap=${pcap_file}-rx.pcap
7641 }
7642
7643 test_ip_packet()
7644 {
7645 local active_gw=$1
7646 local backup_gw=$2
7647
7648 # Send ip packet between foo1 and outside1
7649 src_mac="f00000010203" # foo1 mac
7650 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7651 src_ip=`ip_to_hex 192 168 1 2`
7652 dst_ip=`ip_to_hex 172 16 1 3`
7653 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7654
7655 # ARP request packet to expect at outside1
7656 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7657
7658 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7659
7660 # Send ARP reply from outside1 back to the router
7661 # XXX: note, we could avoid this if we plug this port into a netns
7662 # and setup the IP address into the port, so the kernel would simply reply
7663 src_mac="000002010203"
7664 reply_mac="f00000010204"
7665 dst_ip=`ip_to_hex 172 16 1 3`
7666 src_ip=`ip_to_hex 172 16 1 1`
7667 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7668
7669 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7670
7671 OVS_WAIT_UNTIL([
7672 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7673 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7674 ])
7675
7676 # Packet to Expect at ext1 chassis, outside1 port
7677 src_mac="000002010203"
7678 dst_mac="f00000010204"
7679 src_ip=`ip_to_hex 192 168 1 2`
7680 dst_ip=`ip_to_hex 172 16 1 3`
7681 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7682 echo $expected > ext1-vif1.expected
7683
7684 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7685 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7686 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7687
7688 # Resend packet from foo1 to outside1
7689 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7690
7691 sleep 1
7692
7693 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7694 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7695 AT_CHECK([grep $expected packets | sort], [0], [expout])
7696 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7697 AT_CHECK([grep $expected packets | sort], [0], [])
7698 }
7699
7700 test_ip_packet gw1 gw2
7701
7702 ovn-nbctl --timeout=3 --wait=hv \
7703 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7704 chassis_name=gw1 \
7705 priority=10 -- \
7706 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7707 chassis_name=gw2 \
7708 priority=20 -- \
7709 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7710
7711 test_ip_packet gw2 gw1
7712
7713 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7714 AT_CLEANUP
7715
7716 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7717 AT_SKIP_IF([test $HAVE_PYTHON = no])
7718 ovn_start
7719
7720 # Logical network:
7721 # One LR R1 that has switches foo (192.168.1.0/24) and
7722 # alice (172.16.1.0/24) connected to it. The logical port
7723 # between R1 and alice has a "redirect-chassis" specified,
7724 # i.e. it is the distributed router gateway port.
7725 # Switch alice also has a localnet port defined.
7726 # An additional switch outside has a localnet port and the
7727 # same subnet as alice (172.16.1.0/24).
7728
7729 # Physical network:
7730 # Three hypervisors hv[123].
7731 # hv1 hosts vif foo1.
7732 # hv2 is the "redirect-chassis" that hosts the distributed
7733 # router gateway port.
7734 # hv3 hosts vif outside1.
7735 # In order to show that connectivity works only through hv2,
7736 # an initial round of tests is run without any bridge-mapping
7737 # defined for the localnet on hv2. These tests are expected
7738 # to fail.
7739 # Subsequent tests are run after defining the bridge-mapping
7740 # for the localnet on hv2. These tests are expected to succeed.
7741
7742 # Create three hypervisors and create OVS ports corresponding
7743 # to logical ports.
7744 net_add n1
7745
7746 sim_add hv1
7747 as hv1
7748 ovs-vsctl add-br br-phys
7749 ovn_attach n1 br-phys 192.168.0.1
7750 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7751 set interface hv1-vif1 external-ids:iface-id=foo1 \
7752 options:tx_pcap=hv1/vif1-tx.pcap \
7753 options:rxq_pcap=hv1/vif1-rx.pcap \
7754 ofport-request=1
7755
7756 sim_add hv2
7757 as hv2
7758 ovs-vsctl add-br br-phys
7759 ovn_attach n1 br-phys 192.168.0.2
7760
7761 sim_add hv3
7762 as hv3
7763 ovs-vsctl add-br br-phys
7764 ovn_attach n1 br-phys 192.168.0.3
7765 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7766 set interface hv3-vif1 external-ids:iface-id=outside1 \
7767 options:tx_pcap=hv3/vif1-tx.pcap \
7768 options:rxq_pcap=hv3/vif1-rx.pcap \
7769 ofport-request=1
7770
7771 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7772 # packets for ARP resolution (native tunneling doesn't queue packets
7773 # for ARP resolution).
7774 OVN_POPULATE_ARP
7775
7776 ovn-nbctl create Logical_Router name=R1
7777
7778 ovn-nbctl ls-add foo
7779 ovn-nbctl ls-add alice
7780 ovn-nbctl ls-add outside
7781
7782 # Connect foo to R1
7783 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7784 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7785 type=router options:router-port=foo \
7786 -- lsp-set-addresses rp-foo router
7787
7788 # Connect alice to R1 as distributed router gateway port on hv2
7789 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7790 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7791 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7792 type=router options:router-port=alice \
7793 -- lsp-set-addresses rp-alice router
7794
7795 # Create logical port foo1 in foo
7796 ovn-nbctl lsp-add foo foo1 \
7797 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7798
7799 # Create logical port outside1 in outside
7800 ovn-nbctl lsp-add outside outside1 \
7801 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7802
7803 # Create localnet port in alice
7804 ovn-nbctl lsp-add alice ln-alice
7805 ovn-nbctl lsp-set-addresses ln-alice unknown
7806 ovn-nbctl lsp-set-type ln-alice localnet
7807 ovn-nbctl lsp-set-options ln-alice network_name=phys
7808
7809 # Create localnet port in outside
7810 ovn-nbctl lsp-add outside ln-outside
7811 ovn-nbctl lsp-set-addresses ln-outside unknown
7812 ovn-nbctl lsp-set-type ln-outside localnet
7813 ovn-nbctl lsp-set-options ln-outside network_name=phys
7814
7815 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7816 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7817 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7818
7819
7820 # Allow some time for ovn-northd and ovn-controller to catch up.
7821 # XXX This should be more systematic.
7822 sleep 2
7823
7824 echo "---------NB dump-----"
7825 ovn-nbctl show
7826 echo "---------------------"
7827 ovn-nbctl list logical_router
7828 echo "---------------------"
7829 ovn-nbctl list logical_router_port
7830 echo "---------------------"
7831
7832 echo "---------SB dump-----"
7833 ovn-sbctl list datapath_binding
7834 echo "---------------------"
7835 ovn-sbctl list port_binding
7836 echo "---------------------"
7837 ovn-sbctl dump-flows
7838 echo "---------------------"
7839 ovn-sbctl list chassis
7840 ovn-sbctl list encap
7841 echo "------ Gateway_Chassis dump (SBDB) -------"
7842 ovn-sbctl list Gateway_Chassis
7843 echo "------ Port_Binding chassisredirect -------"
7844 ovn-sbctl find Port_Binding type=chassisredirect
7845 echo "-------------------------------------------"
7846
7847 echo "------ hv1 dump ----------"
7848 as hv1 ovs-ofctl show br-int
7849 as hv1 ovs-ofctl dump-flows br-int
7850 echo "------ hv2 dump ----------"
7851 as hv2 ovs-ofctl show br-int
7852 as hv2 ovs-ofctl dump-flows br-int
7853 echo "------ hv3 dump ----------"
7854 as hv3 ovs-ofctl show br-int
7855 as hv3 ovs-ofctl dump-flows br-int
7856 echo "--------------------------"
7857
7858
7859 # Check that redirect mapping is programmed only on hv2
7860 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7861 ])
7862 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7863 ])
7864 # Check that hv1 sends chassisredirect port traffic to hv2
7865 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7866 ])
7867 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7868 ])
7869 # Check that arp reply on distributed gateway port is only programmed on hv2
7870 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7871 ])
7872 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7873 ])
7874
7875
7876 ip_to_hex() {
7877 printf "%02x%02x%02x%02x" "$@"
7878 }
7879
7880
7881 : > hv2-vif1.expected
7882 : > hv3-vif1.expected
7883
7884 # test_arp INPORT SHA SPA TPA [REPLY_HA]
7885 #
7886 # Causes a packet to be received on INPORT. The packet is an ARP
7887 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7888 # it should be the hardware address of the target to expect to receive in an
7889 # ARP reply; otherwise no reply is expected.
7890 #
7891 # INPORT is an logical switch port number, e.g. 11 for vif11.
7892 # SHA and REPLY_HA are each 12 hex digits.
7893 # SPA and TPA are each 8 hex digits.
7894 test_arp() {
7895 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7896 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7897 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7898
7899 if test X$reply_ha != X; then
7900 # Expect to receive the reply, if any.
7901 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7902 echo $reply >> hv${hv}-vif$inport.expected
7903 fi
7904 }
7905
7906 rtr_ip=$(ip_to_hex 172 16 1 1)
7907 foo_ip=$(ip_to_hex 192 168 1 2)
7908 outside_ip=$(ip_to_hex 172 16 1 3)
7909
7910 echo $rtr_ip
7911 echo $foo_ip
7912 echo $outside_ip
7913
7914 # ARP for router IP address from outside1, no response expected
7915 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7916
7917 # Now check the packets actually received against the ones expected.
7918 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7919
7920 # Send ip packet between foo1 and outside1
7921 src_mac="f00000010203"
7922 dst_mac="000001010203"
7923 src_ip=`ip_to_hex 192 168 1 2`
7924 dst_ip=`ip_to_hex 172 16 1 3`
7925 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7926
7927 # Now check the packets actually received against the ones expected.
7928 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7929
7930 # Now add bridge-mappings on hv2, which should make everything work
7931 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7932
7933 # Allow some time for ovn-northd and ovn-controller to catch up.
7934 # XXX This should be more systematic.
7935 sleep 2
7936
7937 # ARP for router IP address from outside1
7938 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7939
7940 # Now check the packets actually received against the ones expected.
7941 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7942
7943 # Send ip packet between foo1 and outside1
7944 src_mac="f00000010203"
7945 dst_mac="000001010203"
7946 src_ip=`ip_to_hex 192 168 1 2`
7947 dst_ip=`ip_to_hex 172 16 1 3`
7948 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7949
7950 # ARP request packet to expect at outside1
7951 src_mac="000002010203"
7952 src_ip=`ip_to_hex 172 16 1 1`
7953 arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7954
7955 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7956
7957 echo $arp_request >> hv3-vif1.expected
7958 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7959
7960 # Send ARP reply from outside1 back to the router
7961 reply_mac="f00000010204"
7962 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7963
7964 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7965
7966 # Allow some time for ovn-northd and ovn-controller to catch up.
7967 # XXX This should be more systematic.
7968 sleep 1
7969
7970 # Packet to Expect at outside1
7971 src_mac="000002010203"
7972 dst_mac="f00000010204"
7973 src_ip=`ip_to_hex 192 168 1 2`
7974 dst_ip=`ip_to_hex 172 16 1 3`
7975 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7976
7977 # Resend packet from foo1 to outside1
7978 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7979
7980 echo "------ hv1 dump ----------"
7981 as hv1 ovs-ofctl show br-int
7982 as hv1 ovs-ofctl dump-flows br-int
7983 echo "------ hv2 dump ----------"
7984 as hv2 ovs-ofctl show br-int
7985 as hv2 ovs-ofctl dump-flows br-int
7986 echo "------ hv3 dump ----------"
7987 as hv3 ovs-ofctl show br-int
7988 as hv3 ovs-ofctl dump-flows br-int
7989 echo "----------------------------"
7990
7991 echo $expected >> hv3-vif1.expected
7992 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7993
7994 #Check ovn-trace over "chassisredirect" port
7995 AT_CAPTURE_FILE([trace])
7996 ovn_trace () {
7997 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7998 }
7999
8000 echo 'ip.ttl--;' > expout
8001 echo 'eth.src = 00:00:02:01:02:03;' >> expout
8002 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8003 echo 'output("ln-alice");' >> expout
8004 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])
8005
8006 # Create logical port alice1 in alice on hv1
8007 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8008 set interface hv1-vif2 external-ids:iface-id=alice1 \
8009 options:tx_pcap=hv1/vif2-tx.pcap \
8010 options:rxq_pcap=hv1/vif2-rx.pcap \
8011 ofport-request=1
8012
8013 ovn-nbctl lsp-add alice alice1 \
8014 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8015
8016 # Create logical port foo2 in foo on hv2
8017 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8018 set interface hv2-vif1 external-ids:iface-id=foo2 \
8019 options:tx_pcap=hv2/vif1-tx.pcap \
8020 options:rxq_pcap=hv2/vif1-rx.pcap \
8021 ofport-request=1
8022
8023 ovn-nbctl lsp-add foo foo2 \
8024 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8025
8026 # Allow some time for ovn-northd and ovn-controller to catch up.
8027 # XXX This should be more systematic.
8028 sleep 1
8029
8030 : > hv1-vif2.expected
8031
8032 # Send ip packet between alice1 and foo2
8033 src_mac="f00000010205"
8034 dst_mac="000002010203"
8035 src_ip=`ip_to_hex 172 16 1 4`
8036 dst_ip=`ip_to_hex 192 168 1 3`
8037 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8038
8039 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8040
8041 # Packet to Expect at foo2
8042 src_mac="000001010203"
8043 dst_mac="f00000010206"
8044 src_ip=`ip_to_hex 172 16 1 4`
8045 dst_ip=`ip_to_hex 192 168 1 3`
8046 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8047
8048 echo $expected >> hv2-vif1.expected
8049 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
8050
8051 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
8052 ])
8053
8054 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
8055
8056 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
8057 ])
8058
8059 OVN_CLEANUP([hv1],[hv2],[hv3])
8060
8061 AT_CLEANUP
8062
8063 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8064 AT_SKIP_IF([test $HAVE_PYTHON = no])
8065 ovn_start
8066 # Create logical switches
8067 ovn-nbctl ls-add ls0
8068 ovn-nbctl ls-add ls1
8069 # Create distributed router
8070 ovn-nbctl create Logical_Router name=lr0
8071 # Add distributed gateway port to distributed router
8072 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8073 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8074 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8075 type=router options:router-port=lrp0 addresses="router"
8076 # Add router port to ls1
8077 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8078 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8079 type=router options:router-port=lrp1 addresses="router"
8080 # Add logical ports for NAT rules
8081 ovn-nbctl lsp-add ls1 foo1 \
8082 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8083 ovn-nbctl lsp-add ls1 foo2 \
8084 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
8085 # Add nat-addresses option
8086 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8087 # Add NAT rules
8088 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8089 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8090 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])
8091 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])
8092
8093 net_add n1
8094 sim_add hv1
8095 as hv1
8096 ovs-vsctl add-br br-phys
8097 ovn_attach n1 br-phys 192.168.0.1
8098
8099 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8100 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])
8101
8102 sim_add hv2
8103 as hv2
8104 ovs-vsctl add-br br-phys
8105 ovn_attach n1 br-phys 192.168.0.2
8106 # Initially test with no bridge-mapping on hv2, expect to receive no packets
8107
8108 sim_add hv3
8109 as hv3
8110 ovs-vsctl add-br br-phys
8111 ovn_attach n1 br-phys 192.168.0.3
8112 # Initially test with no bridge-mapping on hv3
8113
8114 # Create a localnet port.
8115 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8116 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8117 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8118 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8119
8120 # Allow some time for ovn-northd and ovn-controller to catch up.
8121 # XXX This should be more systematic.
8122 sleep 2
8123
8124 # Expect no packets when hv2 bridge-mapping is not present
8125 : > packets
8126 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8127
8128 # Add bridge-mapping on hv2
8129 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8130
8131 # Wait for packets to be received.
8132 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8133 trim_zeros() {
8134 sed 's/\(00\)\{1,\}$//'
8135 }
8136 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8137 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8138 echo $expected > expout
8139 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8140 echo $expected >> expout
8141 AT_CHECK([sort packets], [0], [expout])
8142 sort packets | cat
8143
8144 # Temporarily remove nat-addresses option to avoid race conditions
8145 # due to GARP backoff
8146 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8147
8148 reset_pcap_file() {
8149 local iface=$1
8150 local pcap_file=$2
8151 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8152 options:rxq_pcap=dummy-rx.pcap
8153 rm -f ${pcap_file}*.pcap
8154 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8155 options:rxq_pcap=${pcap_file}-rx.pcap
8156 }
8157
8158 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8159
8160 # Add OVS ports for foo1 and foo2 on hv3
8161 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8162 set interface hv3-vif1 external-ids:iface-id=foo1 \
8163 ofport-request=1
8164 ovs-vsctl -- add-port br-int hv3-vif2 -- \
8165 set interface hv3-vif2 external-ids:iface-id=foo2 \
8166 ofport-request=2
8167
8168 # Add bridge-mapping on hv3
8169 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8170
8171 # Re-add nat-addresses option
8172 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8173
8174 # Wait for packets to be received.
8175 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8176 trim_zeros() {
8177 sed 's/\(00\)\{1,\}$//'
8178 }
8179
8180 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8181 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8182 echo $expected >> expout
8183 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8184 echo $expected >> expout
8185 AT_CHECK([sort packets], [0], [expout])
8186 sort packets | cat
8187
8188 OVN_CLEANUP([hv1],[hv2],[hv3])
8189
8190 AT_CLEANUP
8191
8192 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8193 AT_KEYWORDS([ovn-nd_ra])
8194 AT_SKIP_IF([test $HAVE_PYTHON = no])
8195 ovn_start
8196
8197 # In this test case we create 1 lswitch with 3 VIF ports attached,
8198 # and a lrouter connected to the lswitch.
8199 # We generate the Router solicitation packet and verify the Router Advertisement
8200 # reply packet from the ovn-controller.
8201
8202 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8203 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8204 # 'slaac' to allow lrp0 send RA for SLAAC mode.
8205 ovn-nbctl ls-add lsw0
8206 ovn-nbctl lr-add lr0
8207 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8208 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8209 ovn-nbctl \
8210 -- lsp-add lsw0 lsp0 \
8211 -- set Logical_Switch_Port lsp0 type=router \
8212 options:router-port=lrp0 \
8213 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8214 net_add n1
8215 sim_add hv1
8216 as hv1
8217 ovs-vsctl add-br br-phys
8218 ovn_attach n1 br-phys 192.168.0.2
8219
8220 ovn-nbctl lsp-add lsw0 lp1
8221 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8222 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"
8223
8224 ovn-nbctl lsp-add lsw0 lp2
8225 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8226 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"
8227
8228 ovn-nbctl lsp-add lsw0 lp3
8229 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8230 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"
8231
8232 # Add ACL rule for ICMPv6 on lsw0
8233 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8234 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8235 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8236 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8237
8238 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8239 set interface hv1-vif1 external-ids:iface-id=lp1 \
8240 options:tx_pcap=hv1/vif1-tx.pcap \
8241 options:rxq_pcap=hv1/vif1-rx.pcap \
8242 ofport-request=1
8243
8244 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8245 set interface hv1-vif2 external-ids:iface-id=lp2 \
8246 options:tx_pcap=hv1/vif2-tx.pcap \
8247 options:rxq_pcap=hv1/vif2-rx.pcap \
8248 ofport-request=2
8249
8250 ovs-vsctl -- add-port br-int hv1-vif3 -- \
8251 set interface hv1-vif3 external-ids:iface-id=lp3 \
8252 options:tx_pcap=hv1/vif3-tx.pcap \
8253 options:rxq_pcap=hv1/vif3-rx.pcap \
8254 ofport-request=3
8255
8256 # Allow some time for ovn-northd and ovn-controller to catch up.
8257 # XXX This should be more systematic.
8258 sleep 1
8259
8260 reset_pcap_file() {
8261 local iface=$1
8262 local pcap_file=$2
8263 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8264 options:rxq_pcap=dummy-rx.pcap
8265 rm -f ${pcap_file}*.pcap
8266 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8267 options:rxq_pcap=${pcap_file}-rx.pcap
8268 }
8269
8270 # Make sure that ovn-controller has installed the corresponding OF Flow.
8271 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"`])
8272
8273 # This shell function sends a Router Solicitation packet.
8274 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8275 test_ipv6_ra() {
8276 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8277 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8278
8279 local len=24
8280 local mtu_opt=""
8281 if test $mtu != 0; then
8282 len=`expr $len + 8`
8283 mtu_opt=05010000${mtu}
8284 fi
8285
8286 if test ${#prefix_opt} != 0; then
8287 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8288 len=`expr $len + ${#prefix_opt} / 2`
8289 fi
8290
8291 len=$(printf "%x" $len)
8292 local lrp_mac=fa163e000001
8293 local lrp_lla=fe80000000000000f8163efffe000001
8294 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8295 echo $reply >> $inport.expected
8296
8297 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8298 }
8299
8300 AT_CAPTURE_FILE([ofctl_monitor0.log])
8301 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8302 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8303
8304 # MTU is not set and the address mode is set to slaac
8305 addr_mode=00
8306 default_prefix_option_config=030440c0ffffffffffffffff00000000
8307 src_mac=fa163e000002
8308 src_lla=fe80000000000000f8163efffe000002
8309 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8310
8311 # NXT_RESUME should be 1.
8312 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8313
8314 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8315
8316 cat 1.expected | cut -c -112 > expout
8317 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8318
8319 # Skipping the ICMPv6 checksum.
8320 cat 1.expected | cut -c 117- > expout
8321 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8322
8323 rm -f *.expected
8324 reset_pcap_file hv1-vif1 hv1/vif1
8325 reset_pcap_file hv1-vif2 hv1/vif2
8326 reset_pcap_file hv1-vif3 hv1/vif3
8327
8328 # Set the MTU to 1500
8329 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8330
8331 # Make sure that ovn-controller has installed the corresponding OF Flow.
8332 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"`])
8333
8334 addr_mode=00
8335 default_prefix_option_config=030440c0ffffffffffffffff00000000
8336 src_mac=fa163e000003
8337 src_lla=fe80000000000000f8163efffe000003
8338 mtu=000005dc
8339
8340 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8341
8342 # NXT_RESUME should be 2.
8343 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8344
8345 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8346
8347 cat 2.expected | cut -c -112 > expout
8348 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8349
8350 # Skipping the ICMPv6 checksum.
8351 cat 2.expected | cut -c 117- > expout
8352 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8353
8354 rm -f *.expected
8355 reset_pcap_file hv1-vif1 hv1/vif1
8356 reset_pcap_file hv1-vif2 hv1/vif2
8357 reset_pcap_file hv1-vif3 hv1/vif3
8358
8359 # Set the address mode to dhcpv6_stateful
8360 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8361 # Make sure that ovn-controller has installed the corresponding OF Flow.
8362 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"`])
8363
8364 addr_mode=80
8365 default_prefix_option_config=""
8366 src_mac=fa163e000004
8367 src_lla=fe80000000000000f8163efffe000004
8368 mtu=000005dc
8369
8370 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8371
8372 # NXT_RESUME should be 3.
8373 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8374
8375 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8376
8377 cat 3.expected | cut -c -112 > expout
8378 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8379
8380 # Skipping the ICMPv6 checksum.
8381 cat 3.expected | cut -c 117- > expout
8382 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8383
8384 rm -f *.expected
8385 reset_pcap_file hv1-vif1 hv1/vif1
8386 reset_pcap_file hv1-vif2 hv1/vif2
8387 reset_pcap_file hv1-vif3 hv1/vif3
8388
8389 # Set the address mode to dhcpv6_stateless
8390 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8391 # Make sure that ovn-controller has installed the corresponding OF Flow.
8392 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"`])
8393
8394 addr_mode=40
8395 default_prefix_option_config=030440c0ffffffffffffffff00000000
8396 src_mac=fa163e000002
8397 src_lla=fe80000000000000f8163efffe000002
8398 mtu=000005dc
8399
8400 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8401
8402 # NXT_RESUME should be 4.
8403 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8404
8405 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8406
8407 cat 1.expected | cut -c -112 > expout
8408 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8409
8410 # Skipping the ICMPv6 checksum.
8411 cat 1.expected | cut -c 117- > expout
8412 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8413
8414 rm -f *.expected
8415 reset_pcap_file hv1-vif1 hv1/vif1
8416 reset_pcap_file hv1-vif2 hv1/vif2
8417 reset_pcap_file hv1-vif3 hv1/vif3
8418
8419 # Set the address mode to invalid.
8420 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8421 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8422 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"`])
8423
8424 addr_mode=40
8425 default_prefix_option_config=""
8426 src_mac=fa163e000002
8427 src_lla=fe80000000000000f8163efffe000002
8428 mtu=000005dc
8429
8430 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8431
8432 # NXT_RESUME should be 4 only.
8433 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8434
8435 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8436 AT_CHECK([cat 1.packets], [0], [])
8437
8438 OVN_CLEANUP([hv1])
8439 AT_CLEANUP
8440
8441 AT_SETUP([ovn -- /32 router IP address])
8442 AT_SKIP_IF([test $HAVE_PYTHON = no])
8443 ovn_start
8444
8445 # Logical network:
8446 # 2 LS 'foo' and 'alice' connected via router R1.
8447 # R1 connects to 'alice' with a /32 IP address. We use static routes and
8448 # nexthop to push traffic to a logical port in switch 'alice'
8449
8450 ovn-nbctl lr-add R1
8451
8452 ovn-nbctl ls-add foo
8453 ovn-nbctl ls-add alice
8454
8455 # Connect foo to R1
8456 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8457 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8458 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8459
8460 # Connect alice to R1.
8461 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8462 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8463 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8464
8465 # Create logical port foo1 in foo
8466 ovn-nbctl lsp-add foo foo1 \
8467 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8468
8469 # Create logical port alice1 in alice
8470 ovn-nbctl lsp-add alice alice1 \
8471 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8472
8473 #install default route in R1 to use alice1's IP address as nexthop
8474 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8475
8476 # Create two hypervisor and create OVS ports corresponding to logical ports.
8477 net_add n1
8478
8479 sim_add hv1
8480 as hv1
8481 ovs-vsctl add-br br-phys
8482 ovn_attach n1 br-phys 192.168.0.1
8483 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8484 set interface hv1-vif1 external-ids:iface-id=foo1 \
8485 options:tx_pcap=hv1/vif1-tx.pcap \
8486 options:rxq_pcap=hv1/vif1-rx.pcap \
8487 ofport-request=1
8488
8489 sim_add hv2
8490 as hv2
8491 ovs-vsctl add-br br-phys
8492 ovn_attach n1 br-phys 192.168.0.2
8493 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8494 set interface hv2-vif1 external-ids:iface-id=alice1 \
8495 options:tx_pcap=hv2/vif1-tx.pcap \
8496 options:rxq_pcap=hv2/vif1-rx.pcap \
8497 ofport-request=1
8498
8499
8500 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8501 # packets for ARP resolution (native tunneling doesn't queue packets
8502 # for ARP resolution).
8503 OVN_POPULATE_ARP
8504
8505 # Allow some time for ovn-northd and ovn-controller to catch up.
8506 # XXX This should be more systematic.
8507 sleep 1
8508
8509 ip_to_hex() {
8510 printf "%02x%02x%02x%02x" "$@"
8511 }
8512
8513 # Send ip packets between foo1 and alice1
8514 src_mac="f00000010203"
8515 dst_mac="000000010203"
8516 src_ip=`ip_to_hex 192 168 1 2`
8517 dst_ip=`ip_to_hex 10 0 0 2`
8518 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8519
8520 # Send the first packet to trigger a ARP response and population of
8521 # mac_bindings table.
8522 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8523 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8524 ovn-nbctl --wait=hv sync
8525 # Send the second packet to reach the destination.
8526 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8527
8528 # Packet to Expect at 'alice1'
8529 src_mac="000000010204"
8530 dst_mac="f00000010204"
8531 src_ip=`ip_to_hex 192 168 1 2`
8532 dst_ip=`ip_to_hex 10 0 0 2`
8533 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8534
8535 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8536
8537 OVN_CLEANUP([hv1],[hv2])
8538
8539 AT_CLEANUP
8540
8541 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8542 AT_SKIP_IF([test $HAVE_PYTHON = no])
8543 ovn_start
8544
8545 ovn-nbctl ls-add ls1
8546
8547 # Add localport to the switch
8548 ovn-nbctl lsp-add ls1 lp01
8549 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8550 ovn-nbctl lsp-set-type lp01 localport
8551
8552 net_add n1
8553
8554 for i in 1 2; do
8555 sim_add hv$i
8556 as hv$i
8557 ovs-vsctl add-br br-phys
8558 ovn_attach n1 br-phys 192.168.0.$i
8559 ovs-vsctl add-port br-int vif01 -- \
8560 set Interface vif01 external-ids:iface-id=lp01 \
8561 options:tx_pcap=hv${i}/vif01-tx.pcap \
8562 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8563 ofport-request=${i}0
8564
8565 ovs-vsctl add-port br-int vif${i}1 -- \
8566 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8567 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8568 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8569 ofport-request=${i}1
8570
8571 ovn-nbctl lsp-add ls1 lp${i}1
8572 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8573 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8574
8575 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8576 done
8577
8578 ovn-nbctl --wait=sb sync
8579 ovn-sbctl dump-flows
8580
8581 OVN_POPULATE_ARP
8582
8583 # Given the name of a logical port, prints the name of the hypervisor
8584 # on which it is located.
8585 vif_to_hv() {
8586 echo hv${1%?}
8587 }
8588 #
8589 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8590 #
8591 # This shell function causes a packet to be received on INPORT. The packet's
8592 # content has Ethernet destination DST and source SRC (each exactly 12 hex
8593 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8594 # logical switch port numbers, e.g. 11 for vif11.
8595 #
8596 # EOUT is the end-to-end output port, that is, where the packet will end up
8597 # after possibly bouncing through one or more localnet ports. LOUT is the
8598 # logical output port, which might be a localnet port, as seen by ovn-trace
8599 # (which doesn't know what localnet ports are connected to and therefore can't
8600 # figure out the end-to-end answer).
8601 #
8602 # DEFHV is the default hypervisor from where the packet is going to be sent
8603 # if the source port is a localport.
8604 for i in 1 2; do
8605 for j in 0 1; do
8606 : > $i$j.expected
8607 done
8608 done
8609 test_packet() {
8610 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8611 echo "$@"
8612
8613 # First try tracing the packet.
8614 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8615 if test $lout != drop; then
8616 echo "output(\"$lout\");"
8617 fi > expout
8618 AT_CAPTURE_FILE([trace])
8619 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8620
8621 # Then actually send a packet, for an end-to-end test.
8622 local packet=$(echo $dst$src | sed 's/://g')${eth}
8623 hv=`vif_to_hv $inport`
8624 # If hypervisor 0 (localport) use the defhv parameter
8625 if test $hv = hv0; then
8626 hv=$defhv
8627 fi
8628 vif=vif$inport
8629 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8630 if test $eout != drop; then
8631 echo $packet >> ${eout#lp}.expected
8632 fi
8633 }
8634
8635
8636 # lp11 and lp21 are on different hypervisors
8637 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8638 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8639
8640 # Both VIFs should be able to reach the localport on their own HV
8641 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8642 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8643
8644 # Packet sent from localport on same hv should reach the vif
8645 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8646 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8647
8648 # Packet sent from localport on different hv should be dropped
8649 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8650 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8651
8652 # Now check the packets actually received against the ones expected.
8653 for i in 1 2; do
8654 for j in 0 1; do
8655 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8656 done
8657 done
8658
8659 OVN_CLEANUP([hv1],[hv2])
8660
8661 AT_CLEANUP
8662
8663 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8664 AT_SKIP_IF([test $HAVE_PYTHON = no])
8665 ovn_start
8666
8667 net_add n1
8668
8669 # create gateways with external network connectivity
8670
8671 for i in 1 2; do
8672 sim_add gw$i
8673 as gw$i
8674 ovs-vsctl add-br br-phys
8675 ovn_attach n1 br-phys 192.168.0.$i
8676 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8677 done
8678
8679 ovn-nbctl ls-add inside
8680 ovn-nbctl ls-add outside
8681
8682 # create hypervisors with a vif port each to an internal network
8683
8684 for i in 1 2; do
8685 sim_add hv$i
8686 as hv$i
8687 ovs-vsctl add-br br-phys
8688 ovn_attach n1 br-phys 192.168.0.1$i
8689 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8690 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8691 options:tx_pcap=hv$i/vif1-tx.pcap \
8692 options:rxq_pcap=hv$i/vif1-rx.pcap \
8693 ofport-request=1
8694
8695 ovn-nbctl lsp-add inside inside$i \
8696 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8697
8698 done
8699
8700 OVN_POPULATE_ARP
8701
8702 ovn-nbctl create Logical_Router name=R1
8703
8704 # Connect inside to R1
8705 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8706 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8707 type=router options:router-port=inside \
8708 -- lsp-set-addresses rp-inside router
8709
8710 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8711 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8712
8713 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8714 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8715 --id=@gc1 create Gateway_Chassis \
8716 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8717 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8718
8719 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8720 type=router options:router-port=outside \
8721 -- lsp-set-addresses rp-outside router
8722
8723 # Create localnet port in outside
8724 ovn-nbctl lsp-add outside ln-outside
8725 ovn-nbctl lsp-set-addresses ln-outside unknown
8726 ovn-nbctl lsp-set-type ln-outside localnet
8727 ovn-nbctl lsp-set-options ln-outside network_name=phys
8728
8729 # Allow some time for ovn-northd and ovn-controller to catch up.
8730 # XXX This should be more systematic.
8731 ovn-nbctl --wait=hv --timeout=3 sync
8732
8733 echo "---------NB dump-----"
8734 ovn-nbctl show
8735 echo "---------------------"
8736 ovn-nbctl list logical_router
8737 echo "---------------------"
8738 ovn-nbctl list logical_router_port
8739 echo "---------------------"
8740
8741 echo "---------SB dump-----"
8742 ovn-sbctl list datapath_binding
8743 echo "---------------------"
8744 ovn-sbctl list port_binding
8745 echo "---------------------"
8746 ovn-sbctl dump-flows
8747 echo "---------------------"
8748 ovn-sbctl list chassis
8749 ovn-sbctl list encap
8750 echo "---------------------"
8751 echo "------ Gateway_Chassis dump (SBDB) -------"
8752 ovn-sbctl list Gateway_Chassis
8753 echo "------ Port_Binding chassisredirect -------"
8754 ovn-sbctl find Port_Binding type=chassisredirect
8755 echo "-------------------------------------------"
8756
8757 for chassis in gw1 gw2 hv1 hv2; do
8758 as $chassis
8759 echo "------ $chassis dump ----------"
8760 ovs-ofctl show br-int
8761 ovs-ofctl dump-flows br-int
8762 echo "--------------------------"
8763 done
8764 function bfd_dump() {
8765 for chassis in gw1 gw2 hv1 hv2; do
8766 as $chassis
8767 echo "------ $chassis dump (BFD)----"
8768 echo "BFD (from $chassis):"
8769 # dump BFD config and status to the other chassis
8770 for chassis2 in gw1 gw2 hv1 hv2; do
8771 if [[ "$chassis" != "$chassis2" ]]; then
8772 echo " -> $chassis2:"
8773 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8774 fi
8775 done
8776 echo "--------------------------"
8777 done
8778 }
8779
8780 bfd_dump
8781
8782 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8783 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8784 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8785 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8786
8787 echo $hv1_gw1_ofport
8788 echo $hv1_gw2_ofport
8789 echo $hv2_gw1_ofport
8790 echo $hv2_gw2_ofport
8791
8792 echo "--- hv1 ---"
8793 as hv1 ovs-ofctl dump-flows br-int table=32
8794
8795 echo "--- hv2 ---"
8796 as hv2 ovs-ofctl dump-flows br-int table=32
8797
8798 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8799 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8800
8801 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport | wc -l], [0], [1
8802 ])
8803
8804 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport | wc -l], [0], [1
8805 ])
8806
8807 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8808
8809 # make sure that flows for handling the outside router port reside on gw1
8810 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8811 ]])
8812 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8813 ]])
8814
8815 # make sure ARP responder flows for outside router port reside on gw1 too
8816 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8817 ]])
8818 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8819 ]])
8820
8821
8822
8823 # check that the chassis redirect port has been claimed by the gw1 chassis
8824 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8825 [0],[[1
8826 ]])
8827
8828
8829 # at this point, we invert the priority of the gw chassis between gw1 and gw2
8830
8831 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8832 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8833 --id=@gc1 create Gateway_Chassis \
8834 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8835 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8836
8837
8838 # XXX: Let the change propagate down to the ovn-controllers
8839 ovn-nbctl --wait=hv --timeout=3 sync
8840
8841 # we make sure that the hypervisors noticed, and inverted the slave ports
8842 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport | wc -l], [0], [1
8843 ])
8844
8845 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport | wc -l], [0], [1
8846 ])
8847
8848 # check that the chassis redirect port has been reclaimed by the gw2 chassis
8849 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8850 [0],[[1
8851 ]])
8852
8853 # check BFD enablement on tunnel ports from gw1 #########
8854 as gw1
8855 for chassis in gw2 hv1 hv2; do
8856 echo "checking gw1 -> $chassis"
8857 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8858 [[enable=true
8859 ]])
8860 done
8861
8862
8863 # check BFD enablement on tunnel ports from gw2 ##########
8864 as gw2
8865 for chassis in gw1 hv1 hv2; do
8866 echo "checking gw2 -> $chassis"
8867 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8868 [[enable=true
8869 ]])
8870 done
8871
8872 # check BFD enablement on tunnel ports from hv1 ###########
8873 as hv1
8874 for chassis in gw1 gw2; do
8875 echo "checking hv1 -> $chassis"
8876 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8877 [[enable=true
8878 ]])
8879 done
8880 # make sure BFD is not enabled to hv2, we don't need it
8881 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8882 [[enable=false
8883 ]])
8884
8885
8886 # check BFD enablement on tunnel ports from hv2 ##########
8887 as hv2
8888 for chassis in gw1 gw2; do
8889 echo "checking hv2 -> $chassis"
8890 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8891 [[enable=true
8892 ]])
8893 done
8894 # make sure BFD is not enabled to hv1, we don't need it
8895 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8896 [[enable=false
8897 ]])
8898
8899 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8900
8901 # make sure that flows for handling the outside router port reside on gw2 now
8902 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8903 ]])
8904 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8905 ]])
8906
8907 # disconnect GW2 from the network, GW1 should take over
8908 as gw2
8909 port=${sandbox}_br-phys
8910 as main ovs-vsctl del-port n1 $port
8911 sleep 4
8912
8913 bfd_dump
8914
8915 # make sure that flows for handling the outside router port reside on gw2 now
8916 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8917 ]])
8918 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8919 ]])
8920
8921 # check that the chassis redirect port has been reclaimed by the gw1 chassis
8922 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8923 [0],[[1
8924 ]])
8925
8926 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8927
8928 AT_CLEANUP
8929
8930 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8931 AT_SKIP_IF([test $HAVE_PYTHON = no])
8932 ovn_start
8933 ovn-nbctl ls-add ls0
8934 ovn-nbctl ls-add ls1
8935 ovn-nbctl create Logical_Router name=lr0
8936 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8937
8938 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8939 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8940 --id=@gc1 create Gateway_Chassis \
8941 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8942 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8943
8944 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8945 type=router options:router-port=lrp0 addresses="router"
8946 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8947 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8948 type=router options:router-port=lrp1 addresses="router"
8949
8950 # Add NAT rules
8951 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8952
8953 net_add n1
8954 sim_add hv1
8955 as hv1
8956 ovs-vsctl add-br br-phys
8957 ovn_attach n1 br-phys 192.168.0.1
8958 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8959 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])
8960
8961 sim_add hv2
8962 as hv2
8963 ovs-vsctl add-br br-phys
8964 ovn_attach n1 br-phys 192.168.0.2
8965 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8966
8967 sim_add hv3
8968 as hv3
8969 ovs-vsctl add-br br-phys
8970 ovn_attach n1 br-phys 192.168.0.3
8971 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8972
8973 # Create a localnet port.
8974 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8975 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8976 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8977 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8978
8979 # wait for earlier changes to take effect
8980 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
8981
8982 reset_pcap_file() {
8983 local iface=$1
8984 local pcap_file=$2
8985 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8986 options:rxq_pcap=dummy-rx.pcap
8987 rm -f ${pcap_file}*.pcap
8988 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8989 options:rxq_pcap=${pcap_file}-rx.pcap
8990 }
8991
8992 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8993 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8994 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8995 # add nat-addresses option
8996 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8997
8998 # Wait for packets to be received through hv2.
8999 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9000 trim_zeros() {
9001 sed 's/\(00\)\{1,\}$//'
9002 }
9003
9004 only_broadcast_from_lrp1() {
9005 grep "fffffffffffff00000000001"
9006 }
9007
9008 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
9009 echo $garp > expout
9010
9011 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
9012 echo "packets on hv1-snoopvif:"
9013 cat hv1_snoop_tx
9014 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
9015 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9016 echo "packets on hv2 br-phys tx"
9017 cat hv2_br_phys_tx
9018 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
9019 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9020 echo "packets on hv3 br-phys tx"
9021 cat hv3_br_phys_tx
9022 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9023
9024
9025 # at this point, we invert the priority of the gw chassis between hv2 and hv3
9026
9027 ovn-nbctl --wait=hv \
9028 --id=@gc0 create Gateway_Chassis \
9029 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9030 --id=@gc1 create Gateway_Chassis \
9031 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9032 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9033
9034
9035 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9036 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9037 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9038
9039 # Wait for packets to be received.
9040 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9041 trim_zeros() {
9042 sed 's/\(00\)\{1,\}$//'
9043 }
9044
9045 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9046 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9047 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9048 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9049 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9050 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9051
9052 # change localnet port tag.
9053 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9054
9055 # wait for earlier changes to take effect
9056 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
9057
9058 # update nat-addresses option
9059 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9060 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9061
9062 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9063 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9064 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9065
9066 # Wait for packets to be received.
9067 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9068 trim_zeros() {
9069 sed 's/\(00\)\{1,\}$//'
9070 }
9071
9072 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9073 echo $garp > expout
9074
9075 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9076 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9077 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9078 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9079 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9080 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9081
9082 OVN_CLEANUP([hv1],[hv2],[hv3])
9083
9084 AT_CLEANUP
9085
9086 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9087 AT_SKIP_IF([test $HAVE_PYTHON = no])
9088 ovn_start
9089
9090 net_add n1
9091
9092 # create two gateways with external network connectivity
9093 for i in 1 2; do
9094 sim_add gw$i
9095 as gw$i
9096 ovs-vsctl add-br br-phys
9097 ovn_attach n1 br-phys 192.168.0.$i
9098 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9099 done
9100
9101 ovn-nbctl ls-add inside
9102 ovn-nbctl ls-add outside
9103
9104 # create one hypervisors with a vif port the internal network
9105 sim_add hv1
9106 as hv1
9107 ovs-vsctl add-br br-phys
9108 ovn_attach n1 br-phys 192.168.0.11
9109 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9110 set interface hv1-vif1 external-ids:iface-id=inside1 \
9111 options:tx_pcap=hv1/vif1-tx.pcap \
9112 options:rxq_pcap=hv1/vif1-rx.pcap \
9113 ofport-request=1
9114
9115 ovn-nbctl lsp-add inside inside1 \
9116 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9117
9118
9119 OVN_POPULATE_ARP
9120
9121 ovn-nbctl create Logical_Router name=R1
9122
9123 # Connect inside to R1
9124 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9125 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9126 type=router options:router-port=inside \
9127 -- lsp-set-addresses rp-inside router
9128
9129 # Connect outside to R1 as distributed router gateway port on gw1+gw2
9130 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9131
9132 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9133 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9134 --id=@gc1 create Gateway_Chassis \
9135 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9136 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9137
9138 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9139 type=router options:router-port=outside \
9140 -- lsp-set-addresses rp-outside router
9141
9142 # Create localnet port in outside
9143 ovn-nbctl lsp-add outside ln-outside
9144 ovn-nbctl lsp-set-addresses ln-outside unknown
9145 ovn-nbctl lsp-set-type ln-outside localnet
9146 ovn-nbctl lsp-set-options ln-outside network_name=phys
9147
9148 # Allow some time for ovn-northd and ovn-controller to catch up.
9149 ovn-nbctl --wait=hv --timeout=3 sync
9150
9151 # currently when ovn-controller is restarted, the old entry is deleted
9152 # and a new one is created, which leaves the Gateway_Chassis with
9153 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
9154 # doesn't have the same effect because "name" is conserved, and the
9155 # Chassis entry is not replaced.
9156
9157 > gw1/ovn-controller.log
9158
9159 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9160 ovn-sbctl destroy Chassis $gw2_chassis
9161
9162 # Ensure ovn-controller has processed latest sbdb update
9163 # ovn-nbctl --wait=hv sync
9164
9165 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9166
9167 OVN_CLEANUP([gw1],[gw2],[hv1])
9168
9169 AT_CLEANUP
9170
9171 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9172 AT_KEYWORDS([ovn-nd_ns for unknown mac])
9173 AT_SKIP_IF([test $HAVE_PYTHON = no])
9174 ovn_start
9175
9176 ovn-nbctl ls-add sw0_ip6
9177 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9178 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9179 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9180
9181 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9182 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9183
9184 ovn-nbctl lr-add lr0_ip6
9185 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
9186 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9187 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9188 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
9189 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9190 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9191
9192 ovn-nbctl ls-add public
9193 ovn-nbctl lsp-add public ln-public
9194 ovn-nbctl lsp-set-addresses ln-public unknown
9195 ovn-nbctl lsp-set-type ln-public localnet
9196 ovn-nbctl lsp-set-options ln-public network_name=phys
9197
9198 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
9199 2001:db8:1:0:200:02ff:fe01:0204/64 \
9200 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9201
9202
9203 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9204 rp-ip6_public type=router options:router-port=ip6_public \
9205 -- lsp-set-addresses rp-ip6_public router
9206
9207 net_add n1
9208 sim_add hv1
9209 as hv1
9210 ovs-vsctl add-br br-phys
9211 ovn_attach n1 br-phys 192.168.0.2
9212
9213 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9214 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9215 options:tx_pcap=hv1/vif1-tx.pcap \
9216 options:rxq_pcap=hv1/vif1-rx.pcap \
9217 ofport-request=1
9218 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9219
9220 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9221 cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9222
9223 # There is only one chassis.
9224 chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9225 OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
9226
9227 trim_zeros() {
9228 sed 's/\(00\)\{1,\}$//'
9229 }
9230
9231 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9232 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
9233 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9234 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9235 # This function sends ipv6 packet
9236 test_ipv6() {
9237 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9238 dst_ip=20010db800010000020002fffe010205
9239
9240 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9241 packet=${packet}8000000000000000
9242 shift; shift; shift; shift
9243
9244 dst_mac=3333ff010205
9245 src_mac=000002010204
9246 mcast_node_ip=ff0200000000000000000001ff010205
9247 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9248 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9249 expected_packet=${expected_packet}0101${src_mac}
9250
9251 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9252 echo $expected_packet >> ipv6_ns.expected
9253 }
9254
9255 src_mac=506400000002
9256 dst_mac=00000000af01
9257 src_ip=aef0000000000000526400fffe000002
9258 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9259 # should be received by the ports attached to br-phys.
9260 test_ipv6 1 $src_mac $dst_mac $src_ip 2
9261
9262 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9263 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9264
9265 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9266 trim_zeros > 1.packets
9267 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9268 trim_zeros > 2.packets
9269
9270 cat ipv6_ns.expected | cut -c -112 > expout
9271 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9272 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9273
9274 # Skipping the ICMPv6 checksum
9275 cat ipv6_ns.expected | cut -c 117- > expout
9276 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9277 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9278
9279 OVN_CLEANUP([hv1])
9280
9281 AT_CLEANUP
9282
9283 AT_SETUP([ovn -- options:requested-chassis for logical port])
9284 ovn_start
9285
9286 net_add n1
9287
9288 ovn-nbctl ls-add ls0
9289 ovn-nbctl lsp-add ls0 lsp0
9290
9291 # create two hypervisors, each with one vif port
9292 sim_add hv1
9293 as hv1
9294 ovs-vsctl add-br br-phys
9295 ovn_attach n1 br-phys 192.168.0.11
9296 ovs-vsctl -- add-port br-int hv1-vif0 -- \
9297 set Interface hv1-vif0 ofport-request=1
9298
9299 sim_add hv2
9300 as hv2
9301 ovs-vsctl add-br br-phys
9302 ovn_attach n1 br-phys 192.168.0.12
9303 ovs-vsctl -- add-port br-int hv2-vif0 -- \
9304 set Interface hv2-vif0 ofport-request=1
9305
9306 # Allow only chassis hv1 to bind logical port lsp0.
9307 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9308
9309 # Allow some time for ovn-northd and ovn-controller to catch up.
9310 ovn-nbctl --wait=hv --timeout=3 sync
9311
9312 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
9313 ovn-sbctl wait-until chassis hv1
9314 ovn-sbctl wait-until chassis hv2
9315 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9316 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9317
9318 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9319 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9320 as hv2
9321 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9322
9323 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9324 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9325
9326 # (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9327 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9328 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9329
9330 # (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9331 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9332 as hv1
9333 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9334
9335 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9336 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9337
9338 # (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9339 as hv1 ovs-ofctl dump-flows br-int
9340 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9341 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9342
9343 # (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9344 # the requested chassis for lsp0 is changed from hv1 to hv2.
9345 echo "verifying that lsp0 binding moves when requested-chassis is changed"
9346
9347 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9348 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9349 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
9350
9351 # (6) Chassis hv2 should add flows and hv1 should not.
9352 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9353 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9354
9355 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9356 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9357
9358 OVN_CLEANUP([hv1],[hv2])
9359
9360 AT_CLEANUP
9361
9362 AT_SETUP([ovn -- options:requested-chassis with hostname])
9363
9364 ovn_start
9365
9366 ovn-nbctl ls-add ls0
9367 ovn-nbctl lsp-add ls0 lsp0
9368
9369 net_add n1
9370 sim_add hv1
9371 as hv1
9372 ovs-vsctl add-br br-phys
9373 ovn_attach n1 br-phys 192.168.0.11
9374 ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
9375
9376 ovn-sbctl wait-until chassis hv1
9377 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9378 echo "hv1_hostname=${hv1_hostname}"
9379 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9380 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9381
9382 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9383 echo "hv1_uuid=${hv1_uuid}"
9384 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9385 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9386 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9387 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9388
9389 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9390 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9391 ovn-nbctl --wait=hv --timeout=3 sync
9392 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9393 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9394 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9395
9396 OVN_CLEANUP([hv1])
9397
9398 AT_CLEANUP
9399
9400 AT_SETUP([ovn -- IPv6 periodic RA])
9401 ovn_start
9402
9403 # This test sets up two hypervisors.
9404 # hv1 and hv2 run ovn-controllers, and
9405 # each has a VIF connected to the same
9406 # logical switch in OVN. The logical
9407 # switch is connected to a logical
9408 # router port that is configured to send
9409 # periodic router advertisements.
9410 #
9411 # The reason for having two ovn-controller
9412 # hypervisors is to ensure that the
9413 # periodic RAs being sent by each ovn-controller
9414 # are kept to their local hypervisors. If the
9415 # packets are not kept local, then each port
9416 # will receive too many RAs.
9417
9418 net_add n1
9419 sim_add hv1
9420 sim_add hv2
9421 as hv1
9422 ovs-vsctl add-br br-phys
9423 ovn_attach n1 br-phys 192.168.0.2
9424 as hv2
9425 ovs-vsctl add-br br-phys
9426 ovn_attach n1 br-phys 192.168.0.3
9427
9428 ovn-nbctl lr-add ro
9429 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
9430
9431 ovn-nbctl ls-add sw
9432 ovn-nbctl lsp-add sw sw-ro
9433 ovn-nbctl lsp-set-type sw-ro router
9434 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9435 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9436 ovn-nbctl lsp-add sw sw-p1
9437 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9438 ovn-nbctl lsp-add sw sw-p2
9439 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9440
9441 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9442 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9443 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9444 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9445
9446 for i in 1 2 ; do
9447 as hv$i
9448 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9449 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9450 options:tx_pcap=hv$i/vif1-tx.pcap \
9451 options:rxq_pcap=hv$i/vif1-rx.pcap \
9452 ofport-request=1
9453 done
9454
9455 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9456 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
9457
9458 reset_pcap_file() {
9459 local iface=$1
9460 local pcap_file=$2
9461 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9462 options:rxq_pcap=dummy-rx.pcap
9463 rm -f ${pcap_file}*.pcap
9464 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9465 options:rxq_pcap=${pcap_file}-rx.pcap
9466
9467 }
9468
9469 construct_expected_ra() {
9470 local src_mac=000000000001
9471 local dst_mac=333300000001
9472 local src_addr=fe80000000000000020000fffe000001
9473 local dst_addr=ff020000000000000000000000000001
9474
9475 local mtu=$1
9476 local ra_mo=$2
9477 local ra_prefix_la=$3
9478
9479 local slla=0101${src_mac}
9480 local mtu_opt=""
9481 if test $mtu != 0; then
9482 mtu_opt=05010000${mtu}
9483 fi
9484 shift 3
9485
9486 local prefix=""
9487 while [[ $# -gt 0 ]] ; do
9488 local size=$1
9489 local net=$2
9490 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9491 shift 2
9492 done
9493
9494 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
9495 local icmp=8600XXXX${ra}
9496
9497 local ip_len=$(expr ${#icmp} / 2)
9498 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
9499
9500 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9501 local eth=${dst_mac}${src_mac}86dd${ip}
9502 local packet=${eth}
9503 echo $packet >> expected
9504 }
9505
9506 ra_test() {
9507 construct_expected_ra $@
9508
9509 for i in hv1 hv2 ; do
9510 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9511
9512 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9513
9514 cat expected | cut -c -112 > expout
9515 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9516
9517 # Skip ICMPv6 checksum.
9518 cat expected | cut -c 117- > expout
9519 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9520
9521 rm -f packets
9522 as $i reset_pcap_file $i-vif1 $i/vif1
9523 done
9524
9525 rm -f expected
9526 }
9527
9528 # Baseline test with no MTU
9529 ra_test 0 00 c0 40 aef00000000000000000000000000000
9530
9531 # Now make sure an MTU option makes it
9532 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9533 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9534
9535 # Now test for multiple network prefixes
9536 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9537 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9538
9539 # Test a different address mode now
9540 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9541 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9542
9543 # And the other address mode
9544 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9545 ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9546
9547 OVN_CLEANUP([hv1],[hv2])
9548 AT_CLEANUP
9549
9550 AT_SETUP([ovn -- ACL reject rule test])
9551 AT_KEYWORDS([acl-reject])
9552 AT_SKIP_IF([test $HAVE_PYTHON = no])
9553 ovn_start
9554
9555 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9556 #
9557 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9558 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9559 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9560 # unreachable frame generated from ACL rule hit
9561 #
9562 # INPORT is a lport number, e.g. 11 for vif11.
9563 # HV is a hypervisor number
9564 # ETH_SRC and ETH_DST are each 12 hex digits.
9565 # IPV4_SRC and IPV4_DST are each 8 hex digits.
9566 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9567 test_ip_packet() {
9568 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9569 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9570 shift 9
9571
9572 local ip_ttl=ff
9573 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9574
9575 local reply_icmp_ttl=ff
9576 local icmp_type_code_response=0301
9577 local icmp_data=00000000
9578 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9579 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9580 echo $reply >> vif$inport.expected
9581
9582 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9583 }
9584
9585 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
9586 #
9587 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
9588 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
9589 # EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
9590 test_ipv6_packet() {
9591 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
9592 shift 7
9593
9594 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9595 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
9596
9597 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
9598 echo $reply >> vif$inport.expected
9599
9600 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9601 }
9602
9603 # 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
9604 #
9605 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
9606 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
9607 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
9608 #
9609 # INPORT is an lport number, e.g. 11 for vif11.
9610 # HV is an hypervisor number
9611 # ETH_SRC and ETH_DST are each 12 hex digits.
9612 # IPV4_SRC and IPV4_DST are each 8 hex digits.
9613 # TCP_SPORT and TCP_DPORT are 4 hex digits.
9614 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
9615 test_tcp_syn_packet() {
9616 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9617 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
9618 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
9619 shift 12
9620
9621 local ip_ttl=ff
9622 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
9623
9624 local tcp_rst_ttl=ff
9625 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
9626 echo $reply >> vif$inport.expected
9627
9628 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9629 }
9630
9631 # Create hypervisors hv[123].
9632 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
9633 # Add all of the vifs to a single logical switch sw0.
9634
9635 net_add n1
9636 ovn-nbctl ls-add sw0
9637 for i in 1 2 3; do
9638 sim_add hv$i
9639 as hv$i
9640 ovs-vsctl add-br br-phys
9641 ovn_attach n1 br-phys 192.168.0.$i
9642
9643 for j in 1 2 3; do
9644 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
9645 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
9646
9647 ovs-vsctl -- add-port br-int vif$i$j -- \
9648 set interface vif$i$j \
9649 external-ids:iface-id=sw0-p$i$j \
9650 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
9651 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
9652 ofport-request=$i$j
9653 done
9654 done
9655
9656 OVN_POPULATE_ARP
9657 # allow some time for ovn-northd and ovn-controller to catch up.
9658 sleep 1
9659
9660 ip_to_hex() {
9661 printf "%02x%02x%02x%02x" "$@"
9662 }
9663
9664 for i in 1 2 3; do
9665 : > vif${i}1.expected
9666 done
9667
9668 ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
9669 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
9670 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
9671
9672 # Allow some time for ovn-northd and ovn-controller to catch up.
9673 ovn-nbctl --timeout=3 --wait=hv sync
9674
9675 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
9676 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
9677 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
9678
9679 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
9680
9681 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
9682 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
9683 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
9684
9685 for i in 1 2 3; do
9686 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
9687 done
9688
9689 OVN_CLEANUP([hv1], [hv2], [hv3])
9690 AT_CLEANUP
9691
9692 AT_SETUP([ovn -- Port Groups])
9693 AT_KEYWORDS([ovnpg])
9694 AT_SKIP_IF([test $HAVE_PYTHON = no])
9695 ovn_start
9696
9697 # Logical network:
9698 #
9699 # Three logical switches ls1, ls2, ls3.
9700 # One logical router lr0 connected to ls[123],
9701 # with nine subnets, three per logical switch:
9702 #
9703 # lrp11 on ls1 for subnet 192.168.11.0/24
9704 # lrp12 on ls1 for subnet 192.168.12.0/24
9705 # lrp13 on ls1 for subnet 192.168.13.0/24
9706 # ...
9707 # lrp33 on ls3 for subnet 192.168.33.0/24
9708 #
9709 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9710 # digits are the subnet and the last digit distinguishes the VIF.
9711 #
9712 # This test will create two port groups and uses them in ACL.
9713
9714 get_lsp_uuid () {
9715 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9716 }
9717
9718 pg1_ports=
9719 pg2_ports=
9720 for i in 1 2 3; do
9721 ovn-nbctl ls-add ls$i
9722 for j in 1 2 3; do
9723 for k in 1 2 3; do
9724 ovn-nbctl \
9725 -- lsp-add ls$i lp$i$j$k \
9726 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
9727 192.168.$i$j.$k"
9728 # logical ports lp[12]?1 belongs to port group pg1
9729 if test $i != 3 && test $k == 1; then
9730 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9731 fi
9732 # logical ports lp[23]?2 belongs to port group pg2
9733 if test $i != 1 && test $k == 2; then
9734 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9735 fi
9736 done
9737 done
9738 done
9739
9740 ovn-nbctl lr-add lr0
9741 for i in 1 2 3; do
9742 for j in 1 2 3; do
9743 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9744 ovn-nbctl \
9745 -- lsp-add ls$i lrp$i$j-attachment \
9746 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9747 options:router-port=lrp$i$j \
9748 addresses='"00:00:00:00:ff:'$i$j'"'
9749 done
9750 done
9751
9752 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9753 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9754
9755 # create ACLs on all lswitches to drop traffic from pg2 to pg1
9756 ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9757 ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9758 ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9759
9760 # Physical network:
9761 #
9762 # Three hypervisors hv[123].
9763 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9764 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9765 # lp?3[123] all on hv3.
9766
9767 # Given the name of a logical port, prints the name of the hypervisor
9768 # on which it is located.
9769 vif_to_hv() {
9770 case $1 in dnl (
9771 ?11) echo 1 ;; dnl (
9772 ?12 | ?21 | ?22) echo 2 ;; dnl (
9773 ?13 | ?23 | ?3?) echo 3 ;;
9774 esac
9775 }
9776
9777 # Given the name of a logical port, prints the name of its logical router
9778 # port, e.g. "vif_to_lrp 123" yields 12.
9779 vif_to_lrp() {
9780 echo ${1%?}
9781 }
9782
9783 # Given the name of a logical port, prints the name of its logical
9784 # switch, e.g. "vif_to_ls 123" yields 1.
9785 vif_to_ls() {
9786 echo ${1%??}
9787 }
9788
9789 net_add n1
9790 for i in 1 2 3; do
9791 sim_add hv$i
9792 as hv$i
9793 ovs-vsctl add-br br-phys
9794 ovn_attach n1 br-phys 192.168.0.$i
9795 done
9796 for i in 1 2 3; do
9797 for j in 1 2 3; do
9798 for k in 1 2 3; do
9799 hv=`vif_to_hv $i$j$k`
9800 as hv$hv ovs-vsctl \
9801 -- add-port br-int vif$i$j$k \
9802 -- set Interface vif$i$j$k \
9803 external-ids:iface-id=lp$i$j$k \
9804 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
9805 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
9806 ofport-request=$i$j$k
9807 done
9808 done
9809 done
9810
9811 # Pre-populate the hypervisors' ARP tables so that we don't lose any
9812 # packets for ARP resolution (native tunneling doesn't queue packets
9813 # for ARP resolution).
9814 OVN_POPULATE_ARP
9815
9816 # Allow some time for ovn-northd and ovn-controller to catch up.
9817 # XXX This should be more systematic.
9818 sleep 1
9819
9820 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9821 #
9822 # This shell function causes a packet to be received on INPORT. The packet's
9823 # content has Ethernet destination DST and source SRC (each exactly 12 hex
9824 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
9825 # more) list the VIFs on which the packet should be received. INPORT and the
9826 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9827 for i in 1 2 3; do
9828 for j in 1 2 3; do
9829 for k in 1 2 3; do
9830 : > $i$j$k.expected
9831 done
9832 done
9833 done
9834 test_ip() {
9835 # This packet has bad checksums but logical L3 routing doesn't check.
9836 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
9837 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9838 shift; shift; shift; shift; shift
9839 hv=hv`vif_to_hv $inport`
9840 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
9841 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
9842 in_ls=`vif_to_ls $inport`
9843 in_lrp=`vif_to_lrp $inport`
9844 for outport; do
9845 out_ls=`vif_to_ls $outport`
9846 if test $in_ls = $out_ls; then
9847 # Ports on the same logical switch receive exactly the same packet.
9848 echo $packet
9849 else
9850 # Routing decrements TTL and updates source and dest MAC
9851 # (and checksum).
9852 out_lrp=`vif_to_lrp $outport`
9853 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
9854 fi >> $outport.expected
9855 done
9856 }
9857
9858 as hv1 ovs-vsctl --columns=name,ofport list interface
9859 as hv1 ovn-sbctl list port_binding
9860 as hv1 ovn-sbctl list datapath_binding
9861 as hv1 ovn-sbctl list port_group
9862 as hv1 ovn-sbctl list address_set
9863 as hv1 ovn-sbctl dump-flows
9864 as hv1 ovs-ofctl dump-flows br-int
9865
9866 # Send IP packets between all pairs of source and destination ports,
9867 # packets matches ACL (pg2 to pg1) should be dropped
9868 ip_to_hex() {
9869 printf "%02x%02x%02x%02x" "$@"
9870 }
9871 for is in 1 2 3; do
9872 for js in 1 2 3; do
9873 for ks in 1 2 3; do
9874 bcast=
9875 s=$is$js$ks
9876 smac=f00000000$s
9877 sip=`ip_to_hex 192 168 $is$js $ks`
9878 for id in 1 2 3; do
9879 for jd in 1 2 3; do
9880 for kd in 1 2 3; do
9881 d=$id$jd$kd
9882 dip=`ip_to_hex 192 168 $id$jd $kd`
9883 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
9884 if test $d != $s; then unicast=$d; else unicast=; fi
9885
9886 # packets matches ACL should be dropped
9887 if test $id != 3 && test $kd == 1; then
9888 if test $is != 1 && test $ks == 2; then
9889 unicast=
9890 fi
9891 fi
9892 test_ip $s $smac $dmac $sip $dip $unicast #1
9893 done
9894 done
9895 done
9896 done
9897 done
9898 done
9899
9900 # Allow some time for packet forwarding.
9901 # XXX This can be improved.
9902 sleep 1
9903
9904 # Now check the packets actually received against the ones expected.
9905 for i in 1 2 3; do
9906 for j in 1 2 3; do
9907 for k in 1 2 3; do
9908 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
9909 [$i$j$k.expected])
9910 done
9911 done
9912 done
9913
9914 # Gracefully terminate daemons
9915 OVN_CLEANUP([hv1], [hv2], [hv3])
9916 AT_CLEANUP
9917
9918 AT_SETUP([ovn -- ACLs on Port Groups])
9919 AT_KEYWORDS([ovnpg_acl])
9920 AT_SKIP_IF([test $HAVE_PYTHON = no])
9921 ovn_start
9922
9923 # Logical network:
9924 #
9925 # Three logical switches ls1, ls2, ls3.
9926 # One logical router lr0 connected to ls[123],
9927 # with nine subnets, three per logical switch:
9928 #
9929 # lrp11 on ls1 for subnet 192.168.11.0/24
9930 # lrp12 on ls1 for subnet 192.168.12.0/24
9931 # lrp13 on ls1 for subnet 192.168.13.0/24
9932 # ...
9933 # lrp33 on ls3 for subnet 192.168.33.0/24
9934 #
9935 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9936 # digits are the subnet and the last digit distinguishes the VIF.
9937 #
9938 # This test will create two port groups and ACLs will be applied on them.
9939
9940 get_lsp_uuid () {
9941 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9942 }
9943
9944 pg1_ports=
9945 pg2_ports=
9946 for i in 1 2 3; do
9947 ovn-nbctl ls-add ls$i
9948 for j in 1 2 3; do
9949 for k in 1 2 3; do
9950 ovn-nbctl \
9951 -- lsp-add ls$i lp$i$j$k \
9952 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
9953 192.168.$i$j.$k"
9954 # logical ports lp[12]?1 belongs to port group pg1
9955 if test $i != 3 && test $k == 1; then
9956 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9957 fi
9958 # logical ports lp[23]?2 belongs to port group pg2
9959 if test $i != 1 && test $k == 2; then
9960 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9961 fi
9962 done
9963 done
9964 done
9965
9966 ovn-nbctl lr-add lr0
9967 for i in 1 2 3; do
9968 for j in 1 2 3; do
9969 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9970 ovn-nbctl \
9971 -- lsp-add ls$i lrp$i$j-attachment \
9972 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9973 options:router-port=lrp$i$j \
9974 addresses='"00:00:00:00:ff:'$i$j'"'
9975 done
9976 done
9977
9978 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9979 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9980
9981 # create ACLs on pg1 to drop traffic from pg2 to pg1
9982 ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
9983 ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
9984 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
9985
9986 # Physical network:
9987 #
9988 # Three hypervisors hv[123].
9989 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9990 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9991 # lp?3[123] all on hv3.
9992
9993 # Given the name of a logical port, prints the name of the hypervisor
9994 # on which it is located.
9995 vif_to_hv() {
9996 case $1 in dnl (
9997 ?11) echo 1 ;; dnl (
9998 ?12 | ?21 | ?22) echo 2 ;; dnl (
9999 ?13 | ?23 | ?3?) echo 3 ;;
10000 esac
10001 }
10002
10003 # Given the name of a logical port, prints the name of its logical router
10004 # port, e.g. "vif_to_lrp 123" yields 12.
10005 vif_to_lrp() {
10006 echo ${1%?}
10007 }
10008
10009 # Given the name of a logical port, prints the name of its logical
10010 # switch, e.g. "vif_to_ls 123" yields 1.
10011 vif_to_ls() {
10012 echo ${1%??}
10013 }
10014
10015 net_add n1
10016 for i in 1 2 3; 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 done
10022 for i in 1 2 3; do
10023 for j in 1 2 3; do
10024 for k in 1 2 3; do
10025 hv=`vif_to_hv $i$j$k`
10026 as hv$hv ovs-vsctl \
10027 -- add-port br-int vif$i$j$k \
10028 -- set Interface vif$i$j$k \
10029 external-ids:iface-id=lp$i$j$k \
10030 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10031 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10032 ofport-request=$i$j$k
10033 done
10034 done
10035 done
10036
10037 # Pre-populate the hypervisors' ARP tables so that we don't lose any
10038 # packets for ARP resolution (native tunneling doesn't queue packets
10039 # for ARP resolution).
10040 OVN_POPULATE_ARP
10041
10042 # Allow some time for ovn-northd and ovn-controller to catch up.
10043 # XXX This should be more systematic.
10044 sleep 1
10045
10046 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10047 #
10048 # This shell function causes a packet to be received on INPORT. The packet's
10049 # content has Ethernet destination DST and source SRC (each exactly 12 hex
10050 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
10051 # more) list the VIFs on which the packet should be received. INPORT and the
10052 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
10053 for i in 1 2 3; do
10054 for j in 1 2 3; do
10055 for k in 1 2 3; do
10056 : > $i$j$k.expected
10057 done
10058 done
10059 done
10060 test_ip() {
10061 # This packet has bad checksums but logical L3 routing doesn't check.
10062 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10063 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
10064 shift; shift; shift; shift; shift
10065 hv=hv`vif_to_hv $inport`
10066 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
10067 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
10068 in_ls=`vif_to_ls $inport`
10069 in_lrp=`vif_to_lrp $inport`
10070 for outport; do
10071 out_ls=`vif_to_ls $outport`
10072 if test $in_ls = $out_ls; then
10073 # Ports on the same logical switch receive exactly the same packet.
10074 echo $packet
10075 else
10076 # Routing decrements TTL and updates source and dest MAC
10077 # (and checksum).
10078 out_lrp=`vif_to_lrp $outport`
10079 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10080 fi >> $outport.expected
10081 done
10082 }
10083
10084 as hv1 ovs-vsctl --columns=name,ofport list interface
10085 as hv1 ovn-sbctl list port_binding
10086 as hv1 ovn-sbctl list datapath_binding
10087 as hv1 ovn-sbctl list port_group
10088 as hv1 ovn-sbctl list address_set
10089 as hv1 ovn-sbctl dump-flows
10090 as hv1 ovs-ofctl dump-flows br-int
10091
10092 # Send IP packets between all pairs of source and destination ports,
10093 # packets matches ACL1 but not ACL2 should be dropped
10094 ip_to_hex() {
10095 printf "%02x%02x%02x%02x" "$@"
10096 }
10097 for is in 1 2 3; do
10098 for js in 1 2 3; do
10099 for ks in 1 2 3; do
10100 bcast=
10101 s=$is$js$ks
10102 smac=f00000000$s
10103 sip=`ip_to_hex 192 168 $is$js $ks`
10104 for id in 1 2 3; do
10105 for jd in 1 2 3; do
10106 for kd in 1 2 3; do
10107 d=$id$jd$kd
10108 dip=`ip_to_hex 192 168 $id$jd $kd`
10109 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10110 if test $d != $s; then unicast=$d; else unicast=; fi
10111
10112 # packets matches ACL1 but not ACL2 should be dropped
10113 if test $id != 3 && test $kd == 1; then
10114 if test $is == 1 || test $ks != 2; then
10115 unicast=
10116 fi
10117 fi
10118 test_ip $s $smac $dmac $sip $dip $unicast #1
10119 done
10120 done
10121 done
10122 done
10123 done
10124 done
10125
10126 # Allow some time for packet forwarding.
10127 # XXX This can be improved.
10128 sleep 1
10129
10130 # Now check the packets actually received against the ones expected.
10131 for i in 1 2 3; do
10132 for j in 1 2 3; do
10133 for k in 1 2 3; do
10134 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10135 [$i$j$k.expected])
10136 done
10137 done
10138 done
10139
10140 # Gracefully terminate daemons
10141 OVN_CLEANUP([hv1], [hv2], [hv3])
10142 AT_CLEANUP
10143
10144 AT_SETUP([ovn -- ACL conjunction])
10145 ovn_start
10146
10147 ovn-nbctl ls-add ls1
10148
10149 ovn-nbctl lsp-add ls1 ls1-lp1 \
10150 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10151
10152 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10153
10154 ovn-nbctl lsp-add ls1 ls1-lp2 \
10155 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10156
10157 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10158
10159 net_add n1
10160 sim_add hv1
10161
10162 as hv1
10163 ovs-vsctl add-br br-phys
10164 ovn_attach n1 br-phys 192.168.0.1
10165 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10166 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
10167 options:tx_pcap=hv1/vif1-tx.pcap \
10168 options:rxq_pcap=hv1/vif1-rx.pcap \
10169 ofport-request=1
10170
10171 ovs-vsctl -- add-port br-int hv1-vif2 -- \
10172 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
10173 options:tx_pcap=hv1/vif2-tx.pcap \
10174 options:rxq_pcap=hv1/vif2-rx.pcap \
10175 ofport-request=2
10176
10177 ovn-nbctl create Address_Set name=set1 \
10178 addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
10179 ovn-nbctl create Address_Set name=set2 \
10180 addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
10181 ovn-nbctl acl-add ls1 to-lport 1002 \
10182 'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
10183 ovn-nbctl acl-add ls1 to-lport 1001 \
10184 'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
10185
10186 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10187 #
10188 # This shell function causes an ip packet to be received on INPORT.
10189 # The packet's content has Ethernet destination DST and source SRC
10190 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
10191 # The OUTPORTs (zero or more) list the VIFs on which the packet should
10192 # be received. INPORT and the OUTPORTs are specified as logical switch
10193 # port numbers, e.g. 11 for vif11.
10194 test_ip() {
10195 # This packet has bad checksums but logical L3 routing doesn't check.
10196 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10197 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
10198 ${dst_ip}0035111100080000
10199 shift; shift; shift; shift; shift
10200 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
10201 for outport; do
10202 echo $packet >> $outport.expected
10203 done
10204 }
10205
10206 ip_to_hex() {
10207 printf "%02x%02x%02x%02x" "$@"
10208 }
10209
10210 reset_pcap_file() {
10211 local iface=$1
10212 local pcap_file=$2
10213 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10214 options:rxq_pcap=dummy-rx.pcap
10215 rm -f ${pcap_file}*.pcap
10216 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10217 options:rxq_pcap=${pcap_file}-rx.pcap
10218 }
10219
10220
10221 sip=`ip_to_hex 10 0 0 4`
10222 dip=`ip_to_hex 10 0 0 6`
10223
10224 test_ip 1 f00000000001 f00000000002 $sip $dip 2
10225
10226 cat 2.expected > expout
10227 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10228 AT_CHECK([cat 2.packets], [0], [expout])
10229
10230 # There should be total of 12 flows present with conjunction action and 2 flows
10231 # with conj match. Eg.
10232 # table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
10233 # table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
10234 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
10235 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
10236 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
10237 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
10238 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
10239 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
10240 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
10241 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
10242 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
10243 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
10244 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
10245 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
10246
10247 OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
10248 grep conjunction | wc -l`])
10249 OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
10250 grep conj_id | wc -l`])
10251
10252 as hv1 ovs-ofctl dump-flows br-int
10253
10254 # Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
10255 ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10256 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10257
10258 reset_pcap_file hv1-vif2 hv1/vif2
10259
10260 rm -f 2.packets
10261
10262 sip=`ip_to_hex 10 0 0 4`
10263 dip=`ip_to_hex 10 0 0 7`
10264
10265 test_ip 1 f00000000001 f00000000002 $sip $dip
10266 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10267 AT_CHECK([cat 2.packets], [0], [])
10268
10269 AT_CLEANUP