1757Sdg#!/bin/sh
2757Sdg# SPDX-License-Identifier: GPL-2.0
3757Sdg#
4757Sdg# End-to-end ipvs test suite
5757Sdg# Topology:
6757Sdg#--------------------------------------------------------------+
7757Sdg#                      |                                       |
8757Sdg#         ns0          |         ns1                           |
9757Sdg#      -----------     |     -----------    -----------        |
10757Sdg#      | veth01  | --------- | veth10  |    | veth12  |        |
11757Sdg#      -----------    peer   -----------    -----------        |
12757Sdg#           |          |                        |              |
13757Sdg#      -----------     |                        |              |
14757Sdg#      |  br0    |     |-----------------  peer |--------------|
15757Sdg#      -----------     |                        |              |
16757Sdg#           |          |                        |              |
17757Sdg#      ----------     peer   ----------      -----------       |
18757Sdg#      |  veth02 | --------- |  veth20 |     | veth21  |       |
19757Sdg#      ----------      |     ----------      -----------       |
20757Sdg#                      |         ns2                           |
21757Sdg#                      |                                       |
22757Sdg#--------------------------------------------------------------+
23757Sdg#
24757Sdg# We assume that all network driver are loaded
25757Sdg#
26757Sdg
27757Sdg# Kselftest framework requirement - SKIP code is 4.
28757Sdgksft_skip=4
29757Sdgret=0
30757SdgGREEN='\033[0;92m'
31757SdgRED='\033[0;31m'
32757SdgNC='\033[0m' # No Color
3310063Sbde
34757Sdgreadonly port=8080
35757Sdg
36757Sdgreadonly vip_v4=207.175.44.110
37757Sdgreadonly cip_v4=10.0.0.2
38757Sdgreadonly gip_v4=10.0.0.1
39757Sdgreadonly dip_v4=172.16.0.1
402056Swollmanreadonly rip_v4=172.16.0.2
41757Sdgreadonly sip_v4=10.0.0.3
422056Swollman
43757Sdgreadonly infile="$(mktemp)"
442056Swollmanreadonly outfile="$(mktemp)"
451321Sdgreadonly datalen=32
462056Swollman
472056Swollmansysipvsnet="/proc/sys/net/ipv4/vs/"
48757Sdgif [ ! -d $sysipvsnet ]; then
492056Swollman	modprobe -q ip_vs
50757Sdg	if [ $? -ne 0 ]; then
51757Sdg		echo "skip: could not run test without ipvs module"
52757Sdg		exit $ksft_skip
53757Sdg	fi
54757Sdgfi
55757Sdg
56757Sdgip -Version > /dev/null 2>&1
57757Sdgif [ $? -ne 0 ]; then
58757Sdg	echo "SKIP: Could not run test without ip tool"
59757Sdg	exit $ksft_skip
60757Sdgfi
61757Sdg
621321Sdgipvsadm -v > /dev/null 2>&1
631321Sdgif [ $? -ne 0 ]; then
641321Sdg	echo "SKIP: Could not run test without ipvsadm"
651321Sdg	exit $ksft_skip
661321Sdgfi
67757Sdg
68757Sdgsetup() {
69757Sdg	ip netns add ns0
701321Sdg	ip netns add ns1
711321Sdg	ip netns add ns2
721321Sdg
731321Sdg	ip link add veth01 netns ns0 type veth peer name veth10 netns ns1
741321Sdg	ip link add veth02 netns ns0 type veth peer name veth20 netns ns2
751321Sdg	ip link add veth12 netns ns1 type veth peer name veth21 netns ns2
761321Sdg
771321Sdg	ip netns exec ns0 ip link set veth01 up
781321Sdg	ip netns exec ns0 ip link set veth02 up
791321Sdg	ip netns exec ns0 ip link add br0 type bridge
801321Sdg	ip netns exec ns0 ip link set veth01 master br0
811321Sdg	ip netns exec ns0 ip link set veth02 master br0
821321Sdg	ip netns exec ns0 ip link set br0 up
831321Sdg	ip netns exec ns0 ip addr add ${cip_v4}/24 dev br0
841321Sdg
851321Sdg	ip netns exec ns1 ip link set lo up
86757Sdg	ip netns exec ns1 ip link set veth10 up
871321Sdg	ip netns exec ns1 ip addr add ${gip_v4}/24 dev veth10
881321Sdg	ip netns exec ns1 ip link set veth12 up
89757Sdg	ip netns exec ns1 ip addr add ${dip_v4}/24 dev veth12
901321Sdg
91757Sdg	ip netns exec ns2 ip link set lo up
92757Sdg	ip netns exec ns2 ip link set veth21 up
931321Sdg	ip netns exec ns2 ip addr add ${rip_v4}/24 dev veth21
941321Sdg	ip netns exec ns2 ip link set veth20 up
951321Sdg	ip netns exec ns2 ip addr add ${sip_v4}/24 dev veth20
96757Sdg
97757Sdg	sleep 1
98757Sdg
99757Sdg	dd if=/dev/urandom of="${infile}" bs="${datalen}" count=1 status=none
100757Sdg}
101757Sdg
102757Sdgcleanup() {
103757Sdg	for i in 0 1 2
104757Sdg	do
105757Sdg		ip netns del ns$i > /dev/null 2>&1
106757Sdg	done
107757Sdg
108757Sdg	if [ -f "${outfile}" ]; then
109757Sdg		rm "${outfile}"
110757Sdg	fi
111757Sdg	if [ -f "${infile}" ]; then
112757Sdg		rm "${infile}"
113757Sdg	fi
114757Sdg}
115757Sdg
116757Sdgserver_listen() {
117757Sdg	ip netns exec ns2 nc -l -p 8080 > "${outfile}" &
118757Sdg	server_pid=$!
119757Sdg	sleep 0.2
120757Sdg}
121757Sdg
122757Sdgclient_connect() {
123757Sdg	ip netns exec ns0 timeout 2 nc -w 1 ${vip_v4} ${port} < "${infile}"
124757Sdg}
125757Sdg
126757Sdgverify_data() {
127757Sdg	wait "${server_pid}"
128757Sdg	cmp "$infile" "$outfile" 2>/dev/null
129757Sdg}
130757Sdg
131757Sdgtest_service() {
132757Sdg	server_listen
1334929Sbde	client_connect
1344929Sbde	verify_data
1354929Sbde}
1364929Sbde
1374929Sbde
138757Sdgtest_dr() {
1391321Sdg	ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0
1401321Sdg
141757Sdg	ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1
142757Sdg	ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr
143757Sdg	ip netns exec ns1 ipvsadm -a -t ${vip_v4}:${port} -r ${rip_v4}:${port}
144757Sdg	ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1
145757Sdg
146757Sdg	# avoid incorrect arp response
1471321Sdg	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_ignore=1
1481321Sdg	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_announce=2
1491321Sdg	# avoid reverse route lookup
150757Sdg	ip netns exec ns2 sysctl -qw  net.ipv4.conf.all.rp_filter=0
151757Sdg	ip netns exec ns2 sysctl -qw  net.ipv4.conf.veth21.rp_filter=0
1521321Sdg	ip netns exec ns2 ip addr add ${vip_v4}/32 dev lo:1
1531321Sdg
154757Sdg	test_service
1554929Sbde}
1561321Sdg
1571321Sdgtest_nat() {
158757Sdg	ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0
159757Sdg
160757Sdg	ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1
1615603Sbde	ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr
1625603Sbde	ip netns exec ns1 ipvsadm -a -m -t ${vip_v4}:${port} -r ${rip_v4}:${port}
163757Sdg	ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1
164757Sdg
1651321Sdg	ip netns exec ns2 ip link del veth20
166757Sdg	ip netns exec ns2 ip route add default via ${dip_v4} dev veth21
167757Sdg
168757Sdg	test_service
1695603Sbde}
170757Sdg
171757Sdgtest_tun() {
172757Sdg	ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0
1731321Sdg
174757Sdg	ip netns exec ns1 modprobe ipip
1751321Sdg	ip netns exec ns1 ip link set tunl0 up
176757Sdg	ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=0
1771321Sdg	ip netns exec ns1 sysctl -qw net.ipv4.conf.all.send_redirects=0
17810063Sbde	ip netns exec ns1 sysctl -qw net.ipv4.conf.default.send_redirects=0
17910063Sbde	ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr
18010063Sbde	ip netns exec ns1 ipvsadm -a -i -t ${vip_v4}:${port} -r ${rip_v4}:${port}
18110063Sbde	ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1
18210063Sbde
18310063Sbde	ip netns exec ns2 modprobe ipip
18410063Sbde	ip netns exec ns2 ip link set tunl0 up
18510063Sbde	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_ignore=1
18610063Sbde	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_announce=2
18710063Sbde	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=0
18810063Sbde	ip netns exec ns2 sysctl -qw net.ipv4.conf.tunl0.rp_filter=0
189757Sdg	ip netns exec ns2 sysctl -qw net.ipv4.conf.veth21.rp_filter=0
19010063Sbde	ip netns exec ns2 ip addr add ${vip_v4}/32 dev lo:1
191757Sdg
1921321Sdg	test_service
1931321Sdg}
1941321Sdg
1951321Sdgrun_tests() {
1961321Sdg	local errors=
1971321Sdg
1981321Sdg	echo "Testing DR mode..."
1991321Sdg	cleanup
2001321Sdg	setup
2011321Sdg	test_dr
2021321Sdg	errors=$(( $errors + $? ))
203757Sdg
204757Sdg	echo "Testing NAT mode..."
2051321Sdg	cleanup
2061321Sdg	setup
2074929Sbde	test_nat
2081321Sdg	errors=$(( $errors + $? ))
2091321Sdg
210757Sdg	echo "Testing Tunnel mode..."
211757Sdg	cleanup
212757Sdg	setup
213757Sdg	test_tun
214757Sdg	errors=$(( $errors + $? ))
215757Sdg
216757Sdg	return $errors
2171321Sdg}
218757Sdg
219924Sdgtrap cleanup EXIT
220757Sdg
221757Sdgrun_tests
222757Sdg
223757Sdgif [ $? -ne 0 ]; then
2241321Sdg	echo -e "$(basename $0): ${RED}FAIL${NC}"
225757Sdg	exit 1
226757Sdgfi
227757Sdgecho -e "$(basename $0): ${GREEN}PASS${NC}"
2281321Sdgexit 0
229757Sdg