1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3#
4# End-to-end ipvs test suite
5# Topology:
6#--------------------------------------------------------------+
7#                      |                                       |
8#         ns0          |         ns1                           |
9#      -----------     |     -----------    -----------        |
10#      | veth01  | --------- | veth10  |    | veth12  |        |
11#      -----------    peer   -----------    -----------        |
12#           |          |                        |              |
13#      -----------     |                        |              |
14#      |  br0    |     |-----------------  peer |--------------|
15#      -----------     |                        |              |
16#           |          |                        |              |
17#      ----------     peer   ----------      -----------       |
18#      |  veth02 | --------- |  veth20 |     | veth21  |       |
19#      ----------      |     ----------      -----------       |
20#                      |         ns2                           |
21#                      |                                       |
22#--------------------------------------------------------------+
23#
24# We assume that all network driver are loaded
25#
26
27# Kselftest framework requirement - SKIP code is 4.
28ksft_skip=4
29ret=0
30GREEN='\033[0;92m'
31RED='\033[0;31m'
32NC='\033[0m' # No Color
33
34readonly port=8080
35
36readonly vip_v4=207.175.44.110
37readonly cip_v4=10.0.0.2
38readonly gip_v4=10.0.0.1
39readonly dip_v4=172.16.0.1
40readonly rip_v4=172.16.0.2
41readonly sip_v4=10.0.0.3
42
43readonly infile="$(mktemp)"
44readonly outfile="$(mktemp)"
45readonly datalen=32
46
47sysipvsnet="/proc/sys/net/ipv4/vs/"
48if [ ! -d $sysipvsnet ]; then
49	modprobe -q ip_vs
50	if [ $? -ne 0 ]; then
51		echo "skip: could not run test without ipvs module"
52		exit $ksft_skip
53	fi
54fi
55
56ip -Version > /dev/null 2>&1
57if [ $? -ne 0 ]; then
58	echo "SKIP: Could not run test without ip tool"
59	exit $ksft_skip
60fi
61
62ipvsadm -v > /dev/null 2>&1
63if [ $? -ne 0 ]; then
64	echo "SKIP: Could not run test without ipvsadm"
65	exit $ksft_skip
66fi
67
68setup() {
69	ip netns add ns0
70	ip netns add ns1
71	ip netns add ns2
72
73	ip link add veth01 netns ns0 type veth peer name veth10 netns ns1
74	ip link add veth02 netns ns0 type veth peer name veth20 netns ns2
75	ip link add veth12 netns ns1 type veth peer name veth21 netns ns2
76
77	ip netns exec ns0 ip link set veth01 up
78	ip netns exec ns0 ip link set veth02 up
79	ip netns exec ns0 ip link add br0 type bridge
80	ip netns exec ns0 ip link set veth01 master br0
81	ip netns exec ns0 ip link set veth02 master br0
82	ip netns exec ns0 ip link set br0 up
83	ip netns exec ns0 ip addr add ${cip_v4}/24 dev br0
84
85	ip netns exec ns1 ip link set lo up
86	ip netns exec ns1 ip link set veth10 up
87	ip netns exec ns1 ip addr add ${gip_v4}/24 dev veth10
88	ip netns exec ns1 ip link set veth12 up
89	ip netns exec ns1 ip addr add ${dip_v4}/24 dev veth12
90
91	ip netns exec ns2 ip link set lo up
92	ip netns exec ns2 ip link set veth21 up
93	ip netns exec ns2 ip addr add ${rip_v4}/24 dev veth21
94	ip netns exec ns2 ip link set veth20 up
95	ip netns exec ns2 ip addr add ${sip_v4}/24 dev veth20
96
97	sleep 1
98
99	dd if=/dev/urandom of="${infile}" bs="${datalen}" count=1 status=none
100}
101
102cleanup() {
103	for i in 0 1 2
104	do
105		ip netns del ns$i > /dev/null 2>&1
106	done
107
108	if [ -f "${outfile}" ]; then
109		rm "${outfile}"
110	fi
111	if [ -f "${infile}" ]; then
112		rm "${infile}"
113	fi
114}
115
116server_listen() {
117	ip netns exec ns2 nc -l -p 8080 > "${outfile}" &
118	server_pid=$!
119	sleep 0.2
120}
121
122client_connect() {
123	ip netns exec ns0 timeout 2 nc -w 1 ${vip_v4} ${port} < "${infile}"
124}
125
126verify_data() {
127	wait "${server_pid}"
128	cmp "$infile" "$outfile" 2>/dev/null
129}
130
131test_service() {
132	server_listen
133	client_connect
134	verify_data
135}
136
137
138test_dr() {
139	ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0
140
141	ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1
142	ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr
143	ip netns exec ns1 ipvsadm -a -t ${vip_v4}:${port} -r ${rip_v4}:${port}
144	ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1
145
146	# avoid incorrect arp response
147	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_ignore=1
148	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_announce=2
149	# avoid reverse route lookup
150	ip netns exec ns2 sysctl -qw  net.ipv4.conf.all.rp_filter=0
151	ip netns exec ns2 sysctl -qw  net.ipv4.conf.veth21.rp_filter=0
152	ip netns exec ns2 ip addr add ${vip_v4}/32 dev lo:1
153
154	test_service
155}
156
157test_nat() {
158	ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0
159
160	ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1
161	ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr
162	ip netns exec ns1 ipvsadm -a -m -t ${vip_v4}:${port} -r ${rip_v4}:${port}
163	ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1
164
165	ip netns exec ns2 ip link del veth20
166	ip netns exec ns2 ip route add default via ${dip_v4} dev veth21
167
168	test_service
169}
170
171test_tun() {
172	ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0
173
174	ip netns exec ns1 modprobe ipip
175	ip netns exec ns1 ip link set tunl0 up
176	ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=0
177	ip netns exec ns1 sysctl -qw net.ipv4.conf.all.send_redirects=0
178	ip netns exec ns1 sysctl -qw net.ipv4.conf.default.send_redirects=0
179	ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr
180	ip netns exec ns1 ipvsadm -a -i -t ${vip_v4}:${port} -r ${rip_v4}:${port}
181	ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1
182
183	ip netns exec ns2 modprobe ipip
184	ip netns exec ns2 ip link set tunl0 up
185	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_ignore=1
186	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_announce=2
187	ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=0
188	ip netns exec ns2 sysctl -qw net.ipv4.conf.tunl0.rp_filter=0
189	ip netns exec ns2 sysctl -qw net.ipv4.conf.veth21.rp_filter=0
190	ip netns exec ns2 ip addr add ${vip_v4}/32 dev lo:1
191
192	test_service
193}
194
195run_tests() {
196	local errors=
197
198	echo "Testing DR mode..."
199	cleanup
200	setup
201	test_dr
202	errors=$(( $errors + $? ))
203
204	echo "Testing NAT mode..."
205	cleanup
206	setup
207	test_nat
208	errors=$(( $errors + $? ))
209
210	echo "Testing Tunnel mode..."
211	cleanup
212	setup
213	test_tun
214	errors=$(( $errors + $? ))
215
216	return $errors
217}
218
219trap cleanup EXIT
220
221run_tests
222
223if [ $? -ne 0 ]; then
224	echo -e "$(basename $0): ${RED}FAIL${NC}"
225	exit 1
226fi
227echo -e "$(basename $0): ${GREEN}PASS${NC}"
228exit 0
229