1#!/bin/bash 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 27source lib.sh 28 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 if ! modprobe -q ip_vs; then 50 echo "skip: could not run test without ipvs module" 51 exit $ksft_skip 52 fi 53fi 54 55checktool "ipvsadm -v" "run test without ipvsadm" 56checktool "socat -h" "run test without socat" 57 58setup() { 59 setup_ns ns0 ns1 ns2 60 61 ip link add veth01 netns "${ns0}" type veth peer name veth10 netns "${ns1}" 62 ip link add veth02 netns "${ns0}" type veth peer name veth20 netns "${ns2}" 63 ip link add veth12 netns "${ns1}" type veth peer name veth21 netns "${ns2}" 64 65 ip netns exec "${ns0}" ip link set veth01 up 66 ip netns exec "${ns0}" ip link set veth02 up 67 ip netns exec "${ns0}" ip link add br0 type bridge 68 ip netns exec "${ns0}" ip link set veth01 master br0 69 ip netns exec "${ns0}" ip link set veth02 master br0 70 ip netns exec "${ns0}" ip link set br0 up 71 ip netns exec "${ns0}" ip addr add "${cip_v4}/24" dev br0 72 73 ip netns exec "${ns1}" ip link set veth10 up 74 ip netns exec "${ns1}" ip addr add "${gip_v4}/24" dev veth10 75 ip netns exec "${ns1}" ip link set veth12 up 76 ip netns exec "${ns1}" ip addr add "${dip_v4}/24" dev veth12 77 78 ip netns exec "${ns2}" ip link set veth21 up 79 ip netns exec "${ns2}" ip addr add "${rip_v4}/24" dev veth21 80 ip netns exec "${ns2}" ip link set veth20 up 81 ip netns exec "${ns2}" ip addr add "${sip_v4}/24" dev veth20 82 83 sleep 1 84 85 dd if=/dev/urandom of="${infile}" bs="${datalen}" count=1 status=none 86} 87 88cleanup() { 89 cleanup_all_ns 90 91 if [ -f "${outfile}" ]; then 92 rm "${outfile}" 93 fi 94 if [ -f "${infile}" ]; then 95 rm "${infile}" 96 fi 97} 98 99server_listen() { 100 ip netns exec "$ns2" timeout 5 socat -u -4 TCP-LISTEN:8080,reuseaddr STDOUT > "${outfile}" & 101 server_pid=$! 102 sleep 0.2 103} 104 105client_connect() { 106 ip netns exec "${ns0}" timeout 2 socat -u -4 STDIN TCP:"${vip_v4}":"${port}" < "${infile}" 107} 108 109verify_data() { 110 wait "${server_pid}" 111 cmp "$infile" "$outfile" 2>/dev/null 112} 113 114test_service() { 115 server_listen 116 client_connect 117 verify_data 118} 119 120 121test_dr() { 122 ip netns exec "${ns0}" ip route add "${vip_v4}" via "${gip_v4}" dev br0 123 124 ip netns exec "${ns1}" sysctl -qw net.ipv4.ip_forward=1 125 ip netns exec "${ns1}" ipvsadm -A -t "${vip_v4}:${port}" -s rr 126 ip netns exec "${ns1}" ipvsadm -a -t "${vip_v4}:${port}" -r "${rip_v4}:${port}" 127 ip netns exec "${ns1}" ip addr add "${vip_v4}/32" dev lo:1 128 129 # avoid incorrect arp response 130 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.arp_ignore=1 131 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.arp_announce=2 132 # avoid reverse route lookup 133 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.rp_filter=0 134 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.veth21.rp_filter=0 135 ip netns exec "${ns2}" ip addr add "${vip_v4}/32" dev lo:1 136 137 test_service 138} 139 140test_nat() { 141 ip netns exec "${ns0}" ip route add "${vip_v4}" via "${gip_v4}" dev br0 142 143 ip netns exec "${ns1}" sysctl -qw net.ipv4.ip_forward=1 144 ip netns exec "${ns1}" ipvsadm -A -t "${vip_v4}:${port}" -s rr 145 ip netns exec "${ns1}" ipvsadm -a -m -t "${vip_v4}:${port}" -r "${rip_v4}:${port}" 146 ip netns exec "${ns1}" ip addr add "${vip_v4}/32" dev lo:1 147 148 ip netns exec "${ns2}" ip link del veth20 149 ip netns exec "${ns2}" ip route add default via "${dip_v4}" dev veth21 150 151 test_service 152} 153 154test_tun() { 155 ip netns exec "${ns0}" ip route add "${vip_v4}" via "${gip_v4}" dev br0 156 157 ip netns exec "${ns1}" modprobe -q ipip 158 ip netns exec "${ns1}" ip link set tunl0 up 159 ip netns exec "${ns1}" sysctl -qw net.ipv4.ip_forward=0 160 ip netns exec "${ns1}" sysctl -qw net.ipv4.conf.all.send_redirects=0 161 ip netns exec "${ns1}" sysctl -qw net.ipv4.conf.default.send_redirects=0 162 ip netns exec "${ns1}" ipvsadm -A -t "${vip_v4}:${port}" -s rr 163 ip netns exec "${ns1}" ipvsadm -a -i -t "${vip_v4}:${port}" -r ${rip_v4}:${port} 164 ip netns exec "${ns1}" ip addr add ${vip_v4}/32 dev lo:1 165 166 ip netns exec "${ns2}" modprobe -q ipip 167 ip netns exec "${ns2}" ip link set tunl0 up 168 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.arp_ignore=1 169 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.arp_announce=2 170 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.rp_filter=0 171 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.tunl0.rp_filter=0 172 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.veth21.rp_filter=0 173 ip netns exec "${ns2}" ip addr add "${vip_v4}/32" dev lo:1 174 175 test_service 176} 177 178run_tests() { 179 local errors= 180 181 echo "Testing DR mode..." 182 cleanup 183 setup 184 test_dr 185 errors=$(( $errors + $? )) 186 187 echo "Testing NAT mode..." 188 cleanup 189 setup 190 test_nat 191 errors=$(( $errors + $? )) 192 193 echo "Testing Tunnel mode..." 194 cleanup 195 setup 196 test_tun 197 errors=$(( $errors + $? )) 198 199 return $errors 200} 201 202trap cleanup EXIT 203 204run_tests 205 206if [ $? -ne 0 ]; then 207 echo -e "$(basename $0): ${RED}FAIL${NC}" 208 exit 1 209fi 210echo -e "$(basename $0): ${GREEN}PASS${NC}" 211exit 0 212