Skip to content

Commit

Permalink
Merge branch 'bpf-xsk-selftests'
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
borkmann committed Dec 9, 2020
2 parents b60da49 + 7d20441 commit 08c6a2f
Show file tree
Hide file tree
Showing 5 changed files with 1,633 additions and 2 deletions.
7 changes: 5 additions & 2 deletions tools/testing/selftests/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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 \
Expand All @@ -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

Expand Down
259 changes: 259 additions & 0 deletions tools/testing/selftests/bpf/test_xsk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright(c) 2020 Intel Corporation, Weqaar Janjua <[email protected]>

# 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
Loading

0 comments on commit 08c6a2f

Please sign in to comment.