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