mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-30 15:50:10 -04:00
Merge branch 'bpf-xsk-selftests'
Weqaar Janjua says:
====================
This patch set adds AF_XDP selftests based on veth to selftests/bpf.
# Topology:
# ---------
# -----------
# _ | Process | _
# / ----------- \
# / | \
# / | \
# ----------- | -----------
# | Thread1 | | | Thread2 |
# ----------- | -----------
# | | |
# ----------- | -----------
# | xskX | | | xskY |
# ----------- | -----------
# | | |
# ----------- | ----------
# | vethX | --------- | vethY |
# ----------- peer ----------
# | | |
# namespaceX | namespaceY
These selftests test AF_XDP SKB and Native/DRV modes using veth Virtual
Ethernet interfaces.
The test program contains two threads, each thread is single socket with
a unique UMEM. It validates in-order packet delivery and packet content
by sending packets to each other.
Prerequisites setup by script test_xsk.sh:
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>
* create a spec file veth.spec that includes this run-time configuration
*** xxxx and yyyy are randomly generated 4 digit numbers used to avoid
conflict with any existing interface
Adds xsk framework test to validate veth xdp DRV and SKB modes.
The following tests are provided:
1. AF_XDP SKB mode
Generic mode XDP is driver independent, used when the driver does
not have support for XDP. Works on any netdevice using sockets and
generic XDP path. XDP hook from netif_receive_skb().
a. nopoll - soft-irq processing
b. poll - using poll() syscall
c. Socket Teardown
Create a Tx and a Rx socket, Tx from one socket, Rx on another.
Destroy both sockets, then repeat multiple times. Only nopoll mode
is used
d. Bi-directional Sockets
Configure sockets as bi-directional tx/rx sockets, sets up fill
and completion rings on each socket, tx/rx in both directions.
Only nopoll mode is used
2. AF_XDP DRV/Native mode
Works on any netdevice with XDP_REDIRECT support, driver dependent.
Processes packets before SKB allocation. Provides better performance
than SKB. Driver hook available just after DMA of buffer descriptor.
a. nopoll
b. poll
c. Socket Teardown
d. Bi-directional Sockets
* Only copy mode is supported because veth does not currently support
zero-copy mode
Total tests: 8
Flow:
* Single process spawns two threads: Tx and Rx
* Each of these two threads attach to a veth interface within their
assigned namespaces
* Each thread creates one AF_XDP socket connected to a unique umem
for each veth interface
* Tx thread transmits 10k packets from veth<xxxx> to veth<yyyy>
* Rx thread verifies if all 10k packets were received and delivered
in-order, and have the right content
v2 changes:
* Move selftests/xsk to selftests/bpf
* Remove Makefiles under selftests/xsk, and utilize selftests/bpf/Makefile
v3 changes:
* merge all test scripts test_xsk_*.sh into test_xsk.sh
v4 changes:
* merge xsk_env.sh into xsk_prereqs.sh
* test_xsk.sh add cliarg -c for color-coded output
* test_xsk.sh PREREQUISITES disables IPv6 on veth interfaces
* test_xsk.sh PREREQUISITES adds xsk framework test
* test_xsk.sh is independently executable
* xdpxceiver.c Tx/Rx validates only IPv4 packets with TOS 0x9, ignores
others
====================
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
@@ -46,7 +46,8 @@ endif
|
||||
|
||||
TEST_GEN_FILES =
|
||||
TEST_FILES = test_lwt_ip_encap.o \
|
||||
test_tc_edt.o
|
||||
test_tc_edt.o \
|
||||
xsk_prereqs.sh
|
||||
|
||||
# Order correspond to 'make run_tests' order
|
||||
TEST_PROGS := test_kmod.sh \
|
||||
@@ -70,6 +71,7 @@ TEST_PROGS := test_kmod.sh \
|
||||
test_bpftool_build.sh \
|
||||
test_bpftool.sh \
|
||||
test_bpftool_metadata.sh \
|
||||
test_xsk.sh
|
||||
|
||||
TEST_PROGS_EXTENDED := with_addr.sh \
|
||||
with_tunnels.sh \
|
||||
@@ -80,7 +82,8 @@ TEST_PROGS_EXTENDED := with_addr.sh \
|
||||
# Compile but not part of 'make run_tests'
|
||||
TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \
|
||||
flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \
|
||||
test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko
|
||||
test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \
|
||||
xdpxceiver
|
||||
|
||||
TEST_CUSTOM_PROGS = urandom_read
|
||||
|
||||
|
||||
259
tools/testing/selftests/bpf/test_xsk.sh
Executable file
259
tools/testing/selftests/bpf/test_xsk.sh
Executable file
@@ -0,0 +1,259 @@
|
||||
#!/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>
|
||||
# * create a spec file veth.spec that includes this run-time configuration
|
||||
# *** 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 xdpxceiver.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 (full color-coded output):
|
||||
# sudo ./test_xsk.sh -c
|
||||
#
|
||||
# If running from kselftests:
|
||||
# sudo make colorconsole=1 run_tests
|
||||
#
|
||||
# Run (full output without color-coding):
|
||||
# sudo ./test_xsk.sh
|
||||
|
||||
. xsk_prereqs.sh
|
||||
|
||||
while getopts c flag
|
||||
do
|
||||
case "${flag}" in
|
||||
c) colorconsole=1;;
|
||||
esac
|
||||
done
|
||||
|
||||
TEST_NAME="PREREQUISITES"
|
||||
|
||||
URANDOM=/dev/urandom
|
||||
[ ! -e "${URANDOM}" ] && { echo "${URANDOM} not found. Skipping tests."; test_exit 1 1; }
|
||||
|
||||
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
|
||||
|
||||
setup_vethPairs() {
|
||||
echo "setting up ${VETH0}: namespace: ${NS0}"
|
||||
ip netns add ${NS1}
|
||||
ip link add ${VETH0} type veth peer name ${VETH1}
|
||||
if [ -f /proc/net/if_inet6 ]; then
|
||||
echo 1 > /proc/sys/net/ipv6/conf/${VETH0}/disable_ipv6
|
||||
fi
|
||||
echo "setting up ${VETH1}: namespace: ${NS1}"
|
||||
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 link set ${VETH0} up
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
echo "${VETH0}:${VETH1},${NS1}" > ${SPECFILE}
|
||||
|
||||
validate_veth_spec_file
|
||||
|
||||
echo "Spec file created: ${SPECFILE}"
|
||||
|
||||
test_status $retval "${TEST_NAME}"
|
||||
|
||||
## START TESTS
|
||||
|
||||
statusList=()
|
||||
|
||||
### TEST 1
|
||||
TEST_NAME="XSK KSELFTEST FRAMEWORK"
|
||||
|
||||
echo "Switching interfaces [${VETH0}, ${VETH1}] to XDP Generic mode"
|
||||
vethXDPgeneric ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
retval=$?
|
||||
if [ $retval -eq 0 ]; then
|
||||
echo "Switching interfaces [${VETH0}, ${VETH1}] to XDP Native mode"
|
||||
vethXDPnative ${VETH0} ${VETH1} ${NS1}
|
||||
fi
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
### TEST 2
|
||||
TEST_NAME="SKB NOPOLL"
|
||||
|
||||
vethXDPgeneric ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
params=("-S")
|
||||
execxdpxceiver params
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
### TEST 3
|
||||
TEST_NAME="SKB POLL"
|
||||
|
||||
vethXDPgeneric ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
params=("-S" "-p")
|
||||
execxdpxceiver params
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
### TEST 4
|
||||
TEST_NAME="DRV NOPOLL"
|
||||
|
||||
vethXDPnative ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
params=("-N")
|
||||
execxdpxceiver params
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
### TEST 5
|
||||
TEST_NAME="DRV POLL"
|
||||
|
||||
vethXDPnative ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
params=("-N" "-p")
|
||||
execxdpxceiver params
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
### TEST 6
|
||||
TEST_NAME="SKB SOCKET TEARDOWN"
|
||||
|
||||
vethXDPgeneric ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
params=("-S" "-T")
|
||||
execxdpxceiver params
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
### TEST 7
|
||||
TEST_NAME="DRV SOCKET TEARDOWN"
|
||||
|
||||
vethXDPnative ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
params=("-N" "-T")
|
||||
execxdpxceiver params
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
### TEST 8
|
||||
TEST_NAME="SKB BIDIRECTIONAL SOCKETS"
|
||||
|
||||
vethXDPgeneric ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
params=("-S" "-B")
|
||||
execxdpxceiver params
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
### TEST 9
|
||||
TEST_NAME="DRV BIDIRECTIONAL SOCKETS"
|
||||
|
||||
vethXDPnative ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
params=("-N" "-B")
|
||||
execxdpxceiver params
|
||||
|
||||
retval=$?
|
||||
test_status $retval "${TEST_NAME}"
|
||||
statusList+=($retval)
|
||||
|
||||
## END TESTS
|
||||
|
||||
cleanup_exit ${VETH0} ${VETH1} ${NS1}
|
||||
|
||||
for _status in "${statusList[@]}"
|
||||
do
|
||||
if [ $_status -ne 0 ]; then
|
||||
test_exit $ksft_fail 0
|
||||
fi
|
||||
done
|
||||
|
||||
test_exit $ksft_pass 0
|
||||
1074
tools/testing/selftests/bpf/xdpxceiver.c
Normal file
1074
tools/testing/selftests/bpf/xdpxceiver.c
Normal file
File diff suppressed because it is too large
Load Diff
160
tools/testing/selftests/bpf/xdpxceiver.h
Normal file
160
tools/testing/selftests/bpf/xdpxceiver.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright(c) 2020 Intel Corporation.
|
||||
*/
|
||||
|
||||
#ifndef XDPXCEIVER_H_
|
||||
#define XDPXCEIVER_H_
|
||||
|
||||
#ifndef SOL_XDP
|
||||
#define SOL_XDP 283
|
||||
#endif
|
||||
|
||||
#ifndef AF_XDP
|
||||
#define AF_XDP 44
|
||||
#endif
|
||||
|
||||
#ifndef PF_XDP
|
||||
#define PF_XDP AF_XDP
|
||||
#endif
|
||||
|
||||
#define MAX_INTERFACES 2
|
||||
#define MAX_INTERFACE_NAME_CHARS 7
|
||||
#define MAX_INTERFACES_NAMESPACE_CHARS 10
|
||||
#define MAX_SOCKS 1
|
||||
#define MAX_TEARDOWN_ITER 10
|
||||
#define MAX_BIDI_ITER 2
|
||||
#define PKT_HDR_SIZE (sizeof(struct ethhdr) + sizeof(struct iphdr) + \
|
||||
sizeof(struct udphdr))
|
||||
#define MIN_PKT_SIZE 64
|
||||
#define ETH_FCS_SIZE 4
|
||||
#define PKT_SIZE (MIN_PKT_SIZE - ETH_FCS_SIZE)
|
||||
#define IP_PKT_SIZE (PKT_SIZE - sizeof(struct ethhdr))
|
||||
#define IP_PKT_VER 0x4
|
||||
#define IP_PKT_TOS 0x9
|
||||
#define UDP_PKT_SIZE (IP_PKT_SIZE - sizeof(struct iphdr))
|
||||
#define UDP_PKT_DATA_SIZE (UDP_PKT_SIZE - sizeof(struct udphdr))
|
||||
#define TMOUT_SEC (3)
|
||||
#define EOT (-1)
|
||||
#define USLEEP_MAX 200000
|
||||
#define THREAD_STACK 60000000
|
||||
#define SOCK_RECONF_CTR 10
|
||||
#define BATCH_SIZE 64
|
||||
#define POLL_TMOUT 1000
|
||||
#define NEED_WAKEUP true
|
||||
|
||||
typedef __u32 u32;
|
||||
typedef __u16 u16;
|
||||
typedef __u8 u8;
|
||||
|
||||
enum TESTS {
|
||||
ORDER_CONTENT_VALIDATE_XDP_SKB = 0,
|
||||
ORDER_CONTENT_VALIDATE_XDP_DRV = 1,
|
||||
};
|
||||
|
||||
u8 uut;
|
||||
u8 debug_pkt_dump;
|
||||
u32 num_frames;
|
||||
u8 switching_notify;
|
||||
u8 bidi_pass;
|
||||
|
||||
static u32 opt_xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
|
||||
static int opt_queue;
|
||||
static int opt_pkt_count;
|
||||
static int opt_poll;
|
||||
static int opt_teardown;
|
||||
static int opt_bidi;
|
||||
static u32 opt_xdp_bind_flags = XDP_USE_NEED_WAKEUP;
|
||||
static u8 pkt_data[XSK_UMEM__DEFAULT_FRAME_SIZE];
|
||||
static u32 pkt_counter;
|
||||
static u32 prev_pkt = -1;
|
||||
static int sigvar;
|
||||
|
||||
struct xsk_umem_info {
|
||||
struct xsk_ring_prod fq;
|
||||
struct xsk_ring_cons cq;
|
||||
struct xsk_umem *umem;
|
||||
void *buffer;
|
||||
};
|
||||
|
||||
struct xsk_socket_info {
|
||||
struct xsk_ring_cons rx;
|
||||
struct xsk_ring_prod tx;
|
||||
struct xsk_umem_info *umem;
|
||||
struct xsk_socket *xsk;
|
||||
unsigned long rx_npkts;
|
||||
unsigned long tx_npkts;
|
||||
unsigned long prev_rx_npkts;
|
||||
unsigned long prev_tx_npkts;
|
||||
u32 outstanding_tx;
|
||||
};
|
||||
|
||||
struct flow_vector {
|
||||
enum fvector {
|
||||
tx,
|
||||
rx,
|
||||
bidi,
|
||||
undef,
|
||||
} vector;
|
||||
};
|
||||
|
||||
struct generic_data {
|
||||
u32 seqnum;
|
||||
};
|
||||
|
||||
struct ifaceconfigobj {
|
||||
u8 dst_mac[ETH_ALEN];
|
||||
u8 src_mac[ETH_ALEN];
|
||||
struct in_addr dst_ip;
|
||||
struct in_addr src_ip;
|
||||
u16 src_port;
|
||||
u16 dst_port;
|
||||
} *ifaceconfig;
|
||||
|
||||
struct ifobject {
|
||||
int ifindex;
|
||||
int ifdict_index;
|
||||
char ifname[MAX_INTERFACE_NAME_CHARS];
|
||||
char nsname[MAX_INTERFACES_NAMESPACE_CHARS];
|
||||
struct flow_vector fv;
|
||||
struct xsk_socket_info *xsk;
|
||||
struct xsk_umem_info *umem;
|
||||
u8 dst_mac[ETH_ALEN];
|
||||
u8 src_mac[ETH_ALEN];
|
||||
u32 dst_ip;
|
||||
u32 src_ip;
|
||||
u16 src_port;
|
||||
u16 dst_port;
|
||||
};
|
||||
|
||||
static struct ifobject *ifdict[MAX_INTERFACES];
|
||||
|
||||
/*threads*/
|
||||
atomic_int spinning_tx;
|
||||
atomic_int spinning_rx;
|
||||
pthread_mutex_t sync_mutex;
|
||||
pthread_mutex_t sync_mutex_tx;
|
||||
pthread_cond_t signal_rx_condition;
|
||||
pthread_cond_t signal_tx_condition;
|
||||
pthread_t t0, t1, ns_thread;
|
||||
pthread_attr_t attr;
|
||||
|
||||
struct targs {
|
||||
bool retptr;
|
||||
int idx;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(head_s, pkt) head = TAILQ_HEAD_INITIALIZER(head);
|
||||
struct head_s *head_p;
|
||||
struct pkt {
|
||||
char *pkt_frame;
|
||||
|
||||
TAILQ_ENTRY(pkt) pkt_nodes;
|
||||
} *pkt_node_rx, *pkt_node_rx_q;
|
||||
|
||||
struct pkt_frame {
|
||||
char *payload;
|
||||
} *pkt_obj;
|
||||
|
||||
struct pkt_frame **pkt_buf;
|
||||
|
||||
#endif /* XDPXCEIVER_H */
|
||||
135
tools/testing/selftests/bpf/xsk_prereqs.sh
Executable file
135
tools/testing/selftests/bpf/xsk_prereqs.sh
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright(c) 2020 Intel Corporation.
|
||||
|
||||
ksft_pass=0
|
||||
ksft_fail=1
|
||||
ksft_xfail=2
|
||||
ksft_xpass=3
|
||||
ksft_skip=4
|
||||
|
||||
GREEN='\033[0;92m'
|
||||
YELLOW='\033[0;93m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
STACK_LIM=131072
|
||||
SPECFILE=veth.spec
|
||||
XSKOBJ=xdpxceiver
|
||||
NUMPKTS=10000
|
||||
|
||||
validate_root_exec()
|
||||
{
|
||||
msg="skip all tests:"
|
||||
if [ $UID != 0 ]; then
|
||||
echo $msg must be run as root >&2
|
||||
test_exit $ksft_fail 2
|
||||
else
|
||||
return $ksft_pass
|
||||
fi
|
||||
}
|
||||
|
||||
validate_veth_support()
|
||||
{
|
||||
msg="skip all tests:"
|
||||
if [ $(ip link add $1 type veth 2>/dev/null; echo $?;) != 0 ]; then
|
||||
echo $msg veth kernel support not available >&2
|
||||
test_exit $ksft_skip 1
|
||||
else
|
||||
ip link del $1
|
||||
return $ksft_pass
|
||||
fi
|
||||
}
|
||||
|
||||
validate_veth_spec_file()
|
||||
{
|
||||
if [ ! -f ${SPECFILE} ]; then
|
||||
test_exit $ksft_skip 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_status()
|
||||
{
|
||||
statusval=$1
|
||||
if [ -n "${colorconsole+set}" ]; then
|
||||
if [ $statusval -eq 2 ]; then
|
||||
echo -e "${YELLOW}$2${NC}: [ ${RED}FAIL${NC} ]"
|
||||
elif [ $statusval -eq 1 ]; then
|
||||
echo -e "${YELLOW}$2${NC}: [ ${RED}SKIPPED${NC} ]"
|
||||
elif [ $statusval -eq 0 ]; then
|
||||
echo -e "${YELLOW}$2${NC}: [ ${GREEN}PASS${NC} ]"
|
||||
fi
|
||||
else
|
||||
if [ $statusval -eq 2 ]; then
|
||||
echo -e "$2: [ FAIL ]"
|
||||
elif [ $statusval -eq 1 ]; then
|
||||
echo -e "$2: [ SKIPPED ]"
|
||||
elif [ $statusval -eq 0 ]; then
|
||||
echo -e "$2: [ PASS ]"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
test_exit()
|
||||
{
|
||||
retval=$1
|
||||
if [ $2 -ne 0 ]; then
|
||||
test_status $2 $(basename $0)
|
||||
fi
|
||||
exit $retval
|
||||
}
|
||||
|
||||
clear_configs()
|
||||
{
|
||||
if [ $(ip netns show | grep $3 &>/dev/null; echo $?;) == 0 ]; then
|
||||
[ $(ip netns exec $3 ip link show $2 &>/dev/null; echo $?;) == 0 ] &&
|
||||
{ echo "removing link $1:$2"; ip netns exec $3 ip link del $2; }
|
||||
echo "removing ns $3"
|
||||
ip netns del $3
|
||||
fi
|
||||
#Once we delete a veth pair node, the entire veth pair is removed,
|
||||
#this is just to be cautious just incase the NS does not exist then
|
||||
#veth node inside NS won't get removed so we explicitly remove it
|
||||
[ $(ip link show $1 &>/dev/null; echo $?;) == 0 ] &&
|
||||
{ echo "removing link $1"; ip link del $1; }
|
||||
if [ -f ${SPECFILE} ]; then
|
||||
echo "removing spec file:" ${SPECFILE}
|
||||
rm -f ${SPECFILE}
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_exit()
|
||||
{
|
||||
echo "cleaning up..."
|
||||
clear_configs $1 $2 $3
|
||||
}
|
||||
|
||||
validate_ip_utility()
|
||||
{
|
||||
[ ! $(type -P ip) ] && { echo "'ip' not found. Skipping tests."; test_exit $ksft_skip 1; }
|
||||
}
|
||||
|
||||
vethXDPgeneric()
|
||||
{
|
||||
ip link set dev $1 xdpdrv off
|
||||
ip netns exec $3 ip link set dev $2 xdpdrv off
|
||||
}
|
||||
|
||||
vethXDPnative()
|
||||
{
|
||||
ip link set dev $1 xdpgeneric off
|
||||
ip netns exec $3 ip link set dev $2 xdpgeneric off
|
||||
}
|
||||
|
||||
execxdpxceiver()
|
||||
{
|
||||
local -a 'paramkeys=("${!'"$1"'[@]}")' copy
|
||||
paramkeysstr=${paramkeys[*]}
|
||||
|
||||
for index in $paramkeysstr;
|
||||
do
|
||||
current=$1"[$index]"
|
||||
copy[$index]=${!current}
|
||||
done
|
||||
|
||||
./${XSKOBJ} -i ${VETH0} -i ${VETH1},${NS1} ${copy[*]} -C ${NUMPKTS}
|
||||
}
|
||||
Reference in New Issue
Block a user