diff --git a/scripts/piperf.sh b/scripts/piperf.sh new file mode 100755 index 000000000..db34de952 --- /dev/null +++ b/scripts/piperf.sh @@ -0,0 +1,142 @@ +#!/bin/bash + +# Copyright 2022, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +iperf_count=8 +netdev= +ifaddr= +netns= +base_port=9000 +ptp4l= + +while getopts i:n:p:-: option; do + case "${option}" in + -) + case "${OPTARG}" in + ifaddr) + ifaddr="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 )) + ;; + ifaddr=*) + ifaddr=${OPTARG#*=} + ;; + netns) + netns="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 )) + ;; + netns=*) + netns=${OPTARG#*=} + ;; + ptp4l) + ptp4l=1 + ;; + *) + if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then + echo "Unknown option --${OPTARG}" >&2 + fi + ;; + esac;; + i) netdev=${OPTARG};; + n) iperf_count=${OPTARG};; + p) base_port=${OPTARG};; + esac +done +shift $((OPTIND -1)) + +numa_cmd= +netns_cmd= + +if [ ! -z "$netdev" ]; then + if [ ! -z "$ifaddr" ]; then + if [ -z "$netns" ]; then + netns=$netdev + fi + fi + + if [ ! -x "$(command -v numactl)" ] ; then + echo "numactl not found; cannot bind iperf to netdev NUMA node" >&2 + else + numa_cmd="numactl -l -N netdev:$netdev" + fi +else + if [ ! -z "$ifaddr" ]; then + echo "Interface address specified, but interface name not specified" >&2 + exit -1 + fi +fi + +if [ ! -z "$netns" ]; then + netns_cmd="ip netns exec $netns" + if [ -f "/var/run/netns/$netns" ]; then + echo "Network namespace '$netns' already exists" + else + echo "Creating network namespace '$netns'" + ip netns add $netns + echo "Adding interface '$netdev' to network namespace '$netns'" + ip link set dev $netdev netns $netns + $netns_cmd ip link set dev $netdev up + fi +fi + +if [ ! -z "$ifaddr" ]; then + echo "Adding address '$ifaddr' to '$netdev'" + $netns_cmd ip addr add $ifaddr dev $netdev +fi + +function cleanup() +{ + echo "Cleaning up..." + + # kill all subprocesses + trap '' TERM + pkill -P $$ + + # clean up netns + if [ ! -z "$netns" ]; then + if [ -f "/var/run/netns/$netns" -a -z "$(ip netns pids $netns)" ]; then + echo "Deleting network namespace '$netns'" + ip netns del $netns + fi + fi +} + +trap "exit" INT TERM +trap cleanup EXIT + +# start servers + +for i in $(seq 1 $iperf_count); do + echo Starting iperf3 instance $i on port $(($base_port+i)) + $netns_cmd $numa_cmd iperf3 -p $(($base_port+i)) "$@" & +done + +if [ ! -z $ptp4l ]; then + $netns_cmd ptp4l -i $netdev -m --masterOnly=1 --logSyncInterval=-3 & +fi + +wait