@@ -15768,6 +15768,7 @@ M: Breno Leitao <leitao@debian.org>
S: Maintained
F: Documentation/networking/netconsole.rst
F: drivers/net/netconsole.c
+F: tools/testing/selftests/net/netconsole/
NETDEVSIM
M: Jakub Kicinski <kuba@kernel.org>
new file mode 100755
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0
+
+# This test creates two virtual interfaces, assigns one of them (the "destination
+# interface") to a new namespace, and assigns IP addresses to both interfaces.
+#
+# It listens on the destination interface using netcat (nc) and configures a
+# dynamic target on netconsole, pointing to the destination IP address.
+#
+# Finally, it checks whether the message was received properly on the
+# destination interface. Note that this test may pollute the kernel log buffer
+# (dmesg) and relies on dynamic configuration and namespaces being configured."
+#
+# Author: Breno Leitao <leitao@debian.org>
+
+SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
+
+# Simple script to test dynamic targets in netconsole
+SRCIF="veth0"
+SRCIP=192.168.1.1
+
+DSTIF="veth1"
+DSTIP=192.168.1.2
+
+PORT="6666"
+MSG="netconsole selftest"
+TARGET=$(mktemp -u netcons_XXXXX)
+NETCONS_CONFIGFS="/sys/kernel/config/netconsole"
+FULLPATH="${NETCONS_CONFIGFS}"/"${TARGET}"
+# This will be have some tmp values appened to it in set_network()
+NAMESPACE="netconsns"
+
+# Used to create and delete namespaces
+source "${SCRIPTDIR}"/../lib.sh
+
+function set_network() {
+ # this is coming from lib.sh
+ setup_ns "${NAMESPACE}"
+ NAMESPACE=${NS_LIST[0]}
+ ip link add "${SRCIF}" type veth peer name "${DSTIF}"
+
+ # "${DSTIF}"
+ ip link set "${DSTIF}" netns "${NAMESPACE}"
+ ip netns exec "${NAMESPACE}" ip addr add "${DSTIP}"/24 dev "${DSTIF}"
+ ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" up
+
+ # later, configure "${SRCIF}"
+ ip addr add "${SRCIP}"/24 dev "${SRCIF}"
+ ip link set "${SRCIF}" up
+}
+
+function create_dynamic_target() {
+ DSTMAC=$(ip netns exec "${NAMESPACE}" ip link show "${DSTIF}" | awk '/ether/ {print $2}')
+
+ # Create a dynamic target
+ mkdir ${FULLPATH}
+
+ echo ${DSTIP} > ${FULLPATH}/remote_ip
+ echo ${SRCIP} > ${FULLPATH}/local_ip
+ echo ${DSTMAC} > ${FULLPATH}/remote_mac
+ echo "${SRCIF}" > ${FULLPATH}/dev_name
+
+ echo 1 > ${FULLPATH}/enabled
+}
+
+function cleanup() {
+ echo 0 > "${FULLPATH}"/enabled
+ rmdir "${FULLPATH}"
+ # This will delete DSTIF also
+ ip link del "${SRCIF}"
+ # this is coming from lib.sh
+ cleanup_all_ns
+}
+
+function listen_port() {
+ OUTPUT=${1}
+ echo "Saving content in ${OUTPUT}"
+ timeout 2 ip netns exec "${NAMESPACE}" nc -u -l "${PORT}" | sed '/^$/q' > ${OUTPUT}
+}
+
+function validate_result() {
+ TMPFILENAME=/tmp/"${TARGET}"
+
+ # sleep until the file isc reated
+ sleep 1
+ # Check if the file exists
+ if [ ! -f "$TMPFILENAME" ]; then
+ echo "FAIL: File was not generate." >&2
+ return ${ksft_fail}
+ fi
+
+ if ! grep -q "${MSG}" "${TMPFILENAME}"; then
+ echo "FAIL: ${MSG} not found in ${TMPFILENAME}" >&2
+ cat ${TMPFILENAME} >&2
+ return ${ksft_fail}
+ fi
+
+ rm ${TMPFILENAME}
+ return ${ksft_pass}
+}
+
+function check_for_dependencies() {
+ if [ "$(id -u)" -ne 0 ]; then
+ echo "This script must be run as root" >&2
+ exit 1
+ fi
+
+ if ! which nc > /dev/null ; then
+ echo "SKIP: nc(1) is not available" >&2
+ exit ${ksft_skip}
+ fi
+
+ if ! which ip > /dev/null ; then
+ echo "SKIP: ip(1) is not available" >&2
+ exit ${ksft_skip}
+ fi
+
+ if [ ! -d "${NETCONS_CONFIGFS}" ]; then
+ echo "SKIP: directory ${NETCONS_CONFIGFS} does not exist. Check if NETCONSOLE_DYNAMIC is enabled" >&2
+ exit ${ksft_skip}
+ fi
+
+ if ip link show veth0 2> /dev/null; then
+ echo "SKIP: interface veth0 exists in the system. Not overwriting it."
+ exit ${ksft_skip}
+ fi
+}
+
+# ========== #
+# Start here #
+# ========== #
+
+# Check for basic system dependency and exit if not found
+check_for_dependencies
+# Create one namespace and two interfaces
+set_network
+# Create a dynamic target for netconsole
+create_dynamic_target
+# Listed for netconsole port inside the namespace and destination interface
+listen_port /tmp/"${TARGET}" &
+# Wait for nc to start and listen to the port.
+sleep 1
+
+# Send the message
+echo "${MSG}: ${TARGET}" > /dev/kmsg
+
+# Make sure the message was received in the dst part
+validate_result
+ret=$?
+# Remove the namespace, interfaces and netconsole target
+cleanup
+
+exit ${ret}
Adds a selftest that creates two virtual interfaces, assigns one to a new namespace, and assigns IP addresses to both. It listens on the destination interface using netcat and configures a dynamic target on netconsole, pointing to the destination IP address. The test then checks if the message was received properly on the destination interface. Signed-off-by: Breno Leitao <leitao@debian.org> --- MAINTAINERS | 1 + .../net/netconsole/basic_integration_test.sh | 153 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100755 tools/testing/selftests/net/netconsole/basic_integration_test.sh