Merge branch 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / tools / testing / selftests / net / mptcp / simult_flows.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 rndh=$(printf %x $sec)-$(mktemp -u XXXXXX)
5 ns1="ns1-$rndh"
6 ns2="ns2-$rndh"
7 ns3="ns3-$rndh"
8 capture=false
9 ksft_skip=4
10 timeout_poll=30
11 timeout_test=$((timeout_poll * 2 + 1))
12 test_cnt=1
13 ret=0
14 bail=0
15
16 usage() {
17         echo "Usage: $0 [ -b ] [ -c ] [ -d ]"
18         echo -e "\t-b: bail out after first error, otherwise runs al testcases"
19         echo -e "\t-c: capture packets for each test using tcpdump (default: no capture)"
20         echo -e "\t-d: debug this script"
21 }
22
23 cleanup()
24 {
25         rm -f "$cout" "$sout"
26         rm -f "$large" "$small"
27         rm -f "$capout"
28
29         local netns
30         for netns in "$ns1" "$ns2" "$ns3";do
31                 ip netns del $netns
32         done
33 }
34
35 ip -Version > /dev/null 2>&1
36 if [ $? -ne 0 ];then
37         echo "SKIP: Could not run test without ip tool"
38         exit $ksft_skip
39 fi
40
41 #  "$ns1"              ns2                    ns3
42 #     ns1eth1    ns2eth1   ns2eth3      ns3eth1
43 #            netem
44 #     ns1eth2    ns2eth2
45 #            netem
46
47 setup()
48 {
49         large=$(mktemp)
50         small=$(mktemp)
51         sout=$(mktemp)
52         cout=$(mktemp)
53         capout=$(mktemp)
54         size=$((2048 * 4096))
55         dd if=/dev/zero of=$small bs=4096 count=20 >/dev/null 2>&1
56         dd if=/dev/zero of=$large bs=4096 count=$((size / 4096)) >/dev/null 2>&1
57
58         trap cleanup EXIT
59
60         for i in "$ns1" "$ns2" "$ns3";do
61                 ip netns add $i || exit $ksft_skip
62                 ip -net $i link set lo up
63                 ip netns exec $i sysctl -q net.ipv4.conf.all.rp_filter=0
64                 ip netns exec $i sysctl -q net.ipv4.conf.default.rp_filter=0
65         done
66
67         ip link add ns1eth1 netns "$ns1" type veth peer name ns2eth1 netns "$ns2"
68         ip link add ns1eth2 netns "$ns1" type veth peer name ns2eth2 netns "$ns2"
69         ip link add ns2eth3 netns "$ns2" type veth peer name ns3eth1 netns "$ns3"
70
71         ip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth1
72         ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth1 nodad
73         ip -net "$ns1" link set ns1eth1 up mtu 1500
74         ip -net "$ns1" route add default via 10.0.1.2
75         ip -net "$ns1" route add default via dead:beef:1::2
76
77         ip -net "$ns1" addr add 10.0.2.1/24 dev ns1eth2
78         ip -net "$ns1" addr add dead:beef:2::1/64 dev ns1eth2 nodad
79         ip -net "$ns1" link set ns1eth2 up mtu 1500
80         ip -net "$ns1" route add default via 10.0.2.2 metric 101
81         ip -net "$ns1" route add default via dead:beef:2::2 metric 101
82
83         ip netns exec "$ns1" ./pm_nl_ctl limits 1 1
84         ip netns exec "$ns1" ./pm_nl_ctl add 10.0.2.1 dev ns1eth2 flags subflow
85
86         ip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1
87         ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad
88         ip -net "$ns2" link set ns2eth1 up mtu 1500
89
90         ip -net "$ns2" addr add 10.0.2.2/24 dev ns2eth2
91         ip -net "$ns2" addr add dead:beef:2::2/64 dev ns2eth2 nodad
92         ip -net "$ns2" link set ns2eth2 up mtu 1500
93
94         ip -net "$ns2" addr add 10.0.3.2/24 dev ns2eth3
95         ip -net "$ns2" addr add dead:beef:3::2/64 dev ns2eth3 nodad
96         ip -net "$ns2" link set ns2eth3 up mtu 1500
97         ip netns exec "$ns2" sysctl -q net.ipv4.ip_forward=1
98         ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1
99
100         ip -net "$ns3" addr add 10.0.3.3/24 dev ns3eth1
101         ip -net "$ns3" addr add dead:beef:3::3/64 dev ns3eth1 nodad
102         ip -net "$ns3" link set ns3eth1 up mtu 1500
103         ip -net "$ns3" route add default via 10.0.3.2
104         ip -net "$ns3" route add default via dead:beef:3::2
105
106         ip netns exec "$ns3" ./pm_nl_ctl limits 1 1
107 }
108
109 # $1: ns, $2: port
110 wait_local_port_listen()
111 {
112         local listener_ns="${1}"
113         local port="${2}"
114
115         local port_hex i
116
117         port_hex="$(printf "%04X" "${port}")"
118         for i in $(seq 10); do
119                 ip netns exec "${listener_ns}" cat /proc/net/tcp* | \
120                         awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" &&
121                         break
122                 sleep 0.1
123         done
124 }
125
126 do_transfer()
127 {
128         local cin=$1
129         local sin=$2
130         local max_time=$3
131         local port
132         port=$((10000+$test_cnt))
133         test_cnt=$((test_cnt+1))
134
135         :> "$cout"
136         :> "$sout"
137         :> "$capout"
138
139         local addr_port
140         addr_port=$(printf "%s:%d" ${connect_addr} ${port})
141
142         if $capture; then
143                 local capuser
144                 if [ -z $SUDO_USER ] ; then
145                         capuser=""
146                 else
147                         capuser="-Z $SUDO_USER"
148                 fi
149
150                 local capfile="${rndh}-${port}"
151                 local capopt="-i any -s 65535 -B 32768 ${capuser}"
152
153                 ip netns exec ${ns3}  tcpdump ${capopt} -w "${capfile}-listener.pcap"  >> "${capout}" 2>&1 &
154                 local cappid_listener=$!
155
156                 ip netns exec ${ns1} tcpdump ${capopt} -w "${capfile}-connector.pcap" >> "${capout}" 2>&1 &
157                 local cappid_connector=$!
158
159                 sleep 1
160         fi
161
162         timeout ${timeout_test} \
163                 ip netns exec ${ns3} \
164                         ./mptcp_connect -jt ${timeout_poll} -l -p $port \
165                                 0.0.0.0 < "$sin" > "$sout" &
166         local spid=$!
167
168         wait_local_port_listen "${ns3}" "${port}"
169
170         local start
171         start=$(date +%s%3N)
172         timeout ${timeout_test} \
173                 ip netns exec ${ns1} \
174                         ./mptcp_connect -jt ${timeout_poll} -p $port \
175                                 10.0.3.3 < "$cin" > "$cout" &
176         local cpid=$!
177
178         wait $cpid
179         local retc=$?
180         wait $spid
181         local rets=$?
182
183         local stop
184         stop=$(date +%s%3N)
185
186         if $capture; then
187                 sleep 1
188                 kill ${cappid_listener}
189                 kill ${cappid_connector}
190         fi
191
192         local duration
193         duration=$((stop-start))
194
195         cmp $sin $cout > /dev/null 2>&1
196         local cmps=$?
197         cmp $cin $sout > /dev/null 2>&1
198         local cmpc=$?
199
200         printf "%16s" "$duration max $max_time "
201         if [ $retc -eq 0 ] && [ $rets -eq 0 ] && \
202            [ $cmpc -eq 0 ] && [ $cmps -eq 0 ] && \
203            [ $duration -lt $max_time ]; then
204                 echo "[ OK ]"
205                 cat "$capout"
206                 return 0
207         fi
208
209         echo " [ fail ]"
210         echo "client exit code $retc, server $rets" 1>&2
211         echo -e "\nnetns ${ns3} socket stat for $port:" 1>&2
212         ip netns exec ${ns3} ss -nita 1>&2 -o "sport = :$port"
213         echo -e "\nnetns ${ns1} socket stat for $port:" 1>&2
214         ip netns exec ${ns1} ss -nita 1>&2 -o "dport = :$port"
215         ls -l $sin $cout
216         ls -l $cin $sout
217
218         cat "$capout"
219         return 1
220 }
221
222 run_test()
223 {
224         local rate1=$1
225         local rate2=$2
226         local delay1=$3
227         local delay2=$4
228         local lret
229         local dev
230         shift 4
231         local msg=$*
232
233         [ $delay1 -gt 0 ] && delay1="delay $delay1" || delay1=""
234         [ $delay2 -gt 0 ] && delay2="delay $delay2" || delay2=""
235
236         for dev in ns1eth1 ns1eth2; do
237                 tc -n $ns1 qdisc del dev $dev root >/dev/null 2>&1
238         done
239         for dev in ns2eth1 ns2eth2; do
240                 tc -n $ns2 qdisc del dev $dev root >/dev/null 2>&1
241         done
242         tc -n $ns1 qdisc add dev ns1eth1 root netem rate ${rate1}mbit $delay1
243         tc -n $ns1 qdisc add dev ns1eth2 root netem rate ${rate2}mbit $delay2
244         tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1
245         tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2
246
247         # time is measure in ms
248         local time=$((size * 8 * 1000 / (( $rate1 + $rate2) * 1024 *1024) ))
249
250         # mptcp_connect will do some sleeps to allow the mp_join handshake
251         # completion
252         time=$((time + 1350))
253
254         printf "%-50s" "$msg"
255         do_transfer $small $large $((time * 11 / 10))
256         lret=$?
257         if [ $lret -ne 0 ]; then
258                 ret=$lret
259                 [ $bail -eq 0 ] || exit $ret
260         fi
261
262         printf "%-50s" "$msg - reverse direction"
263         do_transfer $large $small $((time * 11 / 10))
264         lret=$?
265         if [ $lret -ne 0 ]; then
266                 ret=$lret
267                 [ $bail -eq 0 ] || exit $ret
268         fi
269 }
270
271 while getopts "bcdh" option;do
272         case "$option" in
273         "h")
274                 usage $0
275                 exit 0
276                 ;;
277         "b")
278                 bail=1
279                 ;;
280         "c")
281                 capture=true
282                 ;;
283         "d")
284                 set -x
285                 ;;
286         "?")
287                 usage $0
288                 exit 1
289                 ;;
290         esac
291 done
292
293 setup
294 run_test 10 10 0 0 "balanced bwidth"
295 run_test 10 10 1 50 "balanced bwidth with unbalanced delay"
296
297 # we still need some additional infrastructure to pass the following test-cases
298 run_test 30 10 0 0 "unbalanced bwidth"
299 run_test 30 10 1 50 "unbalanced bwidth with unbalanced delay"
300 run_test 30 10 50 1 "unbalanced bwidth with opposed, unbalanced delay"
301 exit $ret