]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - tests/sys/netinet/fibs_test.sh
MFC r263445 and r265385. Note that the change to ObsoleteFiles.inc in
[FreeBSD/stable/10.git] / tests / sys / netinet / fibs_test.sh
1 #
2 #  Copyright (c) 2014 Spectra Logic Corporation
3 #  All rights reserved.
4 #
5 #  Redistribution and use in source and binary forms, with or without
6 #  modification, are permitted provided that the following conditions
7 #  are met:
8 #  1. Redistributions of source code must retain the above copyright
9 #     notice, this list of conditions, and the following disclaimer,
10 #     without modification.
11 #  2. Redistributions in binary form must reproduce at minimum a disclaimer
12 #     substantially similar to the "NO WARRANTY" disclaimer below
13 #     ("Disclaimer") and any redistribution must be conditioned upon
14 #     including a substantially similar Disclaimer requirement for further
15 #     binary redistribution.
16 #
17 #  NO WARRANTY
18 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 #  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
21 #  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 #  HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 #  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 #  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 #  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 #  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27 #  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 #  POSSIBILITY OF SUCH DAMAGES.
29 #
30 #  Authors: Alan Somers         (Spectra Logic Corporation)
31 #
32 # $FreeBSD$
33
34 # All of the tests in this file requires the test-suite config variable "fibs"
35 # to be defined to a space-delimited list of FIBs that may be used for testing.
36
37 # arpresolve should check the interface fib for routes to a target when
38 # creating an ARP table entry.  This is a regression for kern/167947, where
39 # arpresolve only checked the default route.
40 #
41 # Outline:
42 # Create two tap(4) interfaces
43 # Simulate a crossover cable between them by using net/socat
44 # Use nping (from security/nmap) to send an ICMP echo request from one
45 # interface to the other, spoofing the source IP.  The source IP must be
46 # spoofed, or else it will already have an entry in the arp table.
47 # Check whether an arp entry exists for the spoofed IP
48 atf_test_case arpresolve_checks_interface_fib cleanup
49 arpresolve_checks_interface_fib_head()
50 {
51         atf_set "descr" "arpresolve should check the interface fib, not the default fib, for routes"
52         atf_set "require.user" "root"
53         atf_set "require.config" "fibs"
54         atf_set "require.progs" "socat nping"
55 }
56 arpresolve_checks_interface_fib_body()
57 {
58         atf_expect_fail "kern/167947 arpresolve checks only the default FIB for the interface route"
59         # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
60         # and a non-default fib
61         ADDR0="192.0.2.2"
62         ADDR1="192.0.2.3"
63         SUBNET="192.0.2.0"
64         # Due to bug TBD (regressed by multiple_fibs_on_same_subnet) we need
65         # diffferent subnet masks, or FIB1 won't have a subnet route.
66         MASK0="24"
67         MASK1="25"
68         # Spoof a MAC that is reserved per RFC7042
69         SPOOF_ADDR="192.0.2.4"
70         SPOOF_MAC="00:00:5E:00:53:00"
71
72         # Check system configuration
73         if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
74                 atf_skip "This test requires net.add_addr_allfibs=0"
75         fi
76         get_fibs 2
77
78         # Configure TAP interfaces
79         setup_tap "$FIB0" ${ADDR0} ${MASK0}
80         TAP0=$TAP
81         setup_tap "$FIB1" ${ADDR1} ${MASK1}
82         TAP1=$TAP
83
84         # Simulate a crossover cable
85         socat /dev/${TAP0} /dev/${TAP1} &
86         SOCAT_PID=$!
87         echo ${SOCAT_PID} >> "processes_to_kill"
88
89         # Send an ICMP echo request with a spoofed source IP
90         setfib 2 nping -c 1 -e ${TAP0} -S ${SPOOF_ADDR} \
91                 --source-mac ${SPOOF_MAC} --icmp --icmp-type "echo-request" \
92                 --icmp-code 0 --icmp-id 0xdead --icmp-seq 1 --data 0xbeef \
93                 ${ADDR1}
94         # For informational and debugging purposes only, look for the
95         # characteristic error message
96         dmesg | grep "llinfo.*${SPOOF_ADDR}"
97         # Check that the ARP entry exists
98         atf_check -o match:"${SPOOF_ADDR}.*expires" setfib 3 arp ${SPOOF_ADDR}
99 }
100 arpresolve_checks_interface_fib_cleanup()
101 {
102         for PID in `cat "processes_to_kill"`; do
103                 kill $PID
104         done
105         cleanup_tap
106 }
107
108
109 # Regression test for kern/187549
110 atf_test_case loopback_and_network_routes_on_nondefault_fib cleanup
111 loopback_and_network_routes_on_nondefault_fib_head()
112 {
113         atf_set "descr" "When creating and deleting loopback routes, use the interface's fib"
114         atf_set "require.user" "root"
115         atf_set "require.config" "fibs"
116 }
117
118 loopback_and_network_routes_on_nondefault_fib_body()
119 {
120         atf_expect_fail "kern/187549 Host and network routes for a new interface appear in the wrong FIB"
121         # Configure the TAP interface to use an RFC5737 nonrouteable address
122         # and a non-default fib
123         ADDR="192.0.2.2"
124         SUBNET="192.0.2.0"
125         MASK="24"
126
127         # Check system configuration
128         if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
129                 atf_skip "This test requires net.add_addr_allfibs=0"
130         fi
131         get_fibs 1
132
133         # Configure a TAP interface
134         setup_tap ${FIB0} ${ADDR} ${MASK}
135
136         # Check whether the host route exists in only the correct FIB
137         setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
138         if [ 0 -ne $? ]; then
139                 setfib ${FIB0} netstat -rn -f inet
140                 atf_fail "Host route did not appear in the correct FIB"
141         fi
142         setfib 0 netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
143         if [ 0 -eq $? ]; then
144                 setfib 0 netstat -rn -f inet
145                 atf_fail "Host route appeared in the wrong FIB"
146         fi
147
148         # Check whether the network route exists in only the correct FIB
149         setfib ${FIB0} netstat -rn -f inet | \
150                 grep -q "^${SUBNET}/${MASK}.*${TAPD}"
151         if [ 0 -ne $? ]; then
152                 setfib ${FIB0} netstat -rn -f inet
153                 atf_fail "Network route did not appear in the correct FIB"
154         fi
155         setfib 0 netstat -rn -f inet | \
156                 grep -q "^${SUBNET}/${MASK}.*${TAPD}"
157         if [ 0 -eq $? ]; then
158                 setfib ${FIB0} netstat -rn -f inet
159                 atf_fail "Network route appeared in the wrong FIB"
160         fi
161 }
162
163 loopback_and_network_routes_on_nondefault_fib_cleanup()
164 {
165         cleanup_tap
166 }
167
168
169 # Regression test for kern/187552
170 atf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup
171 default_route_with_multiple_fibs_on_same_subnet_head()
172 {
173         atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default routes"
174         atf_set "require.user" "root"
175         atf_set "require.config" "fibs"
176 }
177
178 default_route_with_multiple_fibs_on_same_subnet_body()
179 {
180         atf_expect_fail "kern/187552 default route uses the wrong interface when multiple interfaces have the same subnet but different fibs"
181         # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
182         # and a non-default fib
183         ADDR0="192.0.2.2"
184         ADDR1="192.0.2.3"
185         GATEWAY="192.0.2.1"
186         SUBNET="192.0.2.0"
187         MASK="24"
188
189         # Check system configuration
190         if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
191                 atf_skip "This test requires net.add_addr_allfibs=0"
192         fi
193         get_fibs 2
194
195         # Configure TAP interfaces
196         setup_tap "$FIB0" ${ADDR0} ${MASK}
197         TAP0=$TAP
198         setup_tap "$FIB1" ${ADDR1} ${MASK}
199         TAP1=$TAP
200
201         # Attempt to add default routes
202         setfib ${FIB0} route add default ${GATEWAY}
203         setfib ${FIB1} route add default ${GATEWAY}
204
205         # Verify that the default route exists for both fibs, with their
206         # respective interfaces.
207         atf_check -o match:"^default.*${TAP0}$" \
208                 setfib ${FIB0} netstat -rn -f inet
209         atf_check -o match:"^default.*${TAP1}$" \
210                 setfib ${FIB1} netstat -rn -f inet
211 }
212
213 default_route_with_multiple_fibs_on_same_subnet_cleanup()
214 {
215         cleanup_tap
216 }
217
218
219 # Regression test for kern/187550
220 atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup
221 subnet_route_with_multiple_fibs_on_same_subnet_head()
222 {
223         atf_set "descr" "Multiple FIBs can have subnet routes for the same subnet"
224         atf_set "require.user" "root"
225         atf_set "require.config" "fibs"
226 }
227
228 subnet_route_with_multiple_fibs_on_same_subnet_body()
229 {
230         atf_expect_fail "kern/187550 Multiple interfaces on different FIBs but the same subnet don't all have a subnet route"
231         # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
232         # and a non-default fib
233         ADDR0="192.0.2.2"
234         ADDR1="192.0.2.3"
235         SUBNET="192.0.2.0"
236         MASK="24"
237
238         # Check system configuration
239         if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
240                 atf_skip "This test requires net.add_addr_allfibs=0"
241         fi
242         get_fibs 2
243
244         # Configure TAP interfaces
245         setup_tap "$FIB0" ${ADDR0} ${MASK}
246         setup_tap "$FIB1" ${ADDR1} ${MASK}
247
248         # Check that a subnet route exists on both fibs
249         atf_check -o ignore setfib "$FIB0" route get $ADDR1
250         atf_check -o ignore setfib "$FIB1" route get $ADDR0
251 }
252
253 subnet_route_with_multiple_fibs_on_same_subnet_cleanup()
254 {
255         cleanup_tap
256 }
257
258 # Test that source address selection works correctly for UDP packets with
259 # SO_DONTROUTE set that are sent on non-default FIBs.
260 # This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host"
261 # Regression test for kern/187553
262 atf_test_case udp_dontroute cleanup
263 udp_dontroute_head()
264 {
265         atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works"
266         atf_set "require.user" "root"
267         atf_set "require.config" "fibs"
268 }
269
270 udp_dontroute_body()
271 {
272         atf_expect_fail "kern/187553 Source address selection for UDP packets with SO_DONTROUTE uses the default FIB"
273         # Configure the TAP interface to use an RFC5737 nonrouteable address
274         # and a non-default fib
275         ADDR="192.0.2.2"
276         SUBNET="192.0.2.0"
277         MASK="24"
278         # Use a different IP on the same subnet as the target
279         TARGET="192.0.2.100"
280
281         # Check system configuration
282         if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
283                 atf_skip "This test requires net.add_addr_allfibs=0"
284         fi
285         get_fibs 1
286
287         # Configure a TAP interface
288         setup_tap ${FIB0} ${ADDR} ${MASK}
289
290         # Send a UDP packet with SO_DONTROUTE.  In the failure case, it will
291         # return ENETUNREACH
292         SRCDIR=`atf_get_srcdir`
293         atf_check -o ignore setfib ${FIB0} ${SRCDIR}/udp_dontroute ${TARGET}
294 }
295
296 udp_dontroute_cleanup()
297 {
298         cleanup_tap
299 }
300
301
302 atf_init_test_cases()
303 {
304         atf_add_test_case arpresolve_checks_interface_fib
305         atf_add_test_case loopback_and_network_routes_on_nondefault_fib
306         atf_add_test_case default_route_with_multiple_fibs_on_same_subnet
307         atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet
308         atf_add_test_case udp_dontroute
309 }
310
311 # Looks up one or more fibs from the configuration data and validates them.
312 # Returns the results in the env varilables FIB0, FIB1, etc.
313
314 # parameter numfibs     The number of fibs to lookup
315 get_fibs()
316 {
317         NUMFIBS=$1
318         net_fibs=`sysctl -n net.fibs`
319         i=0
320         while [ $i -lt "$NUMFIBS" ]; do
321                 fib=`atf_config_get "fibs" | \
322                         awk -v i=$(( i + 1 )) '{print $i}'`
323                 echo "fib is ${fib}"
324                 eval FIB${i}=${fib}
325                 if [ "$fib" -ge "$net_fibs" ]; then
326                         atf_skip "The ${i}th configured fib is ${fib}, which is not less than net.fibs, which is ${net_fibs}"
327                 fi
328                 i=$(( $i + 1 ))
329         done
330 }
331
332 # Creates a new tap(4) interface, registers it for cleanup, and returns the
333 # name via the environment variable TAP
334 get_tap()
335 {
336         local TAPN=0
337         while ! ifconfig tap${TAPN} create > /dev/null 2>&1; do
338                 if [ "$TAPN" -ge 8 ]; then
339                         atf_skip "Could not create a tap(4) interface"
340                 else
341                         TAPN=$(($TAPN + 1))
342                 fi
343         done
344         local TAPD=tap${TAPN}
345         # Record the TAP device so we can clean it up later
346         echo ${TAPD} >> "tap_devices_to_cleanup"
347         TAP=${TAPD}
348 }
349
350 # Create a tap(4) interface, configure it, and register it for cleanup.
351 # parameters:
352 # fib
353 # IP address
354 # Netmask in number of bits (eg 24 or 8)
355 # Return: the tap interface name as the env variable TAP
356 setup_tap()
357 {
358         local FIB=$1
359         local ADDR=$2
360         local MASK=$3
361         get_tap
362         echo setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB
363         setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB
364 }
365
366 cleanup_tap()
367 {
368         for TAPD in `cat "tap_devices_to_cleanup"`; do
369                 ifconfig ${TAPD} destroy
370         done
371 }