Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test is for checking IPv4 and IPv6 FIB rules API
5
6# Kselftest framework requirement - SKIP code is 4.
7ksft_skip=4
8
9ret=0
10
11PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
12IP="ip -netns testns"
13
14RTABLE=100
15GW_IP4=192.51.100.2
16SRC_IP=192.51.100.3
17GW_IP6=2001:db8:1::2
18SRC_IP6=2001:db8:1::3
19
20DEV_ADDR=192.51.100.1
21DEV_ADDR6=2001:db8:1::1
22DEV=dummy0
23TESTS="fib_rule6 fib_rule4"
24
25log_test()
26{
27 local rc=$1
28 local expected=$2
29 local msg="$3"
30
31 if [ ${rc} -eq ${expected} ]; then
32 nsuccess=$((nsuccess+1))
33 printf "\n TEST: %-50s [ OK ]\n" "${msg}"
34 else
35 ret=1
36 nfail=$((nfail+1))
37 printf "\n TEST: %-50s [FAIL]\n" "${msg}"
38 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
39 echo
40 echo "hit enter to continue, 'q' to quit"
41 read a
42 [ "$a" = "q" ] && exit 1
43 fi
44 fi
45}
46
47log_section()
48{
49 echo
50 echo "######################################################################"
51 echo "TEST SECTION: $*"
52 echo "######################################################################"
53}
54
55setup()
56{
57 set -e
58 ip netns add testns
59 $IP link set dev lo up
60
61 $IP link add dummy0 type dummy
62 $IP link set dev dummy0 up
63 $IP address add $DEV_ADDR/24 dev dummy0
64 $IP -6 address add $DEV_ADDR6/64 dev dummy0
65
66 set +e
67}
68
69cleanup()
70{
71 $IP link del dev dummy0 &> /dev/null
72 ip netns del testns
73}
74
75fib_check_iproute_support()
76{
77 ip rule help 2>&1 | grep -q $1
78 if [ $? -ne 0 ]; then
79 echo "SKIP: iproute2 iprule too old, missing $1 match"
80 return 1
81 fi
82
83 ip route get help 2>&1 | grep -q $2
84 if [ $? -ne 0 ]; then
85 echo "SKIP: iproute2 get route too old, missing $2 match"
86 return 1
87 fi
88
89 return 0
90}
91
92fib_rule6_del()
93{
94 $IP -6 rule del $1
95 log_test $? 0 "rule6 del $1"
96}
97
98fib_rule6_del_by_pref()
99{
100 pref=$($IP -6 rule show $1 table $RTABLE | cut -d ":" -f 1)
101 $IP -6 rule del pref $pref
102}
103
104fib_rule6_test_match_n_redirect()
105{
106 local match="$1"
107 local getmatch="$2"
108 local description="$3"
109
110 $IP -6 rule add $match table $RTABLE
111 $IP -6 route get $GW_IP6 $getmatch | grep -q "table $RTABLE"
112 log_test $? 0 "rule6 check: $description"
113
114 fib_rule6_del_by_pref "$match"
115 log_test $? 0 "rule6 del by pref: $description"
116}
117
118fib_rule6_test_reject()
119{
120 local match="$1"
121 local rc
122
123 $IP -6 rule add $match table $RTABLE 2>/dev/null
124 rc=$?
125 log_test $rc 2 "rule6 check: $match"
126
127 if [ $rc -eq 0 ]; then
128 $IP -6 rule del $match table $RTABLE
129 fi
130}
131
132fib_rule6_test()
133{
134 local getmatch
135 local match
136 local cnt
137
138 # setup the fib rule redirect route
139 $IP -6 route add table $RTABLE default via $GW_IP6 dev $DEV onlink
140
141 match="oif $DEV"
142 fib_rule6_test_match_n_redirect "$match" "$match" "oif redirect to table"
143
144 match="from $SRC_IP6 iif $DEV"
145 fib_rule6_test_match_n_redirect "$match" "$match" "iif redirect to table"
146
147 # Reject dsfield (tos) options which have ECN bits set
148 for cnt in $(seq 1 3); do
149 match="dsfield $cnt"
150 fib_rule6_test_reject "$match"
151 done
152
153 # Don't take ECN bits into account when matching on dsfield
154 match="tos 0x10"
155 for cnt in "0x10" "0x11" "0x12" "0x13"; do
156 # Using option 'tos' instead of 'dsfield' as old iproute2
157 # versions don't support 'dsfield' in ip rule show.
158 getmatch="tos $cnt"
159 fib_rule6_test_match_n_redirect "$match" "$getmatch" \
160 "$getmatch redirect to table"
161 done
162
163 match="fwmark 0x64"
164 getmatch="mark 0x64"
165 fib_rule6_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table"
166
167 fib_check_iproute_support "uidrange" "uid"
168 if [ $? -eq 0 ]; then
169 match="uidrange 100-100"
170 getmatch="uid 100"
171 fib_rule6_test_match_n_redirect "$match" "$getmatch" "uid redirect to table"
172 fi
173
174 fib_check_iproute_support "sport" "sport"
175 if [ $? -eq 0 ]; then
176 match="sport 666 dport 777"
177 fib_rule6_test_match_n_redirect "$match" "$match" "sport and dport redirect to table"
178 fi
179
180 fib_check_iproute_support "ipproto" "ipproto"
181 if [ $? -eq 0 ]; then
182 match="ipproto tcp"
183 fib_rule6_test_match_n_redirect "$match" "$match" "ipproto match"
184 fi
185
186 fib_check_iproute_support "ipproto" "ipproto"
187 if [ $? -eq 0 ]; then
188 match="ipproto ipv6-icmp"
189 fib_rule6_test_match_n_redirect "$match" "$match" "ipproto ipv6-icmp match"
190 fi
191}
192
193fib_rule4_del()
194{
195 $IP rule del $1
196 log_test $? 0 "del $1"
197}
198
199fib_rule4_del_by_pref()
200{
201 pref=$($IP rule show $1 table $RTABLE | cut -d ":" -f 1)
202 $IP rule del pref $pref
203}
204
205fib_rule4_test_match_n_redirect()
206{
207 local match="$1"
208 local getmatch="$2"
209 local description="$3"
210
211 $IP rule add $match table $RTABLE
212 $IP route get $GW_IP4 $getmatch | grep -q "table $RTABLE"
213 log_test $? 0 "rule4 check: $description"
214
215 fib_rule4_del_by_pref "$match"
216 log_test $? 0 "rule4 del by pref: $description"
217}
218
219fib_rule4_test_reject()
220{
221 local match="$1"
222 local rc
223
224 $IP rule add $match table $RTABLE 2>/dev/null
225 rc=$?
226 log_test $rc 2 "rule4 check: $match"
227
228 if [ $rc -eq 0 ]; then
229 $IP rule del $match table $RTABLE
230 fi
231}
232
233fib_rule4_test()
234{
235 local getmatch
236 local match
237 local cnt
238
239 # setup the fib rule redirect route
240 $IP route add table $RTABLE default via $GW_IP4 dev $DEV onlink
241
242 match="oif $DEV"
243 fib_rule4_test_match_n_redirect "$match" "$match" "oif redirect to table"
244
245 # need enable forwarding and disable rp_filter temporarily as all the
246 # addresses are in the same subnet and egress device == ingress device.
247 ip netns exec testns sysctl -qw net.ipv4.ip_forward=1
248 ip netns exec testns sysctl -qw net.ipv4.conf.$DEV.rp_filter=0
249 match="from $SRC_IP iif $DEV"
250 fib_rule4_test_match_n_redirect "$match" "$match" "iif redirect to table"
251 ip netns exec testns sysctl -qw net.ipv4.ip_forward=0
252
253 # Reject dsfield (tos) options which have ECN bits set
254 for cnt in $(seq 1 3); do
255 match="dsfield $cnt"
256 fib_rule4_test_reject "$match"
257 done
258
259 # Don't take ECN bits into account when matching on dsfield
260 match="tos 0x10"
261 for cnt in "0x10" "0x11" "0x12" "0x13"; do
262 # Using option 'tos' instead of 'dsfield' as old iproute2
263 # versions don't support 'dsfield' in ip rule show.
264 getmatch="tos $cnt"
265 fib_rule4_test_match_n_redirect "$match" "$getmatch" \
266 "$getmatch redirect to table"
267 done
268
269 match="fwmark 0x64"
270 getmatch="mark 0x64"
271 fib_rule4_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table"
272
273 fib_check_iproute_support "uidrange" "uid"
274 if [ $? -eq 0 ]; then
275 match="uidrange 100-100"
276 getmatch="uid 100"
277 fib_rule4_test_match_n_redirect "$match" "$getmatch" "uid redirect to table"
278 fi
279
280 fib_check_iproute_support "sport" "sport"
281 if [ $? -eq 0 ]; then
282 match="sport 666 dport 777"
283 fib_rule4_test_match_n_redirect "$match" "$match" "sport and dport redirect to table"
284 fi
285
286 fib_check_iproute_support "ipproto" "ipproto"
287 if [ $? -eq 0 ]; then
288 match="ipproto tcp"
289 fib_rule4_test_match_n_redirect "$match" "$match" "ipproto tcp match"
290 fi
291
292 fib_check_iproute_support "ipproto" "ipproto"
293 if [ $? -eq 0 ]; then
294 match="ipproto icmp"
295 fib_rule4_test_match_n_redirect "$match" "$match" "ipproto icmp match"
296 fi
297}
298
299run_fibrule_tests()
300{
301 log_section "IPv4 fib rule"
302 fib_rule4_test
303 log_section "IPv6 fib rule"
304 fib_rule6_test
305}
306################################################################################
307# usage
308
309usage()
310{
311 cat <<EOF
312usage: ${0##*/} OPTS
313
314 -t <test> Test(s) to run (default: all)
315 (options: $TESTS)
316EOF
317}
318
319################################################################################
320# main
321
322while getopts ":t:h" opt; do
323 case $opt in
324 t) TESTS=$OPTARG;;
325 h) usage; exit 0;;
326 *) usage; exit 1;;
327 esac
328done
329
330if [ "$(id -u)" -ne 0 ];then
331 echo "SKIP: Need root privileges"
332 exit $ksft_skip
333fi
334
335if [ ! -x "$(command -v ip)" ]; then
336 echo "SKIP: Could not run test without ip tool"
337 exit $ksft_skip
338fi
339
340# start clean
341cleanup &> /dev/null
342setup
343for t in $TESTS
344do
345 case $t in
346 fib_rule6_test|fib_rule6) fib_rule6_test;;
347 fib_rule4_test|fib_rule4) fib_rule4_test;;
348
349 help) echo "Test names: $TESTS"; exit 0;;
350
351 esac
352done
353cleanup
354
355if [ "$TESTS" != "none" ]; then
356 printf "\nTests passed: %3d\n" ${nsuccess}
357 printf "Tests failed: %3d\n" ${nfail}
358fi
359
360exit $ret