xref: /linux/tools/testing/selftests/net/fib_rule_tests.sh (revision 000aa1250d572171807b47fb9cd3fadfbcc36ad0)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test is for checking IPv4 and IPv6 FIB rules API
5
6ret=0
7
8PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
9IP="ip -netns testns"
10
11RTABLE=100
12GW_IP4=192.51.100.2
13SRC_IP=192.51.100.3
14GW_IP6=2001:db8:1::2
15SRC_IP6=2001:db8:1::3
16
17DEV_ADDR=192.51.100.1
18DEV=dummy0
19
20log_test()
21{
22	local rc=$1
23	local expected=$2
24	local msg="$3"
25
26	if [ ${rc} -eq ${expected} ]; then
27		nsuccess=$((nsuccess+1))
28		printf "\n    TEST: %-50s  [ OK ]\n" "${msg}"
29	else
30		ret=1
31		nfail=$((nfail+1))
32		printf "\n    TEST: %-50s  [FAIL]\n" "${msg}"
33		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
34			echo
35			echo "hit enter to continue, 'q' to quit"
36			read a
37			[ "$a" = "q" ] && exit 1
38		fi
39	fi
40}
41
42log_section()
43{
44	echo
45	echo "######################################################################"
46	echo "TEST SECTION: $*"
47	echo "######################################################################"
48}
49
50setup()
51{
52	set -e
53	ip netns add testns
54	$IP link set dev lo up
55
56	$IP link add dummy0 type dummy
57	$IP link set dev dummy0 up
58	$IP address add 192.51.100.1/24 dev dummy0
59	$IP -6 address add 2001:db8:1::1/64 dev dummy0
60
61	set +e
62}
63
64cleanup()
65{
66	$IP link del dev dummy0 &> /dev/null
67	ip netns del testns
68}
69
70fib_check_iproute_support()
71{
72	ip rule help 2>&1 | grep -q $1
73	if [ $? -ne 0 ]; then
74		echo "SKIP: iproute2 iprule too old, missing $1 match"
75		return 1
76	fi
77
78	ip route get help 2>&1 | grep -q $2
79	if [ $? -ne 0 ]; then
80		echo "SKIP: iproute2 get route too old, missing $2 match"
81		return 1
82	fi
83
84	return 0
85}
86
87fib_rule6_del()
88{
89	$IP -6 rule del $1
90	log_test $? 0 "rule6 del $1"
91}
92
93fib_rule6_del_by_pref()
94{
95	pref=$($IP -6 rule show | grep "$1 lookup $TABLE" | cut -d ":" -f 1)
96	$IP -6 rule del pref $pref
97}
98
99fib_rule6_test_match_n_redirect()
100{
101	local match="$1"
102	local getmatch="$2"
103
104	$IP -6 rule add $match table $RTABLE
105	$IP -6 route get $GW_IP6 $getmatch | grep -q "table $RTABLE"
106	log_test $? 0 "rule6 check: $1"
107
108	fib_rule6_del_by_pref "$match"
109	log_test $? 0 "rule6 del by pref: $match"
110}
111
112fib_rule6_test()
113{
114	# setup the fib rule redirect route
115	$IP -6 route add table $RTABLE default via $GW_IP6 dev $DEV onlink
116
117	match="oif $DEV"
118	fib_rule6_test_match_n_redirect "$match" "$match" "oif redirect to table"
119
120	match="from $SRC_IP6 iif $DEV"
121	fib_rule6_test_match_n_redirect "$match" "$match" "iif redirect to table"
122
123	match="tos 0x10"
124	fib_rule6_test_match_n_redirect "$match" "$match" "tos redirect to table"
125
126	match="fwmark 0x64"
127	getmatch="mark 0x64"
128	fib_rule6_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table"
129
130	fib_check_iproute_support "uidrange" "uid"
131	if [ $? -eq 0 ]; then
132		match="uidrange 100-100"
133		getmatch="uid 100"
134		fib_rule6_test_match_n_redirect "$match" "$getmatch" "uid redirect to table"
135	fi
136
137	fib_check_iproute_support "sport" "sport"
138	if [ $? -eq 0 ]; then
139		match="sport 666 dport 777"
140		fib_rule6_test_match_n_redirect "$match" "$match" "sport and dport redirect to table"
141	fi
142
143	fib_check_iproute_support "ipproto" "ipproto"
144	if [ $? -eq 0 ]; then
145		match="ipproto tcp"
146		fib_rule6_test_match_n_redirect "$match" "$match" "ipproto match"
147	fi
148
149	fib_check_iproute_support "ipproto" "ipproto"
150	if [ $? -eq 0 ]; then
151		match="ipproto ipv6-icmp"
152		fib_rule6_test_match_n_redirect "$match" "$match" "ipproto ipv6-icmp match"
153	fi
154}
155
156fib_rule4_del()
157{
158	$IP rule del $1
159	log_test $? 0 "del $1"
160}
161
162fib_rule4_del_by_pref()
163{
164	pref=$($IP rule show | grep "$1 lookup $TABLE" | cut -d ":" -f 1)
165	$IP rule del pref $pref
166}
167
168fib_rule4_test_match_n_redirect()
169{
170	local match="$1"
171	local getmatch="$2"
172
173	$IP rule add $match table $RTABLE
174	$IP route get $GW_IP4 $getmatch | grep -q "table $RTABLE"
175	log_test $? 0 "rule4 check: $1"
176
177	fib_rule4_del_by_pref "$match"
178	log_test $? 0 "rule4 del by pref: $match"
179}
180
181fib_rule4_test()
182{
183	# setup the fib rule redirect route
184	$IP route add table $RTABLE default via $GW_IP4 dev $DEV onlink
185
186	match="oif $DEV"
187	fib_rule4_test_match_n_redirect "$match" "$match" "oif redirect to table"
188
189	# need enable forwarding and disable rp_filter temporarily as all the
190	# addresses are in the same subnet and egress device == ingress device.
191	ip netns exec testns sysctl -w net.ipv4.ip_forward=1
192	ip netns exec testns sysctl -w net.ipv4.conf.$DEV.rp_filter=0
193	match="from $SRC_IP iif $DEV"
194	fib_rule4_test_match_n_redirect "$match" "$match" "iif redirect to table"
195	ip netns exec testns sysctl -w net.ipv4.ip_forward=0
196
197	match="tos 0x10"
198	fib_rule4_test_match_n_redirect "$match" "$match" "tos redirect to table"
199
200	match="fwmark 0x64"
201	getmatch="mark 0x64"
202	fib_rule4_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table"
203
204	fib_check_iproute_support "uidrange" "uid"
205	if [ $? -eq 0 ]; then
206		match="uidrange 100-100"
207		getmatch="uid 100"
208		fib_rule4_test_match_n_redirect "$match" "$getmatch" "uid redirect to table"
209	fi
210
211	fib_check_iproute_support "sport" "sport"
212	if [ $? -eq 0 ]; then
213		match="sport 666 dport 777"
214		fib_rule4_test_match_n_redirect "$match" "$match" "sport and dport redirect to table"
215	fi
216
217	fib_check_iproute_support "ipproto" "ipproto"
218	if [ $? -eq 0 ]; then
219		match="ipproto tcp"
220		fib_rule4_test_match_n_redirect "$match" "$match" "ipproto tcp match"
221	fi
222
223	fib_check_iproute_support "ipproto" "ipproto"
224	if [ $? -eq 0 ]; then
225		match="ipproto icmp"
226		fib_rule4_test_match_n_redirect "$match" "$match" "ipproto icmp match"
227	fi
228}
229
230run_fibrule_tests()
231{
232	log_section "IPv4 fib rule"
233	fib_rule4_test
234	log_section "IPv6 fib rule"
235	fib_rule6_test
236}
237
238if [ "$(id -u)" -ne 0 ];then
239	echo "SKIP: Need root privileges"
240	exit 0
241fi
242
243if [ ! -x "$(command -v ip)" ]; then
244	echo "SKIP: Could not run test without ip tool"
245	exit 0
246fi
247
248# start clean
249cleanup &> /dev/null
250setup
251run_fibrule_tests
252cleanup
253
254if [ "$TESTS" != "none" ]; then
255	printf "\nTests passed: %3d\n" ${nsuccess}
256	printf "Tests failed: %3d\n"   ${nfail}
257fi
258
259exit $ret
260