1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4sec=$(date +%s) 5rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 6ns="ns1-$rndh" 7ksft_skip=4 8test_cnt=1 9timeout_poll=100 10timeout_test=$((timeout_poll * 2 + 1)) 11ret=0 12 13flush_pids() 14{ 15 # mptcp_connect in join mode will sleep a bit before completing, 16 # give it some time 17 sleep 1.1 18 19 ip netns pids "${ns}" | xargs --no-run-if-empty kill -SIGUSR1 &>/dev/null 20} 21 22cleanup() 23{ 24 ip netns pids "${ns}" | xargs --no-run-if-empty kill -SIGKILL &>/dev/null 25 26 ip netns del $ns 27} 28 29ip -Version > /dev/null 2>&1 30if [ $? -ne 0 ];then 31 echo "SKIP: Could not run test without ip tool" 32 exit $ksft_skip 33fi 34ss -h | grep -q MPTCP 35if [ $? -ne 0 ];then 36 echo "SKIP: ss tool does not support MPTCP" 37 exit $ksft_skip 38fi 39 40__chk_nr() 41{ 42 local condition="$1" 43 local expected=$2 44 local msg nr 45 46 shift 2 47 msg=$* 48 nr=$(ss -inmHMN $ns | $condition) 49 50 printf "%-50s" "$msg" 51 if [ $nr != $expected ]; then 52 echo "[ fail ] expected $expected found $nr" 53 ret=$test_cnt 54 else 55 echo "[ ok ]" 56 fi 57 test_cnt=$((test_cnt+1)) 58} 59 60chk_msk_nr() 61{ 62 __chk_nr "grep -c token:" $* 63} 64 65wait_msk_nr() 66{ 67 local condition="grep -c token:" 68 local expected=$1 69 local timeout=20 70 local msg nr 71 local max=0 72 local i=0 73 74 shift 1 75 msg=$* 76 77 while [ $i -lt $timeout ]; do 78 nr=$(ss -inmHMN $ns | $condition) 79 [ $nr == $expected ] && break; 80 [ $nr -gt $max ] && max=$nr 81 i=$((i + 1)) 82 sleep 1 83 done 84 85 printf "%-50s" "$msg" 86 if [ $i -ge $timeout ]; then 87 echo "[ fail ] timeout while expecting $expected max $max last $nr" 88 ret=$test_cnt 89 elif [ $nr != $expected ]; then 90 echo "[ fail ] expected $expected found $nr" 91 ret=$test_cnt 92 else 93 echo "[ ok ]" 94 fi 95 test_cnt=$((test_cnt+1)) 96} 97 98chk_msk_fallback_nr() 99{ 100 __chk_nr "grep -c fallback" $* 101} 102 103chk_msk_remote_key_nr() 104{ 105 __chk_nr "grep -c remote_key" $* 106} 107 108__chk_listen() 109{ 110 local filter="$1" 111 local expected=$2 112 113 shift 2 114 msg=$* 115 116 nr=$(ss -N $ns -Ml "$filter" | grep -c LISTEN) 117 printf "%-50s" "$msg" 118 119 if [ $nr != $expected ]; then 120 echo "[ fail ] expected $expected found $nr" 121 ret=$test_cnt 122 else 123 echo "[ ok ]" 124 fi 125} 126 127chk_msk_listen() 128{ 129 lport=$1 130 local msg="check for listen socket" 131 132 # destination port search should always return empty list 133 __chk_listen "dport $lport" 0 "listen match for dport $lport" 134 135 # should return 'our' mptcp listen socket 136 __chk_listen "sport $lport" 1 "listen match for sport $lport" 137 138 __chk_listen "src inet:0.0.0.0:$lport" 1 "listen match for saddr and sport" 139 140 __chk_listen "" 1 "all listen sockets" 141 142 nr=$(ss -Ml $filter | wc -l) 143} 144 145# $1: ns, $2: port 146wait_local_port_listen() 147{ 148 local listener_ns="${1}" 149 local port="${2}" 150 151 local port_hex i 152 153 port_hex="$(printf "%04X" "${port}")" 154 for i in $(seq 10); do 155 ip netns exec "${listener_ns}" cat /proc/net/tcp | \ 156 awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" && 157 break 158 sleep 0.1 159 done 160} 161 162wait_connected() 163{ 164 local listener_ns="${1}" 165 local port="${2}" 166 167 local port_hex i 168 169 port_hex="$(printf "%04X" "${port}")" 170 for i in $(seq 10); do 171 ip netns exec ${listener_ns} grep -q " 0100007F:${port_hex} " /proc/net/tcp && break 172 sleep 0.1 173 done 174} 175 176trap cleanup EXIT 177ip netns add $ns 178ip -n $ns link set dev lo up 179 180echo "a" | \ 181 timeout ${timeout_test} \ 182 ip netns exec $ns \ 183 ./mptcp_connect -p 10000 -l -t ${timeout_poll} -w 20 \ 184 0.0.0.0 >/dev/null & 185wait_local_port_listen $ns 10000 186chk_msk_nr 0 "no msk on netns creation" 187chk_msk_listen 10000 188 189echo "b" | \ 190 timeout ${timeout_test} \ 191 ip netns exec $ns \ 192 ./mptcp_connect -p 10000 -r 0 -t ${timeout_poll} -w 20 \ 193 127.0.0.1 >/dev/null & 194wait_connected $ns 10000 195chk_msk_nr 2 "after MPC handshake " 196chk_msk_remote_key_nr 2 "....chk remote_key" 197chk_msk_fallback_nr 0 "....chk no fallback" 198flush_pids 199 200 201echo "a" | \ 202 timeout ${timeout_test} \ 203 ip netns exec $ns \ 204 ./mptcp_connect -p 10001 -l -s TCP -t ${timeout_poll} -w 20 \ 205 0.0.0.0 >/dev/null & 206wait_local_port_listen $ns 10001 207echo "b" | \ 208 timeout ${timeout_test} \ 209 ip netns exec $ns \ 210 ./mptcp_connect -p 10001 -r 0 -t ${timeout_poll} -w 20 \ 211 127.0.0.1 >/dev/null & 212wait_connected $ns 10001 213chk_msk_fallback_nr 1 "check fallback" 214flush_pids 215 216NR_CLIENTS=100 217for I in `seq 1 $NR_CLIENTS`; do 218 echo "a" | \ 219 timeout ${timeout_test} \ 220 ip netns exec $ns \ 221 ./mptcp_connect -p $((I+10001)) -l -w 20 \ 222 -t ${timeout_poll} 0.0.0.0 >/dev/null & 223done 224wait_local_port_listen $ns $((NR_CLIENTS + 10001)) 225 226for I in `seq 1 $NR_CLIENTS`; do 227 echo "b" | \ 228 timeout ${timeout_test} \ 229 ip netns exec $ns \ 230 ./mptcp_connect -p $((I+10001)) -w 20 \ 231 -t ${timeout_poll} 127.0.0.1 >/dev/null & 232done 233 234wait_msk_nr $((NR_CLIENTS*2)) "many msk socket present" 235flush_pids 236 237exit $ret 238