mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-26 04:25:27 +08:00
a693ff3ed5
Currently, architecture of xdpxceiver is designed strictly for conducting veth based tests. Veth pair is created together with a network namespace and one of the veth interfaces is moved to the mentioned netns. Then, separate threads for Tx and Rx are spawned which will utilize described setup. Infrastructure described in the paragraph above can not be used for testing AF_XDP support on physical devices. That testing will be conducted on a single network interface and same queue. Xskxceiver needs to be extended to distinguish between veth tests and physical interface tests. Since same iface/queue id pair will be used by both Tx/Rx threads for physical device testing, Tx thread, which happen to run after the Rx thread, is going to create XSK socket with shared umem flag. In order to track this setting throughout the lifetime of spawned threads, introduce 'shared_umem' boolean variable to struct ifobject and set it to true when xdpxceiver is run against physical device. In such case, UMEM size needs to be doubled, so half of it will be used by Rx thread and other half by Tx thread. For two step based test types, value of XSKMAP element under key 0 has to be updated as there is now another socket for the second step. Also, to avoid race conditions when destroying XSK resources, move this activity to the main thread after spawned Rx and Tx threads have finished its job. This way it is possible to gracefully remove shared umem without introducing synchronization mechanisms. To run xsk selftests suite on physical device, append "-i $IFACE" when invoking test_xsk.sh. For veth based tests, simply skip it. When "-i $IFACE" is in place, under the hood test_xsk.sh will use $IFACE for both interfaces supplied to xdpxceiver, which in turn will interpret that this execution of test suite is for a physical device. Note that currently this makes it possible only to test SKB and DRV mode (in case underlying device has native XDP support). ZC testing support is added in a later patch. Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Magnus Karlsson <magnus.karlsson@intel.com> Link: https://lore.kernel.org/bpf/20220901114813.16275-5-maciej.fijalkowski@intel.com
209 lines
4.9 KiB
Bash
Executable File
209 lines
4.9 KiB
Bash
Executable File
#!/bin/bash
|
||
# SPDX-License-Identifier: GPL-2.0
|
||
# Copyright(c) 2020 Intel Corporation, Weqaar Janjua <weqaar.a.janjua@intel.com>
|
||
|
||
# AF_XDP selftests based on veth
|
||
#
|
||
# End-to-end AF_XDP over Veth test
|
||
#
|
||
# Topology:
|
||
# ---------
|
||
# -----------
|
||
# _ | Process | _
|
||
# / ----------- \
|
||
# / | \
|
||
# / | \
|
||
# ----------- | -----------
|
||
# | Thread1 | | | Thread2 |
|
||
# ----------- | -----------
|
||
# | | |
|
||
# ----------- | -----------
|
||
# | xskX | | | xskY |
|
||
# ----------- | -----------
|
||
# | | |
|
||
# ----------- | ----------
|
||
# | vethX | --------- | vethY |
|
||
# ----------- peer ----------
|
||
# | | |
|
||
# namespaceX | namespaceY
|
||
#
|
||
# AF_XDP is an address family optimized for high performance packet processing,
|
||
# it is XDP’s user-space interface.
|
||
#
|
||
# An AF_XDP socket is linked to a single UMEM which is a region of virtual
|
||
# contiguous memory, divided into equal-sized frames.
|
||
#
|
||
# Refer to AF_XDP Kernel Documentation for detailed information:
|
||
# https://www.kernel.org/doc/html/latest/networking/af_xdp.html
|
||
#
|
||
# Prerequisites setup by script:
|
||
#
|
||
# Set up veth interfaces as per the topology shown ^^:
|
||
# * setup two veth interfaces and one namespace
|
||
# ** veth<xxxx> in root namespace
|
||
# ** veth<yyyy> in af_xdp<xxxx> namespace
|
||
# ** namespace af_xdp<xxxx>
|
||
# *** xxxx and yyyy are randomly generated 4 digit numbers used to avoid
|
||
# conflict with any existing interface
|
||
# * tests the veth and xsk layers of the topology
|
||
#
|
||
# See the source xskxceiver.c for information on each test
|
||
#
|
||
# Kernel configuration:
|
||
# ---------------------
|
||
# See "config" file for recommended kernel config options.
|
||
#
|
||
# Turn on XDP sockets and veth support when compiling i.e.
|
||
# Networking support -->
|
||
# Networking options -->
|
||
# [ * ] XDP sockets
|
||
#
|
||
# Executing Tests:
|
||
# ----------------
|
||
# Must run with CAP_NET_ADMIN capability.
|
||
#
|
||
# Run:
|
||
# sudo ./test_xsk.sh
|
||
#
|
||
# If running from kselftests:
|
||
# sudo make run_tests
|
||
#
|
||
# Run with verbose output:
|
||
# sudo ./test_xsk.sh -v
|
||
#
|
||
# Run and dump packet contents:
|
||
# sudo ./test_xsk.sh -D
|
||
#
|
||
# Run test suite for physical device in loopback mode
|
||
# sudo ./test_xsk.sh -i IFACE
|
||
|
||
. xsk_prereqs.sh
|
||
|
||
ETH=""
|
||
|
||
while getopts "vDi:" flag
|
||
do
|
||
case "${flag}" in
|
||
v) verbose=1;;
|
||
D) dump_pkts=1;;
|
||
i) ETH=${OPTARG};;
|
||
esac
|
||
done
|
||
|
||
TEST_NAME="PREREQUISITES"
|
||
|
||
URANDOM=/dev/urandom
|
||
[ ! -e "${URANDOM}" ] && { echo "${URANDOM} not found. Skipping tests."; test_exit $ksft_fail; }
|
||
|
||
VETH0_POSTFIX=$(cat ${URANDOM} | tr -dc '0-9' | fold -w 256 | head -n 1 | head --bytes 4)
|
||
VETH0=ve${VETH0_POSTFIX}
|
||
VETH1_POSTFIX=$(cat ${URANDOM} | tr -dc '0-9' | fold -w 256 | head -n 1 | head --bytes 4)
|
||
VETH1=ve${VETH1_POSTFIX}
|
||
NS0=root
|
||
NS1=af_xdp${VETH1_POSTFIX}
|
||
MTU=1500
|
||
|
||
trap ctrl_c INT
|
||
|
||
function ctrl_c() {
|
||
cleanup_exit ${VETH0} ${VETH1} ${NS1}
|
||
exit 1
|
||
}
|
||
|
||
setup_vethPairs() {
|
||
if [[ $verbose -eq 1 ]]; then
|
||
echo "setting up ${VETH0}: namespace: ${NS0}"
|
||
fi
|
||
ip netns add ${NS1}
|
||
ip link add ${VETH0} numtxqueues 4 numrxqueues 4 type veth peer name ${VETH1} numtxqueues 4 numrxqueues 4
|
||
if [ -f /proc/net/if_inet6 ]; then
|
||
echo 1 > /proc/sys/net/ipv6/conf/${VETH0}/disable_ipv6
|
||
fi
|
||
if [[ $verbose -eq 1 ]]; then
|
||
echo "setting up ${VETH1}: namespace: ${NS1}"
|
||
fi
|
||
|
||
if [[ $busy_poll -eq 1 ]]; then
|
||
echo 2 > /sys/class/net/${VETH0}/napi_defer_hard_irqs
|
||
echo 200000 > /sys/class/net/${VETH0}/gro_flush_timeout
|
||
echo 2 > /sys/class/net/${VETH1}/napi_defer_hard_irqs
|
||
echo 200000 > /sys/class/net/${VETH1}/gro_flush_timeout
|
||
fi
|
||
|
||
ip link set ${VETH1} netns ${NS1}
|
||
ip netns exec ${NS1} ip link set ${VETH1} mtu ${MTU}
|
||
ip link set ${VETH0} mtu ${MTU}
|
||
ip netns exec ${NS1} ip link set ${VETH1} up
|
||
ip netns exec ${NS1} ip link set dev lo up
|
||
ip link set ${VETH0} up
|
||
}
|
||
|
||
if [ ! -z $ETH ]; then
|
||
VETH0=${ETH}
|
||
VETH1=${ETH}
|
||
NS1=""
|
||
else
|
||
validate_root_exec
|
||
validate_veth_support ${VETH0}
|
||
validate_ip_utility
|
||
setup_vethPairs
|
||
|
||
retval=$?
|
||
if [ $retval -ne 0 ]; then
|
||
test_status $retval "${TEST_NAME}"
|
||
cleanup_exit ${VETH0} ${VETH1} ${NS1}
|
||
exit $retval
|
||
fi
|
||
fi
|
||
|
||
|
||
if [[ $verbose -eq 1 ]]; then
|
||
ARGS+="-v "
|
||
fi
|
||
|
||
if [[ $dump_pkts -eq 1 ]]; then
|
||
ARGS="-D "
|
||
fi
|
||
|
||
retval=$?
|
||
test_status $retval "${TEST_NAME}"
|
||
|
||
## START TESTS
|
||
|
||
statusList=()
|
||
|
||
TEST_NAME="XSK_SELFTESTS_${VETH0}_SOFTIRQ"
|
||
|
||
exec_xskxceiver
|
||
|
||
if [ -z $ETH ]; then
|
||
cleanup_exit ${VETH0} ${VETH1} ${NS1}
|
||
fi
|
||
TEST_NAME="XSK_SELFTESTS_${VETH0}_BUSY_POLL"
|
||
busy_poll=1
|
||
|
||
if [ -z $ETH ]; then
|
||
setup_vethPairs
|
||
fi
|
||
exec_xskxceiver
|
||
|
||
## END TESTS
|
||
|
||
if [ -z $ETH ]; then
|
||
cleanup_exit ${VETH0} ${VETH1} ${NS1}
|
||
fi
|
||
|
||
failures=0
|
||
echo -e "\nSummary:"
|
||
for i in "${!statusList[@]}"
|
||
do
|
||
if [ ${statusList[$i]} -ne 0 ]; then
|
||
test_status ${statusList[$i]} ${nameList[$i]}
|
||
failures=1
|
||
fi
|
||
done
|
||
|
||
if [ $failures -eq 0 ]; then
|
||
echo "All tests successful!"
|
||
fi
|