From 21121578422385ed975f9724475ff17c133dc4ff Mon Sep 17 00:00:00 2001 From: Mariusz Drost Date: Fri, 25 Oct 2019 13:55:38 +0100 Subject: l4p/tcp_ofo: Tests for ofo and loss of pkts Tests for packets that are out of order and lost. They validate data send over netcat (TCP) to TLDK/l4fwd app in echo mode. Data is set to be reordered or loss some percentage of packets. Signed-off-by: Mariusz Drost Change-Id: I68f80d1fb75d5e9e5ed6d052ddcdc60588284f78 --- examples/l4fwd/test/config.sh | 444 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 444 insertions(+) create mode 100644 examples/l4fwd/test/config.sh (limited to 'examples/l4fwd/test/config.sh') diff --git a/examples/l4fwd/test/config.sh b/examples/l4fwd/test/config.sh new file mode 100644 index 0000000..5932936 --- /dev/null +++ b/examples/l4fwd/test/config.sh @@ -0,0 +1,444 @@ +#! /bin/bash + +# hardcoded variables which can be changed by the user if needed--------------- + +# DPDK port to be used +DPDK_PORT=0 + +# TCP port to be used +TCP_PORT=6000 + +# local interface addresses to set +LOCAL_IPV4=192.168.1.60 +LOCAL_IPV6=fd12:3456:789a:0001:0000:0000:0000:0060 + +# remote interface addresses to set +REMOTE_IPV4=192.168.1.64 +REMOTE_IPV6=fd12:3456:789a:0001:0000:0000:0000:0064 + +# mask length for addresses of each IP version +MASK_IPV4=24 +MASK_IPV6=64 + +# name of the config files for backend and frontend of l4fwd app +L4FWD_BE_CFG_FILE=$(mktemp) +L4FWD_FE_CFG_FILE=$(mktemp) + +# directory on remote to store tmp files - default /tmp/ +REMOTE_DIR=/tmp/l4fwd_test +# directory on remote to store output files +REMOTE_OUTDIR=${REMOTE_DIR}/out +# directory on remote to store results +REMOTE_RESDIR=${REMOTE_DIR}/results + +# checks done on environment variables----------------------------------------- + +# check ETH_DEV +if [[ -z "${ETH_DEV}" ]] +then + echo "ETH_DEV is invalid" + exit 127 +fi + +# check if L4FWD_PATH points to an executable +if [[ ! -x ${L4FWD_PATH} ]] +then + echo "${L4FWD_PATH} is not executable" + exit 127 +fi + +# check if REMOTE_HOST is reachable +ssh ${REMOTE_HOST} echo +st=$? +if [[ $st -ne 0 ]] +then + echo "host ${REMOTE_HOST} is not reachable" + exit $st +fi + +# get ethernet address of REMOTE_HOST +REMOTE_MAC=$(ssh ${REMOTE_HOST} ip addr show dev ${REMOTE_IFACE}) +st=$? +REMOTE_MAC=$(echo ${REMOTE_MAC} | sed -e 's/^.*ether //' -e 's/ brd.*$//') +if [[ $st -ne 0 || -z "${REMOTE_MAC}" ]] +then + echo "could not retrive ethernet address from ${REMOTE_IFACE}" + exit 127 +fi + +# check if FECORE is set - default 0 +L4FWD_FECORE=${L4FWD_FECORE:-0} + +# check if BECORE is set - default FECORE +L4FWD_BECORE=${L4FWD_BECORE:-${L4FWD_FECORE}} + +# l4fwd app settings----------------------------------------------------------- + +# set file for l4fwd app output +L4FWD_OUT_FILE=./l4fwd.out +# set rbufs/sbufs/streams to open for l4fwd +L4FWD_STREAMS='--rbufs 0x100 --sbufs 0x100 --streams 0x100' + +# set lcores for DPDK to start +if [[ ${L4FWD_FECORE} -ne ${L4FWD_BECORE} ]] +then + L4FWD_LCORE="${L4FWD_FECORE},${L4FWD_BECORE}" +else + L4FWD_LCORE="${L4FWD_FECORE}" +fi + +# set EAL parameters +L4FWD_CMD_EAL_PRM="--lcores='${L4FWD_LCORE}' -n 4 ${ETH_DEV}" + +# l4fwd parameters (listen, TCP only, enable arp, promiscuous) +L4FWD_CMD_PRM="--listen --tcp --enable-arp --promisc ${L4FWD_STREAMS}" + +# l4fwd config files +L4FWD_CONFIG="--fecfg ${L4FWD_FE_CFG_FILE} --becfg ${L4FWD_BE_CFG_FILE}" + +# port parameters +if [[ ${ipv4} -eq 1 ]] +then + L4FWD_PORT_PRM="port=${DPDK_PORT},lcore=${L4FWD_BECORE},rx_offload=0x0\ +,tx_offload=0x0,ipv4=${LOCAL_IPV4}" +elif [[ ${ipv6} -eq 1 ]] +then + L4FWD_PORT_PRM="port=${DPDK_PORT},lcore=${L4FWD_BECORE},rx_offload=0x0\ +,tx_offload=0x0,ipv6=${LOCAL_IPV6}" +fi + +# other variables-------------------------------------------------------------- + +# check if directories on remote are set, if not make one +ssh ${REMOTE_HOST} mkdir -p {${REMOTE_OUTDIR},${REMOTE_RESDIR}} + +# instruction to set +netem="ssh ${REMOTE_HOST} tc qdisc add dev ${REMOTE_IFACE} \ +root netem limit 100000" + +# setting for scp which suppresses output of scp when not in verbose mode +if [[ ${verbose} -eq 1 ]] +then + scp_suppress="" +else + scp_suppress="-q" +fi + +# setting for dd which suppresses output of dd when not in verbose mode +if [[ ${verbose} -eq 1 ]] +then + dd_suppress="" +else + dd_suppress="status=none" +fi + +# set address to use by netcat +if [[ ${ipv4} -eq 1 ]] +then + nc_addr=${LOCAL_IPV4} +elif [[ ${ipv6} -eq 1 ]] +then + nc_addr=${LOCAL_IPV6} +fi + +let "ipv4_elem=(${MASK_IPV4}/8)" +let "ipv6_elem=(${MASK_IPV6}/16)" +let "ipv4_elem_rev=4-${ipv4_elem}" + +ipv4_append="" +while [[ ${ipv4_elem_rev} -ne 0 ]]; do + ipv4_append="${ipv4_append}.0" + let "ipv4_elem_rev=${ipv4_elem_rev}-1" +done + +ipv4_network=$(echo ${REMOTE_IPV4} | cut -d. -f-${ipv4_elem} | \ + sed 's#.*#&'"${ipv4_append}"'#') +ipv6_network=$(echo ${REMOTE_IPV6} | cut -d: -f-${ipv6_elem} | sed 's#.*#&::#') + +# helper functions------------------------------------------------------------- + +# function to check if verbose is set and run command if yes +if_verbose() +{ + if [[ ${verbose} -eq 1 ]] + then + $@ + fi +} + +# update results file +update_results() +{ + file=$1 + status=$2 + it=$3 + + # get only 'real' time in results file + $(ssh ${REMOTE_HOST} "awk '/real/{print \$2}' \ + ${REMOTE_RESDIR}/${file}.result.${it} \ + >> ${REMOTE_RESDIR}/results.out") + + # add file and status of test to results + if [[ ${status} -ne 0 ]] + then + $(ssh ${REMOTE_HOST} "sed -i '$ s_.*_[FAIL]\t&_' \ + ${REMOTE_RESDIR}/results.out") + else + $(ssh ${REMOTE_HOST} "sed -i '$ s_.*_[OK]\t&_' \ + ${REMOTE_RESDIR}/results.out") + fi + + length=$(expr length "${file}") + if [[ ${length} -lt 16 ]] + then + tab="\t\t" + else + tab="\t" + fi + + $(ssh ${REMOTE_HOST} "sed -i '$ s_.*_${file}${tab}&_' \ + ${REMOTE_RESDIR}/results.out") +} + +# start l4fwd app +l4fwd_start() +{ + # create temporary file for command running l4fwd + L4FWD_EXEC_FILE=$(mktemp) + + # store run command + cat << EOF > ${L4FWD_EXEC_FILE} +stdbuf -o0 ${L4FWD_PATH} ${L4FWD_CMD_EAL_PRM} -- ${L4FWD_CMD_PRM} \ +${L4FWD_CONFIG} ${L4FWD_PORT_PRM} > ${L4FWD_OUT_FILE} 2>&1 & +echo \$! +EOF + + # visual break + if_verbose echo -e "\nApp l4fwd started with command:" + if_verbose cat ${L4FWD_EXEC_FILE} + if_verbose echo "" + + # run l4fwd app and get process ID of it + L4FWD_PID=$(/bin/bash ${L4FWD_EXEC_FILE}) + + # wait 2s and check if l4fwd is still running (parsing and init OK) + sleep 2 + if [[ ${L4FWD_PID} -ne $(pgrep -o l4fwd) ]] + then + echo "ERROR: l4fwd app have crashed during initialization" + rm -f ${L4FWD_EXEC_FILE} + exit 127 + fi +} + +# stop l4fwd app +l4fwd_stop() +{ + # kill runnning l4fwd app + kill ${L4FWD_PID} + + # remove temporary files + rm -f ${L4FWD_EXEC_FILE} + rm -f ${L4FWD_FE_CFG_FILE} + rm -f ${L4FWD_BE_CFG_FILE} +} + +# helper function to set netem on remote +setup_netem() +{ + # remove netem settings from remote interface if any + check_netem=$(ssh ${REMOTE_HOST} "tc qdisc show dev \ + ${REMOTE_IFACE} | grep netem") + if [[ -n ${check_netem} ]] + then + ssh ${REMOTE_HOST} tc qdisc del dev ${REMOTE_IFACE} root + fi + + # set default delay for reorder + if [[ ${reorder} -ne 0 && ${delay} -eq 0 ]] + then + delay=20 + fi + + # set appropriate delay/loss/reorder if specified + if [[ ${delay} -ne 0 ]] + then + netem="${netem} delay ${delay}ms" + fi + + if [[ ${loss} -ne 0 ]] + then + # calculate parameters for Simplified Gilbert model + loss_to_set=$(( $(( ${loss} * ${loss_burst} )) \ +/ $(( 100 - ${loss} )) )) + + if [[ ${loss_to_set} -gt 100 ]] + then + loss_to_set=100 + fi + netem="${netem} loss gemodel ${loss_to_set}% ${loss_burst}%" + fi + + if [[ ${reorder} -ne 0 ]] + then + netem="${netem} reorder 100% gap ${reorder}" + fi + + # set netem on remote + ${netem} + + # visual break of the output + if_verbose echo -e "\nNetwork rules on remote set to:" + + # print current netem settings + if_verbose ssh ${REMOTE_HOST} tc qdisc show dev ${REMOTE_IFACE} +} + +# configure IPv4 remote machine +configure_ip4_remote() +{ + # visual break of the output + if_verbose echo "Setting interface on remote" + + # set remote interface with correct IP address + ssh ${REMOTE_HOST} ip link set ${REMOTE_IFACE} down + ssh ${REMOTE_HOST} ip addr flush dev ${REMOTE_IFACE} + ssh ${REMOTE_HOST} ip addr add ${REMOTE_IPV4}/${MASK_IPV4} \ + dev ${REMOTE_IFACE} + ssh ${REMOTE_HOST} ip link set ${REMOTE_IFACE} up + if_verbose ssh ${REMOTE_HOST} ip addr show dev ${REMOTE_IFACE} + + ssh ${REMOTE_HOST} ip neigh flush dev ${REMOTE_IFACE} + ssh ${REMOTE_HOST} iptables --flush + + ssh ${REMOTE_HOST} ip route change ${ipv4_network}/${MASK_IPV4} dev \ + ${REMOTE_IFACE} rto_min 30ms + + # construct instruction + if [[ set_netem -eq 1 ]] + then + setup_netem + fi + + # give linux 1 sec to handle all network settings + sleep 1 +} + +# configure IPv6 remote machine +configure_ip6_remote() +{ + # visual break of the output + if_verbose echo "Setting interface on remote" + + # set remote interface with correct IP address + ssh ${REMOTE_HOST} ip link set ${REMOTE_IFACE} down + ssh ${REMOTE_HOST} sysctl -q -w \ + net.ipv6.conf.${REMOTE_IFACE}.disable_ipv6=0 + ssh ${REMOTE_HOST} ip addr flush dev ${REMOTE_IFACE} + ssh ${REMOTE_HOST} ip -6 addr add ${REMOTE_IPV6}/${MASK_IPV6} \ + dev ${REMOTE_IFACE} + ssh ${REMOTE_HOST} ip -6 link set ${REMOTE_IFACE} up + if_verbose ssh ${REMOTE_HOST} ip addr show dev ${REMOTE_IFACE} + + ssh ${REMOTE_HOST} ip neigh flush dev ${REMOTE_IFACE} + ssh ${REMOTE_HOST} ip -6 neigh add ${LOCAL_IPV6} dev ${REMOTE_IFACE} \ + lladdr ${LOCAL_MAC} + ssh ${REMOTE_HOST} iptables --flush + ssh ${REMOTE_HOST} ip6tables --flush + + ssh ${REMOTE_HOST} ip route change ${ipv6_network}/${MASK_IPV6} dev \ + ${REMOTE_IFACE} proto kernel metric 256 rto_min 30ms + + ssh ${REMOTE_HOST} ip -6 route show + + # construct instruction + if [[ set_netem -eq 1 ]] + then + setup_netem + fi + + # give linux 1 sec to handle all network settings + sleep 1 +} + +# configure remote +configure_remote() +{ + # call proper configuration + if [[ ${ipv4} -eq 1 ]] + then + configure_ip4_remote + + if_verbose echo -e "\nBE configuration:" + config4_be + + if_verbose echo -e "\nFE configuration:" + config4_fe + elif [[ ${ipv6} -eq 1 ]] + then + configure_ip6_remote + + if_verbose echo -e "\nBE configuration:" + config6_be + + if_verbose echo -e "\nFE configuration:" + config6_fe + fi + + # create empty results file on remote + $(ssh ${REMOTE_HOST} "> ${REMOTE_RESDIR}/results.out") +} + +# restore netem settings to default +restore_netem() +{ + if [[ ${set_netem} -eq 1 ]] + then + ssh ${REMOTE_HOST} tc qdisc del dev ${REMOTE_IFACE} root + fi +} + +# remove created directories after test is done +remove_directories() +{ + ssh ${REMOTE_HOST} rm -fr ${REMOTE_DIR} +} + +# configuration of be/fe config------------------------------------------------ +config4_be() +{ + cat < ${L4FWD_BE_CFG_FILE} +port=${DPDK_PORT},masklen=${MASK_IPV4},addr=${REMOTE_IPV4},mac=${REMOTE_MAC} +EOF + + if_verbose cat ${L4FWD_BE_CFG_FILE} +} + +config6_be() +{ + cat < ${L4FWD_BE_CFG_FILE} +port=${DPDK_PORT},masklen=${MASK_IPV6},addr=${REMOTE_IPV6},mac=${REMOTE_MAC} +EOF + + if_verbose cat ${L4FWD_BE_CFG_FILE} +} + +config4_fe() +{ + cat < ${L4FWD_FE_CFG_FILE} +lcore=${L4FWD_FECORE},belcore=${L4FWD_BECORE},op=echo,laddr=${LOCAL_IPV4}\ +,lport=${TCP_PORT},raddr=${REMOTE_IPV4},rport=0 +EOF + + if_verbose cat ${L4FWD_FE_CFG_FILE} +} + +config6_fe() +{ + cat < ${L4FWD_FE_CFG_FILE} +lcore=${L4FWD_FECORE},belcore=${L4FWD_BECORE},op=echo,laddr=${LOCAL_IPV6}\ +,lport=${TCP_PORT},raddr=${REMOTE_IPV6},rport=0 +EOF + + if_verbose cat ${L4FWD_FE_CFG_FILE} +} -- cgit 1.2.3-korg