1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test is for checking GRE GSO.
5source lib.sh
6ret=0
7
8# all tests in this script. Can be overridden with -t option
9TESTS="gre_gso"
10
11VERBOSE=0
12PAUSE_ON_FAIL=no
13PAUSE=no
14TMPFILE=`mktemp`
15PID=
16
17log_test()
18{
19	local rc=$1
20	local expected=$2
21	local msg="$3"
22
23	if [ ${rc} -eq ${expected} ]; then
24		printf "    TEST: %-60s  [ OK ]\n" "${msg}"
25		nsuccess=$((nsuccess+1))
26	else
27		ret=1
28		nfail=$((nfail+1))
29		printf "    TEST: %-60s  [FAIL]\n" "${msg}"
30		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
31		echo
32			echo "hit enter to continue, 'q' to quit"
33			read a
34			[ "$a" = "q" ] && exit 1
35		fi
36	fi
37
38	if [ "${PAUSE}" = "yes" ]; then
39		echo
40		echo "hit enter to continue, 'q' to quit"
41		read a
42		[ "$a" = "q" ] && exit 1
43	fi
44}
45
46setup()
47{
48	set -e
49	setup_ns ns1
50	IP="ip -netns $ns1"
51	NS_EXEC="ip netns exec $ns1"
52
53	ip link add veth0 type veth peer name veth1
54	ip link set veth0 up
55	ip link set veth1 netns $ns1
56	$IP link set veth1 name veth0
57	$IP link set veth0 up
58
59	dd if=/dev/urandom of=$TMPFILE bs=1024 count=2048 &>/dev/null
60	set +e
61}
62
63cleanup()
64{
65	rm -rf $TMPFILE
66	[ -n "$PID" ] && kill $PID
67	ip link del dev gre1 &> /dev/null
68	ip link del dev veth0 &> /dev/null
69	cleanup_ns $ns1
70}
71
72get_linklocal()
73{
74	local dev=$1
75	local ns=$2
76	local addr
77
78	[ -n "$ns" ] && ns="-netns $ns"
79
80	addr=$(ip -6 -br $ns addr show dev ${dev} | \
81	awk '{
82		for (i = 3; i <= NF; ++i) {
83			if ($i ~ /^fe80/)
84				print $i
85		}
86	}'
87	)
88	addr=${addr/\/*}
89
90	[ -z "$addr" ] && return 1
91
92	echo $addr
93
94	return 0
95}
96
97gre_create_tun()
98{
99	local a1=$1
100	local a2=$2
101	local mode
102
103	[[ $a1 =~ ^[0-9.]*$ ]] && mode=gre || mode=ip6gre
104
105	ip tunnel add gre1 mode $mode local $a1 remote $a2 dev veth0
106	ip link set gre1 up
107	$IP tunnel add gre1 mode $mode local $a2 remote $a1 dev veth0
108	$IP link set gre1 up
109}
110
111gre_gst_test_checks()
112{
113	local name=$1
114	local addr=$2
115	local proto=$3
116
117	[ "$proto" == 6 ] && addr="[$addr]"
118
119	$NS_EXEC socat - tcp${proto}-listen:$port,reuseaddr,fork >/dev/null &
120	PID=$!
121	while ! $NS_EXEC ss -ltn | grep -q $port; do ((i++)); sleep 0.01; done
122
123	cat $TMPFILE | timeout 1 socat -u STDIN TCP:$addr:$port
124	log_test $? 0 "$name - copy file w/ TSO"
125
126	ethtool -K veth0 tso off
127
128	cat $TMPFILE | timeout 1 socat -u STDIN TCP:$addr:$port
129	log_test $? 0 "$name - copy file w/ GSO"
130
131	ethtool -K veth0 tso on
132
133	kill $PID
134	PID=
135}
136
137gre6_gso_test()
138{
139	local port=7777
140
141	setup
142
143	a1=$(get_linklocal veth0)
144	a2=$(get_linklocal veth0 $ns1)
145
146	gre_create_tun $a1 $a2
147
148	ip  addr add 172.16.2.1/24 dev gre1
149	$IP addr add 172.16.2.2/24 dev gre1
150
151	ip  -6 addr add 2001:db8:1::1/64 dev gre1 nodad
152	$IP -6 addr add 2001:db8:1::2/64 dev gre1 nodad
153
154	sleep 2
155
156	gre_gst_test_checks GREv6/v4 172.16.2.2 4
157	gre_gst_test_checks GREv6/v6 2001:db8:1::2 6
158
159	cleanup
160}
161
162gre_gso_test()
163{
164	gre6_gso_test
165}
166
167################################################################################
168# usage
169
170usage()
171{
172	cat <<EOF
173usage: ${0##*/} OPTS
174
175        -t <test>   Test(s) to run (default: all)
176                    (options: $TESTS)
177        -p          Pause on fail
178        -P          Pause after each test before cleanup
179        -v          verbose mode (show commands and output)
180EOF
181}
182
183################################################################################
184# main
185
186while getopts :t:pPhv o
187do
188	case $o in
189		t) TESTS=$OPTARG;;
190		p) PAUSE_ON_FAIL=yes;;
191		P) PAUSE=yes;;
192		v) VERBOSE=$(($VERBOSE + 1));;
193		h) usage; exit 0;;
194		*) usage; exit 1;;
195	esac
196done
197
198PEER_CMD="ip netns exec ${PEER_NS}"
199
200# make sure we don't pause twice
201[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
202
203if [ "$(id -u)" -ne 0 ];then
204	echo "SKIP: Need root privileges"
205	exit $ksft_skip;
206fi
207
208if [ ! -x "$(command -v ip)" ]; then
209	echo "SKIP: Could not run test without ip tool"
210	exit $ksft_skip
211fi
212
213if [ ! -x "$(command -v socat)" ]; then
214	echo "SKIP: Could not run test without socat tool"
215	exit $ksft_skip
216fi
217
218# start clean
219cleanup &> /dev/null
220
221for t in $TESTS
222do
223	case $t in
224	gre_gso)		gre_gso_test;;
225
226	help) echo "Test names: $TESTS"; exit 0;;
227	esac
228done
229
230if [ "$TESTS" != "none" ]; then
231	printf "\nTests passed: %3d\n" ${nsuccess}
232	printf "Tests failed: %3d\n"   ${nfail}
233fi
234
235exit $ret
236