18c2ecf20Sopenharmony_ci#!/bin/bash 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci. "$(dirname "${0}")/mptcp_lib.sh" 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_cirndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 78c2ecf20Sopenharmony_cins1="ns1-$rndh" 88c2ecf20Sopenharmony_cins2="ns2-$rndh" 98c2ecf20Sopenharmony_cins3="ns3-$rndh" 108c2ecf20Sopenharmony_cicapture=false 118c2ecf20Sopenharmony_ciksft_skip=4 128c2ecf20Sopenharmony_citimeout=30 138c2ecf20Sopenharmony_citest_cnt=1 148c2ecf20Sopenharmony_ciret=0 158c2ecf20Sopenharmony_cibail=0 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ciusage() { 188c2ecf20Sopenharmony_ci echo "Usage: $0 [ -b ] [ -c ] [ -d ]" 198c2ecf20Sopenharmony_ci echo -e "\t-b: bail out after first error, otherwise runs al testcases" 208c2ecf20Sopenharmony_ci echo -e "\t-c: capture packets for each test using tcpdump (default: no capture)" 218c2ecf20Sopenharmony_ci echo -e "\t-d: debug this script" 228c2ecf20Sopenharmony_ci} 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cicleanup() 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci rm -f "$cout" "$sout" 278c2ecf20Sopenharmony_ci rm -f "$large" "$small" 288c2ecf20Sopenharmony_ci rm -f "$capout" 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci local netns 318c2ecf20Sopenharmony_ci for netns in "$ns1" "$ns2" "$ns3";do 328c2ecf20Sopenharmony_ci ip netns del $netns 338c2ecf20Sopenharmony_ci done 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cimptcp_lib_check_mptcp 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ciip -Version > /dev/null 2>&1 398c2ecf20Sopenharmony_ciif [ $? -ne 0 ];then 408c2ecf20Sopenharmony_ci echo "SKIP: Could not run test without ip tool" 418c2ecf20Sopenharmony_ci exit $ksft_skip 428c2ecf20Sopenharmony_cifi 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci# "$ns1" ns2 ns3 458c2ecf20Sopenharmony_ci# ns1eth1 ns2eth1 ns2eth3 ns3eth1 468c2ecf20Sopenharmony_ci# netem 478c2ecf20Sopenharmony_ci# ns1eth2 ns2eth2 488c2ecf20Sopenharmony_ci# netem 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cisetup() 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci large=$(mktemp) 538c2ecf20Sopenharmony_ci small=$(mktemp) 548c2ecf20Sopenharmony_ci sout=$(mktemp) 558c2ecf20Sopenharmony_ci cout=$(mktemp) 568c2ecf20Sopenharmony_ci capout=$(mktemp) 578c2ecf20Sopenharmony_ci size=$((2048 * 4096)) 588c2ecf20Sopenharmony_ci dd if=/dev/zero of=$small bs=4096 count=20 >/dev/null 2>&1 598c2ecf20Sopenharmony_ci dd if=/dev/zero of=$large bs=4096 count=$((size / 4096)) >/dev/null 2>&1 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci trap cleanup EXIT 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci for i in "$ns1" "$ns2" "$ns3";do 648c2ecf20Sopenharmony_ci ip netns add $i || exit $ksft_skip 658c2ecf20Sopenharmony_ci ip -net $i link set lo up 668c2ecf20Sopenharmony_ci done 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci ip link add ns1eth1 netns "$ns1" type veth peer name ns2eth1 netns "$ns2" 698c2ecf20Sopenharmony_ci ip link add ns1eth2 netns "$ns1" type veth peer name ns2eth2 netns "$ns2" 708c2ecf20Sopenharmony_ci ip link add ns2eth3 netns "$ns2" type veth peer name ns3eth1 netns "$ns3" 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci ip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth1 738c2ecf20Sopenharmony_ci ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth1 nodad 748c2ecf20Sopenharmony_ci ip -net "$ns1" link set ns1eth1 up mtu 1500 758c2ecf20Sopenharmony_ci ip -net "$ns1" route add default via 10.0.1.2 768c2ecf20Sopenharmony_ci ip -net "$ns1" route add default via dead:beef:1::2 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci ip -net "$ns1" addr add 10.0.2.1/24 dev ns1eth2 798c2ecf20Sopenharmony_ci ip -net "$ns1" addr add dead:beef:2::1/64 dev ns1eth2 nodad 808c2ecf20Sopenharmony_ci ip -net "$ns1" link set ns1eth2 up mtu 1500 818c2ecf20Sopenharmony_ci ip -net "$ns1" route add default via 10.0.2.2 metric 101 828c2ecf20Sopenharmony_ci ip -net "$ns1" route add default via dead:beef:2::2 metric 101 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci ip netns exec "$ns1" ./pm_nl_ctl limits 1 1 858c2ecf20Sopenharmony_ci ip netns exec "$ns1" ./pm_nl_ctl add 10.0.2.1 dev ns1eth2 flags subflow 868c2ecf20Sopenharmony_ci ip netns exec "$ns1" sysctl -q net.ipv4.conf.all.rp_filter=0 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci ip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1 898c2ecf20Sopenharmony_ci ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad 908c2ecf20Sopenharmony_ci ip -net "$ns2" link set ns2eth1 up mtu 1500 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci ip -net "$ns2" addr add 10.0.2.2/24 dev ns2eth2 938c2ecf20Sopenharmony_ci ip -net "$ns2" addr add dead:beef:2::2/64 dev ns2eth2 nodad 948c2ecf20Sopenharmony_ci ip -net "$ns2" link set ns2eth2 up mtu 1500 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci ip -net "$ns2" addr add 10.0.3.2/24 dev ns2eth3 978c2ecf20Sopenharmony_ci ip -net "$ns2" addr add dead:beef:3::2/64 dev ns2eth3 nodad 988c2ecf20Sopenharmony_ci ip -net "$ns2" link set ns2eth3 up mtu 1500 998c2ecf20Sopenharmony_ci ip netns exec "$ns2" sysctl -q net.ipv4.ip_forward=1 1008c2ecf20Sopenharmony_ci ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci ip -net "$ns3" addr add 10.0.3.3/24 dev ns3eth1 1038c2ecf20Sopenharmony_ci ip -net "$ns3" addr add dead:beef:3::3/64 dev ns3eth1 nodad 1048c2ecf20Sopenharmony_ci ip -net "$ns3" link set ns3eth1 up mtu 1500 1058c2ecf20Sopenharmony_ci ip -net "$ns3" route add default via 10.0.3.2 1068c2ecf20Sopenharmony_ci ip -net "$ns3" route add default via dead:beef:3::2 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci ip netns exec "$ns3" ./pm_nl_ctl limits 1 1 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci# $1: ns, $2: port 1128c2ecf20Sopenharmony_ciwait_local_port_listen() 1138c2ecf20Sopenharmony_ci{ 1148c2ecf20Sopenharmony_ci local listener_ns="${1}" 1158c2ecf20Sopenharmony_ci local port="${2}" 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci local port_hex i 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci port_hex="$(printf "%04X" "${port}")" 1208c2ecf20Sopenharmony_ci for i in $(seq 10); do 1218c2ecf20Sopenharmony_ci ip netns exec "${listener_ns}" cat /proc/net/tcp* | \ 1228c2ecf20Sopenharmony_ci awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" && 1238c2ecf20Sopenharmony_ci break 1248c2ecf20Sopenharmony_ci sleep 0.1 1258c2ecf20Sopenharmony_ci done 1268c2ecf20Sopenharmony_ci} 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cido_transfer() 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci local cin=$1 1318c2ecf20Sopenharmony_ci local sin=$2 1328c2ecf20Sopenharmony_ci local max_time=$3 1338c2ecf20Sopenharmony_ci local port 1348c2ecf20Sopenharmony_ci port=$((10000+$test_cnt)) 1358c2ecf20Sopenharmony_ci test_cnt=$((test_cnt+1)) 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci :> "$cout" 1388c2ecf20Sopenharmony_ci :> "$sout" 1398c2ecf20Sopenharmony_ci :> "$capout" 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci local addr_port 1428c2ecf20Sopenharmony_ci addr_port=$(printf "%s:%d" ${connect_addr} ${port}) 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci if $capture; then 1458c2ecf20Sopenharmony_ci local capuser 1468c2ecf20Sopenharmony_ci if [ -z $SUDO_USER ] ; then 1478c2ecf20Sopenharmony_ci capuser="" 1488c2ecf20Sopenharmony_ci else 1498c2ecf20Sopenharmony_ci capuser="-Z $SUDO_USER" 1508c2ecf20Sopenharmony_ci fi 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci local capfile="${rndh}-${port}" 1538c2ecf20Sopenharmony_ci local capopt="-i any -s 65535 -B 32768 ${capuser}" 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci ip netns exec ${ns3} tcpdump ${capopt} -w "${capfile}-listener.pcap" >> "${capout}" 2>&1 & 1568c2ecf20Sopenharmony_ci local cappid_listener=$! 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci ip netns exec ${ns1} tcpdump ${capopt} -w "${capfile}-connector.pcap" >> "${capout}" 2>&1 & 1598c2ecf20Sopenharmony_ci local cappid_connector=$! 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci sleep 1 1628c2ecf20Sopenharmony_ci fi 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci ip netns exec ${ns3} ./mptcp_connect -jt $timeout -l -p $port 0.0.0.0 < "$sin" > "$sout" & 1658c2ecf20Sopenharmony_ci local spid=$! 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci wait_local_port_listen "${ns3}" "${port}" 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci local start 1708c2ecf20Sopenharmony_ci start=$(date +%s%3N) 1718c2ecf20Sopenharmony_ci ip netns exec ${ns1} ./mptcp_connect -jt $timeout -p $port 10.0.3.3 < "$cin" > "$cout" & 1728c2ecf20Sopenharmony_ci local cpid=$! 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci wait $cpid 1758c2ecf20Sopenharmony_ci local retc=$? 1768c2ecf20Sopenharmony_ci wait $spid 1778c2ecf20Sopenharmony_ci local rets=$? 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci local stop 1808c2ecf20Sopenharmony_ci stop=$(date +%s%3N) 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci if $capture; then 1838c2ecf20Sopenharmony_ci sleep 1 1848c2ecf20Sopenharmony_ci kill ${cappid_listener} 1858c2ecf20Sopenharmony_ci kill ${cappid_connector} 1868c2ecf20Sopenharmony_ci fi 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci local duration 1898c2ecf20Sopenharmony_ci duration=$((stop-start)) 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci cmp $sin $cout > /dev/null 2>&1 1928c2ecf20Sopenharmony_ci local cmps=$? 1938c2ecf20Sopenharmony_ci cmp $cin $sout > /dev/null 2>&1 1948c2ecf20Sopenharmony_ci local cmpc=$? 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci printf "%16s" "$duration max $max_time " 1978c2ecf20Sopenharmony_ci if [ $retc -eq 0 ] && [ $rets -eq 0 ] && \ 1988c2ecf20Sopenharmony_ci [ $cmpc -eq 0 ] && [ $cmps -eq 0 ] && \ 1998c2ecf20Sopenharmony_ci [ $duration -lt $max_time ]; then 2008c2ecf20Sopenharmony_ci echo "[ OK ]" 2018c2ecf20Sopenharmony_ci cat "$capout" 2028c2ecf20Sopenharmony_ci return 0 2038c2ecf20Sopenharmony_ci fi 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci echo " [ fail ]" 2068c2ecf20Sopenharmony_ci echo "client exit code $retc, server $rets" 1>&2 2078c2ecf20Sopenharmony_ci echo -e "\nnetns ${ns3} socket stat for $port:" 1>&2 2088c2ecf20Sopenharmony_ci ip netns exec ${ns3} ss -nita 1>&2 -o "sport = :$port" 2098c2ecf20Sopenharmony_ci echo -e "\nnetns ${ns1} socket stat for $port:" 1>&2 2108c2ecf20Sopenharmony_ci ip netns exec ${ns1} ss -nita 1>&2 -o "dport = :$port" 2118c2ecf20Sopenharmony_ci ls -l $sin $cout 2128c2ecf20Sopenharmony_ci ls -l $cin $sout 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci cat "$capout" 2158c2ecf20Sopenharmony_ci return 1 2168c2ecf20Sopenharmony_ci} 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_cirun_test() 2198c2ecf20Sopenharmony_ci{ 2208c2ecf20Sopenharmony_ci local rate1=$1 2218c2ecf20Sopenharmony_ci local rate2=$2 2228c2ecf20Sopenharmony_ci local delay1=$3 2238c2ecf20Sopenharmony_ci local delay2=$4 2248c2ecf20Sopenharmony_ci local lret 2258c2ecf20Sopenharmony_ci local dev 2268c2ecf20Sopenharmony_ci shift 4 2278c2ecf20Sopenharmony_ci local msg=$* 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci [ $delay1 -gt 0 ] && delay1="delay $delay1" || delay1="" 2308c2ecf20Sopenharmony_ci [ $delay2 -gt 0 ] && delay2="delay $delay2" || delay2="" 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci for dev in ns1eth1 ns1eth2; do 2338c2ecf20Sopenharmony_ci tc -n $ns1 qdisc del dev $dev root >/dev/null 2>&1 2348c2ecf20Sopenharmony_ci done 2358c2ecf20Sopenharmony_ci for dev in ns2eth1 ns2eth2; do 2368c2ecf20Sopenharmony_ci tc -n $ns2 qdisc del dev $dev root >/dev/null 2>&1 2378c2ecf20Sopenharmony_ci done 2388c2ecf20Sopenharmony_ci tc -n $ns1 qdisc add dev ns1eth1 root netem rate ${rate1}mbit $delay1 2398c2ecf20Sopenharmony_ci tc -n $ns1 qdisc add dev ns1eth2 root netem rate ${rate2}mbit $delay2 2408c2ecf20Sopenharmony_ci tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1 2418c2ecf20Sopenharmony_ci tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci # time is measure in ms 2448c2ecf20Sopenharmony_ci local time=$((size * 8 * 1000 / (( $rate1 + $rate2) * 1024 *1024) )) 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci # mptcp_connect will do some sleeps to allow the mp_join handshake 2478c2ecf20Sopenharmony_ci # completion 2488c2ecf20Sopenharmony_ci time=$((time + 1350)) 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci printf "%-50s" "$msg" 2518c2ecf20Sopenharmony_ci do_transfer $small $large $((time * 11 / 10)) 2528c2ecf20Sopenharmony_ci lret=$? 2538c2ecf20Sopenharmony_ci if [ $lret -ne 0 ]; then 2548c2ecf20Sopenharmony_ci ret=$lret 2558c2ecf20Sopenharmony_ci [ $bail -eq 0 ] || exit $ret 2568c2ecf20Sopenharmony_ci fi 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci printf "%-50s" "$msg - reverse direction" 2598c2ecf20Sopenharmony_ci do_transfer $large $small $((time * 11 / 10)) 2608c2ecf20Sopenharmony_ci lret=$? 2618c2ecf20Sopenharmony_ci if [ $lret -ne 0 ]; then 2628c2ecf20Sopenharmony_ci ret=$lret 2638c2ecf20Sopenharmony_ci [ $bail -eq 0 ] || exit $ret 2648c2ecf20Sopenharmony_ci fi 2658c2ecf20Sopenharmony_ci} 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ciwhile getopts "bcdh" option;do 2688c2ecf20Sopenharmony_ci case "$option" in 2698c2ecf20Sopenharmony_ci "h") 2708c2ecf20Sopenharmony_ci usage $0 2718c2ecf20Sopenharmony_ci exit 0 2728c2ecf20Sopenharmony_ci ;; 2738c2ecf20Sopenharmony_ci "b") 2748c2ecf20Sopenharmony_ci bail=1 2758c2ecf20Sopenharmony_ci ;; 2768c2ecf20Sopenharmony_ci "c") 2778c2ecf20Sopenharmony_ci capture=true 2788c2ecf20Sopenharmony_ci ;; 2798c2ecf20Sopenharmony_ci "d") 2808c2ecf20Sopenharmony_ci set -x 2818c2ecf20Sopenharmony_ci ;; 2828c2ecf20Sopenharmony_ci "?") 2838c2ecf20Sopenharmony_ci usage $0 2848c2ecf20Sopenharmony_ci exit 1 2858c2ecf20Sopenharmony_ci ;; 2868c2ecf20Sopenharmony_ci esac 2878c2ecf20Sopenharmony_cidone 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cisetup 2908c2ecf20Sopenharmony_cirun_test 10 10 0 0 "balanced bwidth" 2918c2ecf20Sopenharmony_cirun_test 10 10 1 50 "balanced bwidth with unbalanced delay" 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci# we still need some additional infrastructure to pass the following test-cases 2948c2ecf20Sopenharmony_ci# run_test 30 10 0 0 "unbalanced bwidth" 2958c2ecf20Sopenharmony_ci# run_test 30 10 1 50 "unbalanced bwidth with unbalanced delay" 2968c2ecf20Sopenharmony_ci# run_test 30 10 50 1 "unbalanced bwidth with opposed, unbalanced delay" 2978c2ecf20Sopenharmony_ciexit $ret 298