#!/bin/bash # # This script runs a test of source and destination host fairness, using # both fq_codel with tc-flow, and cake with the srchost/dsthost keywords. # It looks like cake srchost/dsthost broke some time between kernel 5.4 # and 5.10, but dual-srchost/dual-dsthost still works. # DURATION=10 IPERF3_PORTS=(5101 5102 5103 5104) ipx() { local ns="$1" shift ip netns exec $ns $* } # setup sets up the netns environment setup() { # set up server ip netns add srv ipx srv sysctl -qw net.ipv6.conf.all.disable_ipv6=1 ipx srv ip link add dev srv.l type veth peer name rtr.r ipx srv ip addr add 10.7.1.1/24 dev srv.l ipx srv ip addr add 10.7.1.2/24 dev srv.l ipx srv ip addr add 10.7.1.3/24 dev srv.l ipx srv ip link set srv.l up # set up router ip netns add rtr ipx rtr sysctl -qw net.ipv6.conf.all.disable_ipv6=1 ipx rtr sysctl -qw net.ipv4.ip_forward=1 ipx srv ip link set dev rtr.r netns rtr ipx rtr ip addr add 10.7.1.254/24 dev rtr.r ipx rtr ip link set rtr.r up ipx rtr ip link add dev rtr.l type veth peer name cli.r ipx rtr ip addr add 10.7.0.254/24 dev rtr.l ipx rtr ip link set rtr.l up # set up bridge #ip netns add rtr #ipx rtr sysctl -qw net.ipv6.conf.all.disable_ipv6=1 #ipx rtr sysctl -qw net.ipv4.ip_forward=1 #ipx srv ip link set dev rtr.r netns rtr #ipx rtr ip link set rtr.r up #ipx rtr ip link add dev rtr.l type veth peer name cli.r #ipx rtr ip link set rtr.l up #ipx rtr ip link add name rtr.b type bridge #ipx rtr ip link set rtr.b up #ipx rtr ip link set rtr.r master rtr.b #ipx rtr ip link set rtr.l master rtr.b # set up client ip netns add cli ipx cli sysctl -qw net.ipv6.conf.all.disable_ipv6=1 ipx rtr ip link set dev cli.r netns cli ipx cli ip addr add 10.7.0.1/24 dev cli.r ipx cli ip addr add 10.7.0.2/24 dev cli.r ipx cli ip addr add 10.7.0.3/24 dev cli.r ipx cli ip link set cli.r up # routing ipx srv ip route add default via 10.7.1.254 ipx cli ip route add default via 10.7.0.254 } # setup_fq_codel adds fq_codel and a hash filter with the specified keys setup_fq_codel() { local keys="$1" local iface for iface in rtr.r; do ipx rtr tc qdisc del dev $iface root &>/dev/null ipx rtr tc qdisc add dev $iface root handle 1: htb default fffe ipx rtr tc class add dev $iface parent 1: classid 1:fffe \ htb rate 50Mbit ceil 50Mbit || error ipx rtr tc qdisc add dev $iface parent 1:fffe handle fffe: \ fq_codel flows 65536 || error if [[ $keys != "" ]]; then ipx rtr tc filter add dev $iface protocol all parent fffe: handle 1 \ flow hash keys $keys divisor 65536 || error fi ipx rtr tc qdisc show dev $iface ipx rtr tc filter show dev $iface parent fffe: done } # setup_cake adds cake with the specified args setup_cake() { local cake_args="$1" local iface for iface in rtr.r; do ipx rtr tc qdisc del dev $iface root &>/dev/null ipx rtr tc qdisc add dev $iface root cake bandwidth 50Mbit $cake_args || error ipx rtr tc qdisc show dev $iface done } # run_iperf3 runs iperf3 with a list of args for each instance run_iperf3() { ( local a local n=0 for a in "$@"; do echo iperf3 "$a" ipx cli iperf3 -i 0 -t $DURATION $a > /tmp/chf_iperf_$n.txt & ((n++)) done wait local x=0 for ((x=0; x&2 echo "failed" exit 1 } # teardown cleans up teardown() { ( local p set +e for p in ${IPERF3_PORTS[@]}; do pkill -f "iperf3 -p $p -s -D" done for n in srv rtr cli; do ip netns del $n done ) &> /dev/null } # main trap teardown EXIT setup run teardown