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