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