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