11a418cb8SPaolo Abeni#!/bin/bash 21a418cb8SPaolo Abeni# SPDX-License-Identifier: GPL-2.0 31a418cb8SPaolo Abeni 49161f21cSMatthieu Baerts. "$(dirname "${0}")/mptcp_lib.sh" 59161f21cSMatthieu Baerts 6787eb1e4SMatthieu Baertssec=$(date +%s) 71a418cb8SPaolo Abenirndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 81a418cb8SPaolo Abenins1="ns1-$rndh" 91a418cb8SPaolo Abenins2="ns2-$rndh" 101a418cb8SPaolo Abenins3="ns3-$rndh" 111a418cb8SPaolo Abenicapture=false 121a418cb8SPaolo Abeniksft_skip=4 135888a61cSMatthieu Baertstimeout_poll=30 145888a61cSMatthieu Baertstimeout_test=$((timeout_poll * 2 + 1)) 151a418cb8SPaolo Abenitest_cnt=1 161a418cb8SPaolo Abeniret=0 171a418cb8SPaolo Abenibail=0 18d0d9c8f2SPaolo Abenislack=50 191a418cb8SPaolo Abeni 201a418cb8SPaolo Abeniusage() { 211a418cb8SPaolo Abeni echo "Usage: $0 [ -b ] [ -c ] [ -d ]" 221a418cb8SPaolo Abeni echo -e "\t-b: bail out after first error, otherwise runs al testcases" 231a418cb8SPaolo Abeni echo -e "\t-c: capture packets for each test using tcpdump (default: no capture)" 241a418cb8SPaolo Abeni echo -e "\t-d: debug this script" 251a418cb8SPaolo Abeni} 261a418cb8SPaolo Abeni 271a418cb8SPaolo Abenicleanup() 281a418cb8SPaolo Abeni{ 29bfd862a7SMatthieu Baerts rm -f "$cout" "$sout" 30bfd862a7SMatthieu Baerts rm -f "$large" "$small" 311a418cb8SPaolo Abeni rm -f "$capout" 321a418cb8SPaolo Abeni 331a418cb8SPaolo Abeni local netns 341a418cb8SPaolo Abeni for netns in "$ns1" "$ns2" "$ns3";do 351a418cb8SPaolo Abeni ip netns del $netns 361a418cb8SPaolo Abeni done 371a418cb8SPaolo Abeni} 381a418cb8SPaolo Abeni 399161f21cSMatthieu Baertsmptcp_lib_check_mptcp 409161f21cSMatthieu Baerts 411a418cb8SPaolo Abeniip -Version > /dev/null 2>&1 421a418cb8SPaolo Abeniif [ $? -ne 0 ];then 431a418cb8SPaolo Abeni echo "SKIP: Could not run test without ip tool" 441a418cb8SPaolo Abeni exit $ksft_skip 451a418cb8SPaolo Abenifi 461a418cb8SPaolo Abeni 471a418cb8SPaolo Abeni# "$ns1" ns2 ns3 481a418cb8SPaolo Abeni# ns1eth1 ns2eth1 ns2eth3 ns3eth1 491a418cb8SPaolo Abeni# netem 501a418cb8SPaolo Abeni# ns1eth2 ns2eth2 511a418cb8SPaolo Abeni# netem 521a418cb8SPaolo Abeni 531a418cb8SPaolo Abenisetup() 541a418cb8SPaolo Abeni{ 551a418cb8SPaolo Abeni large=$(mktemp) 561a418cb8SPaolo Abeni small=$(mktemp) 571a418cb8SPaolo Abeni sout=$(mktemp) 581a418cb8SPaolo Abeni cout=$(mktemp) 591a418cb8SPaolo Abeni capout=$(mktemp) 60b6ab64b0SPaolo Abeni size=$((2 * 2048 * 4096)) 61d0d9c8f2SPaolo Abeni 621a418cb8SPaolo Abeni dd if=/dev/zero of=$small bs=4096 count=20 >/dev/null 2>&1 631a418cb8SPaolo Abeni dd if=/dev/zero of=$large bs=4096 count=$((size / 4096)) >/dev/null 2>&1 641a418cb8SPaolo Abeni 651a418cb8SPaolo Abeni trap cleanup EXIT 661a418cb8SPaolo Abeni 671a418cb8SPaolo Abeni for i in "$ns1" "$ns2" "$ns3";do 681a418cb8SPaolo Abeni ip netns add $i || exit $ksft_skip 691a418cb8SPaolo Abeni ip -net $i link set lo up 70d8e336f7SYonglong Li ip netns exec $i sysctl -q net.ipv4.conf.all.rp_filter=0 71d8e336f7SYonglong Li ip netns exec $i sysctl -q net.ipv4.conf.default.rp_filter=0 721a418cb8SPaolo Abeni done 731a418cb8SPaolo Abeni 741a418cb8SPaolo Abeni ip link add ns1eth1 netns "$ns1" type veth peer name ns2eth1 netns "$ns2" 751a418cb8SPaolo Abeni ip link add ns1eth2 netns "$ns1" type veth peer name ns2eth2 netns "$ns2" 761a418cb8SPaolo Abeni ip link add ns2eth3 netns "$ns2" type veth peer name ns3eth1 netns "$ns3" 771a418cb8SPaolo Abeni 781a418cb8SPaolo Abeni ip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth1 791a418cb8SPaolo Abeni ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth1 nodad 801a418cb8SPaolo Abeni ip -net "$ns1" link set ns1eth1 up mtu 1500 811a418cb8SPaolo Abeni ip -net "$ns1" route add default via 10.0.1.2 821a418cb8SPaolo Abeni ip -net "$ns1" route add default via dead:beef:1::2 831a418cb8SPaolo Abeni 841a418cb8SPaolo Abeni ip -net "$ns1" addr add 10.0.2.1/24 dev ns1eth2 851a418cb8SPaolo Abeni ip -net "$ns1" addr add dead:beef:2::1/64 dev ns1eth2 nodad 861a418cb8SPaolo Abeni ip -net "$ns1" link set ns1eth2 up mtu 1500 871a418cb8SPaolo Abeni ip -net "$ns1" route add default via 10.0.2.2 metric 101 881a418cb8SPaolo Abeni ip -net "$ns1" route add default via dead:beef:2::2 metric 101 891a418cb8SPaolo Abeni 901a418cb8SPaolo Abeni ip netns exec "$ns1" ./pm_nl_ctl limits 1 1 911a418cb8SPaolo Abeni ip netns exec "$ns1" ./pm_nl_ctl add 10.0.2.1 dev ns1eth2 flags subflow 921a418cb8SPaolo Abeni 931a418cb8SPaolo Abeni ip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1 941a418cb8SPaolo Abeni ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad 951a418cb8SPaolo Abeni ip -net "$ns2" link set ns2eth1 up mtu 1500 961a418cb8SPaolo Abeni 971a418cb8SPaolo Abeni ip -net "$ns2" addr add 10.0.2.2/24 dev ns2eth2 981a418cb8SPaolo Abeni ip -net "$ns2" addr add dead:beef:2::2/64 dev ns2eth2 nodad 991a418cb8SPaolo Abeni ip -net "$ns2" link set ns2eth2 up mtu 1500 1001a418cb8SPaolo Abeni 1011a418cb8SPaolo Abeni ip -net "$ns2" addr add 10.0.3.2/24 dev ns2eth3 1021a418cb8SPaolo Abeni ip -net "$ns2" addr add dead:beef:3::2/64 dev ns2eth3 nodad 1031a418cb8SPaolo Abeni ip -net "$ns2" link set ns2eth3 up mtu 1500 1041a418cb8SPaolo Abeni ip netns exec "$ns2" sysctl -q net.ipv4.ip_forward=1 1051a418cb8SPaolo Abeni ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1 1061a418cb8SPaolo Abeni 1071a418cb8SPaolo Abeni ip -net "$ns3" addr add 10.0.3.3/24 dev ns3eth1 1081a418cb8SPaolo Abeni ip -net "$ns3" addr add dead:beef:3::3/64 dev ns3eth1 nodad 1091a418cb8SPaolo Abeni ip -net "$ns3" link set ns3eth1 up mtu 1500 1101a418cb8SPaolo Abeni ip -net "$ns3" route add default via 10.0.3.2 1111a418cb8SPaolo Abeni ip -net "$ns3" route add default via dead:beef:3::2 1121a418cb8SPaolo Abeni 1131a418cb8SPaolo Abeni ip netns exec "$ns3" ./pm_nl_ctl limits 1 1 114d0d9c8f2SPaolo Abeni 115d0d9c8f2SPaolo Abeni # debug build can slow down measurably the test program 116d0d9c8f2SPaolo Abeni # we use quite tight time limit on the run-time, to ensure 117d0d9c8f2SPaolo Abeni # maximum B/W usage. 118d0d9c8f2SPaolo Abeni # Use kmemleak/lockdep/kasan/prove_locking presence as a rough 119d0d9c8f2SPaolo Abeni # estimate for this being a debug kernel and increase the 120d0d9c8f2SPaolo Abeni # maximum run-time accordingly. Observed run times for CI builds 121d0d9c8f2SPaolo Abeni # running selftests, including kbuild, were used to determine the 122d0d9c8f2SPaolo Abeni # amount of time to add. 123d0d9c8f2SPaolo Abeni grep -q ' kmemleak_init$\| lockdep_init$\| kasan_init$\| prove_locking$' /proc/kallsyms && slack=$((slack+550)) 1241a418cb8SPaolo Abeni} 1251a418cb8SPaolo Abeni 1261a418cb8SPaolo Abeni# $1: ns, $2: port 1271a418cb8SPaolo Abeniwait_local_port_listen() 1281a418cb8SPaolo Abeni{ 1291a418cb8SPaolo Abeni local listener_ns="${1}" 1301a418cb8SPaolo Abeni local port="${2}" 1311a418cb8SPaolo Abeni 1321a418cb8SPaolo Abeni local port_hex i 1331a418cb8SPaolo Abeni 1341a418cb8SPaolo Abeni port_hex="$(printf "%04X" "${port}")" 1351a418cb8SPaolo Abeni for i in $(seq 10); do 1361a418cb8SPaolo Abeni ip netns exec "${listener_ns}" cat /proc/net/tcp* | \ 1371a418cb8SPaolo Abeni awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" && 1381a418cb8SPaolo Abeni break 1391a418cb8SPaolo Abeni sleep 0.1 1401a418cb8SPaolo Abeni done 1411a418cb8SPaolo Abeni} 1421a418cb8SPaolo Abeni 1431a418cb8SPaolo Abenido_transfer() 1441a418cb8SPaolo Abeni{ 1451a418cb8SPaolo Abeni local cin=$1 1461a418cb8SPaolo Abeni local sin=$2 1471a418cb8SPaolo Abeni local max_time=$3 1481a418cb8SPaolo Abeni local port 1491a418cb8SPaolo Abeni port=$((10000+$test_cnt)) 1501a418cb8SPaolo Abeni test_cnt=$((test_cnt+1)) 1511a418cb8SPaolo Abeni 1521a418cb8SPaolo Abeni :> "$cout" 1531a418cb8SPaolo Abeni :> "$sout" 1541a418cb8SPaolo Abeni :> "$capout" 1551a418cb8SPaolo Abeni 1561a418cb8SPaolo Abeni if $capture; then 1571a418cb8SPaolo Abeni local capuser 1581a418cb8SPaolo Abeni if [ -z $SUDO_USER ] ; then 1591a418cb8SPaolo Abeni capuser="" 1601a418cb8SPaolo Abeni else 1611a418cb8SPaolo Abeni capuser="-Z $SUDO_USER" 1621a418cb8SPaolo Abeni fi 1631a418cb8SPaolo Abeni 1641a418cb8SPaolo Abeni local capfile="${rndh}-${port}" 1651a418cb8SPaolo Abeni local capopt="-i any -s 65535 -B 32768 ${capuser}" 1661a418cb8SPaolo Abeni 1671a418cb8SPaolo Abeni ip netns exec ${ns3} tcpdump ${capopt} -w "${capfile}-listener.pcap" >> "${capout}" 2>&1 & 1681a418cb8SPaolo Abeni local cappid_listener=$! 1691a418cb8SPaolo Abeni 1701a418cb8SPaolo Abeni ip netns exec ${ns1} tcpdump ${capopt} -w "${capfile}-connector.pcap" >> "${capout}" 2>&1 & 1711a418cb8SPaolo Abeni local cappid_connector=$! 1721a418cb8SPaolo Abeni 1731a418cb8SPaolo Abeni sleep 1 1741a418cb8SPaolo Abeni fi 1751a418cb8SPaolo Abeni 1765888a61cSMatthieu Baerts timeout ${timeout_test} \ 1775888a61cSMatthieu Baerts ip netns exec ${ns3} \ 17831b4e63eSGeliang Tang ./mptcp_connect -jt ${timeout_poll} -l -p $port -T $max_time \ 1795888a61cSMatthieu Baerts 0.0.0.0 < "$sin" > "$sout" & 1801a418cb8SPaolo Abeni local spid=$! 1811a418cb8SPaolo Abeni 1821a418cb8SPaolo Abeni wait_local_port_listen "${ns3}" "${port}" 1831a418cb8SPaolo Abeni 1845888a61cSMatthieu Baerts timeout ${timeout_test} \ 1855888a61cSMatthieu Baerts ip netns exec ${ns1} \ 18631b4e63eSGeliang Tang ./mptcp_connect -jt ${timeout_poll} -p $port -T $max_time \ 1875888a61cSMatthieu Baerts 10.0.3.3 < "$cin" > "$cout" & 1881a418cb8SPaolo Abeni local cpid=$! 1891a418cb8SPaolo Abeni 1901a418cb8SPaolo Abeni wait $cpid 1911a418cb8SPaolo Abeni local retc=$? 1921a418cb8SPaolo Abeni wait $spid 1931a418cb8SPaolo Abeni local rets=$? 1941a418cb8SPaolo Abeni 1951a418cb8SPaolo Abeni if $capture; then 1961a418cb8SPaolo Abeni sleep 1 1971a418cb8SPaolo Abeni kill ${cappid_listener} 1981a418cb8SPaolo Abeni kill ${cappid_connector} 1991a418cb8SPaolo Abeni fi 2001a418cb8SPaolo Abeni 2011a418cb8SPaolo Abeni cmp $sin $cout > /dev/null 2>&1 2021a418cb8SPaolo Abeni local cmps=$? 2031a418cb8SPaolo Abeni cmp $cin $sout > /dev/null 2>&1 2041a418cb8SPaolo Abeni local cmpc=$? 2051a418cb8SPaolo Abeni 206b6ab64b0SPaolo Abeni printf "%-16s" " max $max_time " 2071a418cb8SPaolo Abeni if [ $retc -eq 0 ] && [ $rets -eq 0 ] && \ 208b6ab64b0SPaolo Abeni [ $cmpc -eq 0 ] && [ $cmps -eq 0 ]; then 2091a418cb8SPaolo Abeni echo "[ OK ]" 2101a418cb8SPaolo Abeni cat "$capout" 2111a418cb8SPaolo Abeni return 0 2121a418cb8SPaolo Abeni fi 2131a418cb8SPaolo Abeni 2141a418cb8SPaolo Abeni echo " [ fail ]" 2151a418cb8SPaolo Abeni echo "client exit code $retc, server $rets" 1>&2 216036dfd83SMatthieu Baerts echo -e "\nnetns ${ns3} socket stat for $port:" 1>&2 2171a418cb8SPaolo Abeni ip netns exec ${ns3} ss -nita 1>&2 -o "sport = :$port" 218036dfd83SMatthieu Baerts echo -e "\nnetns ${ns1} socket stat for $port:" 1>&2 2191a418cb8SPaolo Abeni ip netns exec ${ns1} ss -nita 1>&2 -o "dport = :$port" 2201a418cb8SPaolo Abeni ls -l $sin $cout 2211a418cb8SPaolo Abeni ls -l $cin $sout 2221a418cb8SPaolo Abeni 2231a418cb8SPaolo Abeni cat "$capout" 2241a418cb8SPaolo Abeni return 1 2251a418cb8SPaolo Abeni} 2261a418cb8SPaolo Abeni 2271a418cb8SPaolo Abenirun_test() 2281a418cb8SPaolo Abeni{ 2291a418cb8SPaolo Abeni local rate1=$1 2301a418cb8SPaolo Abeni local rate2=$2 2311a418cb8SPaolo Abeni local delay1=$3 2321a418cb8SPaolo Abeni local delay2=$4 2331a418cb8SPaolo Abeni local lret 2341a418cb8SPaolo Abeni local dev 2351a418cb8SPaolo Abeni shift 4 2361a418cb8SPaolo Abeni local msg=$* 2371a418cb8SPaolo Abeni 23899ac814eSGeliang Tang [ $delay1 -gt 0 ] && delay1="delay ${delay1}ms" || delay1="" 23999ac814eSGeliang Tang [ $delay2 -gt 0 ] && delay2="delay ${delay2}ms" || delay2="" 2401a418cb8SPaolo Abeni 2411a418cb8SPaolo Abeni for dev in ns1eth1 ns1eth2; do 2421a418cb8SPaolo Abeni tc -n $ns1 qdisc del dev $dev root >/dev/null 2>&1 2431a418cb8SPaolo Abeni done 2441a418cb8SPaolo Abeni for dev in ns2eth1 ns2eth2; do 2451a418cb8SPaolo Abeni tc -n $ns2 qdisc del dev $dev root >/dev/null 2>&1 2461a418cb8SPaolo Abeni done 2471a418cb8SPaolo Abeni tc -n $ns1 qdisc add dev ns1eth1 root netem rate ${rate1}mbit $delay1 2481a418cb8SPaolo Abeni tc -n $ns1 qdisc add dev ns1eth2 root netem rate ${rate2}mbit $delay2 2491a418cb8SPaolo Abeni tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1 2501a418cb8SPaolo Abeni tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2 2511a418cb8SPaolo Abeni 2523de88b95SMatthieu Baerts # time is measured in ms, account for transfer size, aggregated link speed 253b6ab64b0SPaolo Abeni # and header overhead (10%) 2543de88b95SMatthieu Baerts # ms byte -> bit 10% mbit -> kbit -> bit 10% 2553de88b95SMatthieu Baerts local time=$((1000 * size * 8 * 10 / ((rate1 + rate2) * 1000 * 1000 * 9) )) 2561a418cb8SPaolo Abeni 2571a418cb8SPaolo Abeni # mptcp_connect will do some sleeps to allow the mp_join handshake 258b6ab64b0SPaolo Abeni # completion (see mptcp_connect): 200ms on each side, add some slack 259d0d9c8f2SPaolo Abeni time=$((time + 400 + slack)) 2601a418cb8SPaolo Abeni 261b6ab64b0SPaolo Abeni printf "%-60s" "$msg" 262b6ab64b0SPaolo Abeni do_transfer $small $large $time 2631a418cb8SPaolo Abeni lret=$? 264675d9933SMatthieu Baerts mptcp_lib_result_code "${lret}" "${msg}" 265*1c3b01b5SMatthieu Baerts (NGI0) if [ $lret -ne 0 ]; then 2661a418cb8SPaolo Abeni ret=$lret 2671a418cb8SPaolo Abeni [ $bail -eq 0 ] || exit $ret 2681a418cb8SPaolo Abeni fi 2691a418cb8SPaolo Abeni 270db887e24SMatthieu Baerts (NGI0) msg+=" - reverse direction" 271db887e24SMatthieu Baerts (NGI0) printf "%-60s" "${msg}" 272b6ab64b0SPaolo Abeni do_transfer $large $small $time 2731a418cb8SPaolo Abeni lret=$? 274675d9933SMatthieu Baerts mptcp_lib_result_code "${lret}" "${msg}" 275*1c3b01b5SMatthieu Baerts (NGI0) if [ $lret -ne 0 ]; then 2761a418cb8SPaolo Abeni ret=$lret 2771a418cb8SPaolo Abeni [ $bail -eq 0 ] || exit $ret 2781a418cb8SPaolo Abeni fi 2791a418cb8SPaolo Abeni} 2801a418cb8SPaolo Abeni 2811a418cb8SPaolo Abeniwhile getopts "bcdh" option;do 2821a418cb8SPaolo Abeni case "$option" in 2831a418cb8SPaolo Abeni "h") 2841a418cb8SPaolo Abeni usage $0 2851a418cb8SPaolo Abeni exit 0 2861a418cb8SPaolo Abeni ;; 2871a418cb8SPaolo Abeni "b") 2881a418cb8SPaolo Abeni bail=1 2891a418cb8SPaolo Abeni ;; 2901a418cb8SPaolo Abeni "c") 2911a418cb8SPaolo Abeni capture=true 2921a418cb8SPaolo Abeni ;; 2931a418cb8SPaolo Abeni "d") 2941a418cb8SPaolo Abeni set -x 2951a418cb8SPaolo Abeni ;; 2961a418cb8SPaolo Abeni "?") 2971a418cb8SPaolo Abeni usage $0 2981a418cb8SPaolo Abeni exit 1 2991a418cb8SPaolo Abeni ;; 3001a418cb8SPaolo Abeni esac 3011a418cb8SPaolo Abenidone 3021a418cb8SPaolo Abeni 3031a418cb8SPaolo Abenisetup 3041a418cb8SPaolo Abenirun_test 10 10 0 0 "balanced bwidth" 305e2ee3c62SMatthieu Baerts (NGI0)run_test 10 10 1 25 "balanced bwidth with unbalanced delay" 3061a418cb8SPaolo Abeni 3071a418cb8SPaolo Abeni# we still need some additional infrastructure to pass the following test-cases 308*1c3b01b5SMatthieu Baerts (NGI0)run_test 10 3 0 0 "unbalanced bwidth" 309e2ee3c62SMatthieu Baerts (NGI0)run_test 10 3 1 25 "unbalanced bwidth with unbalanced delay" 310e2ee3c62SMatthieu Baerts (NGI0)run_test 10 3 25 1 "unbalanced bwidth with opposed, unbalanced delay" 311675d9933SMatthieu Baerts 312675d9933SMatthieu Baertsmptcp_lib_result_print_all_tap 3131a418cb8SPaolo Abeniexit $ret 314