xref: /linux/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh (revision 1a9239bb4253f9076b5b4b2a1a4e8d7defd77a95)
161f51cc6SBreno Leitao#!/usr/bin/env bash
261f51cc6SBreno Leitao# SPDX-License-Identifier: GPL-2.0
361f51cc6SBreno Leitao
461f51cc6SBreno Leitao# This file contains functions and helpers to support the netconsole
561f51cc6SBreno Leitao# selftests
661f51cc6SBreno Leitao#
761f51cc6SBreno Leitao# Author: Breno Leitao <leitao@debian.org>
861f51cc6SBreno Leitao
961f51cc6SBreno Leitaoset -euo pipefail
1061f51cc6SBreno Leitao
1161f51cc6SBreno LeitaoLIBDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
1261f51cc6SBreno Leitao
1361f51cc6SBreno LeitaoSRCIF="" # to be populated later
1461f51cc6SBreno LeitaoSRCIP=192.0.2.1
1561f51cc6SBreno LeitaoDSTIF="" # to be populated later
1661f51cc6SBreno LeitaoDSTIP=192.0.2.2
1761f51cc6SBreno Leitao
1861f51cc6SBreno LeitaoPORT="6666"
1961f51cc6SBreno LeitaoMSG="netconsole selftest"
2061f51cc6SBreno LeitaoUSERDATA_KEY="key"
2161f51cc6SBreno LeitaoUSERDATA_VALUE="value"
2261f51cc6SBreno LeitaoTARGET=$(mktemp -u netcons_XXXXX)
2361f51cc6SBreno LeitaoDEFAULT_PRINTK_VALUES=$(cat /proc/sys/kernel/printk)
2461f51cc6SBreno LeitaoNETCONS_CONFIGFS="/sys/kernel/config/netconsole"
2561f51cc6SBreno LeitaoNETCONS_PATH="${NETCONS_CONFIGFS}"/"${TARGET}"
2661f51cc6SBreno Leitao# NAMESPACE will be populated by setup_ns with a random value
2761f51cc6SBreno LeitaoNAMESPACE=""
2861f51cc6SBreno Leitao
2961f51cc6SBreno Leitao# IDs for netdevsim
3061f51cc6SBreno LeitaoNSIM_DEV_1_ID=$((256 + RANDOM % 256))
3161f51cc6SBreno LeitaoNSIM_DEV_2_ID=$((512 + RANDOM % 256))
3261f51cc6SBreno LeitaoNSIM_DEV_SYS_NEW="/sys/bus/netdevsim/new_device"
3361f51cc6SBreno Leitao
3461f51cc6SBreno Leitao# Used to create and delete namespaces
3561f51cc6SBreno Leitaosource "${LIBDIR}"/../../../../net/lib.sh
3661f51cc6SBreno Leitaosource "${LIBDIR}"/../../../../net/net_helper.sh
3761f51cc6SBreno Leitao
3861f51cc6SBreno Leitao# Create netdevsim interfaces
3961f51cc6SBreno Leitaocreate_ifaces() {
4061f51cc6SBreno Leitao
4161f51cc6SBreno Leitao	echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_NEW"
4261f51cc6SBreno Leitao	echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_NEW"
4361f51cc6SBreno Leitao	udevadm settle 2> /dev/null || true
4461f51cc6SBreno Leitao
4561f51cc6SBreno Leitao	local NSIM1=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_1_ID"
4661f51cc6SBreno Leitao	local NSIM2=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_2_ID"
4761f51cc6SBreno Leitao
4861f51cc6SBreno Leitao	# These are global variables
4961f51cc6SBreno Leitao	SRCIF=$(find "$NSIM1"/net -maxdepth 1 -type d ! \
5061f51cc6SBreno Leitao		-path "$NSIM1"/net -exec basename {} \;)
5161f51cc6SBreno Leitao	DSTIF=$(find "$NSIM2"/net -maxdepth 1 -type d ! \
5261f51cc6SBreno Leitao		-path "$NSIM2"/net -exec basename {} \;)
5361f51cc6SBreno Leitao}
5461f51cc6SBreno Leitao
5561f51cc6SBreno Leitaolink_ifaces() {
5661f51cc6SBreno Leitao	local NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device"
5761f51cc6SBreno Leitao	local SRCIF_IFIDX=$(cat /sys/class/net/"$SRCIF"/ifindex)
5861f51cc6SBreno Leitao	local DSTIF_IFIDX=$(cat /sys/class/net/"$DSTIF"/ifindex)
5961f51cc6SBreno Leitao
6061f51cc6SBreno Leitao	exec {NAMESPACE_FD}</var/run/netns/"${NAMESPACE}"
6161f51cc6SBreno Leitao	exec {INITNS_FD}</proc/self/ns/net
6261f51cc6SBreno Leitao
6361f51cc6SBreno Leitao	# Bind the dst interface to namespace
6461f51cc6SBreno Leitao	ip link set "${DSTIF}" netns "${NAMESPACE}"
6561f51cc6SBreno Leitao
6661f51cc6SBreno Leitao	# Linking one device to the other one (on the other namespace}
6761f51cc6SBreno Leitao	if ! echo "${INITNS_FD}:$SRCIF_IFIDX $NAMESPACE_FD:$DSTIF_IFIDX"  > $NSIM_DEV_SYS_LINK
6861f51cc6SBreno Leitao	then
6961f51cc6SBreno Leitao		echo "linking netdevsim1 with netdevsim2 should succeed"
7061f51cc6SBreno Leitao		cleanup
7161f51cc6SBreno Leitao		exit "${ksft_skip}"
7261f51cc6SBreno Leitao	fi
7361f51cc6SBreno Leitao}
7461f51cc6SBreno Leitao
7561f51cc6SBreno Leitaofunction configure_ip() {
7661f51cc6SBreno Leitao	# Configure the IPs for both interfaces
7761f51cc6SBreno Leitao	ip netns exec "${NAMESPACE}" ip addr add "${DSTIP}"/24 dev "${DSTIF}"
7861f51cc6SBreno Leitao	ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" up
7961f51cc6SBreno Leitao
8061f51cc6SBreno Leitao	ip addr add "${SRCIP}"/24 dev "${SRCIF}"
8161f51cc6SBreno Leitao	ip link set "${SRCIF}" up
8261f51cc6SBreno Leitao}
8361f51cc6SBreno Leitao
8461f51cc6SBreno Leitaofunction set_network() {
8561f51cc6SBreno Leitao	# setup_ns function is coming from lib.sh
8661f51cc6SBreno Leitao	setup_ns NAMESPACE
8761f51cc6SBreno Leitao
8861f51cc6SBreno Leitao	# Create both interfaces, and assign the destination to a different
8961f51cc6SBreno Leitao	# namespace
9061f51cc6SBreno Leitao	create_ifaces
9161f51cc6SBreno Leitao
9261f51cc6SBreno Leitao	# Link both interfaces back to back
9361f51cc6SBreno Leitao	link_ifaces
9461f51cc6SBreno Leitao
9561f51cc6SBreno Leitao	configure_ip
9661f51cc6SBreno Leitao}
9761f51cc6SBreno Leitao
9861f51cc6SBreno Leitaofunction create_dynamic_target() {
9961f51cc6SBreno Leitao	DSTMAC=$(ip netns exec "${NAMESPACE}" \
10061f51cc6SBreno Leitao		 ip link show "${DSTIF}" | awk '/ether/ {print $2}')
10161f51cc6SBreno Leitao
10261f51cc6SBreno Leitao	# Create a dynamic target
10361f51cc6SBreno Leitao	mkdir "${NETCONS_PATH}"
10461f51cc6SBreno Leitao
10561f51cc6SBreno Leitao	echo "${DSTIP}" > "${NETCONS_PATH}"/remote_ip
10661f51cc6SBreno Leitao	echo "${SRCIP}" > "${NETCONS_PATH}"/local_ip
10761f51cc6SBreno Leitao	echo "${DSTMAC}" > "${NETCONS_PATH}"/remote_mac
10861f51cc6SBreno Leitao	echo "${SRCIF}" > "${NETCONS_PATH}"/dev_name
10961f51cc6SBreno Leitao
11061f51cc6SBreno Leitao	echo 1 > "${NETCONS_PATH}"/enabled
11161f51cc6SBreno Leitao}
11261f51cc6SBreno Leitao
113d5fdfe48SBreno Leitao# Do not append the release to the header of the message
114d5fdfe48SBreno Leitaofunction disable_release_append() {
115d5fdfe48SBreno Leitao	echo 0 > "${NETCONS_PATH}"/enabled
116d5fdfe48SBreno Leitao	echo 0 > "${NETCONS_PATH}"/release
117d5fdfe48SBreno Leitao	echo 1 > "${NETCONS_PATH}"/enabled
118d5fdfe48SBreno Leitao}
119d5fdfe48SBreno Leitao
12061f51cc6SBreno Leitaofunction cleanup() {
12161f51cc6SBreno Leitao	local NSIM_DEV_SYS_DEL="/sys/bus/netdevsim/del_device"
12261f51cc6SBreno Leitao
12361f51cc6SBreno Leitao	# delete netconsole dynamic reconfiguration
12461f51cc6SBreno Leitao	echo 0 > "${NETCONS_PATH}"/enabled
1257dcb6535SBreno Leitao	# Remove all the keys that got created during the selftest
1267dcb6535SBreno Leitao	find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete
12761f51cc6SBreno Leitao	# Remove the configfs entry
12861f51cc6SBreno Leitao	rmdir "${NETCONS_PATH}"
12961f51cc6SBreno Leitao
13061f51cc6SBreno Leitao	# Delete netdevsim devices
13161f51cc6SBreno Leitao	echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_DEL"
13261f51cc6SBreno Leitao	echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_DEL"
13361f51cc6SBreno Leitao
13461f51cc6SBreno Leitao	# this is coming from lib.sh
13561f51cc6SBreno Leitao	cleanup_all_ns
13661f51cc6SBreno Leitao
13761f51cc6SBreno Leitao	# Restoring printk configurations
13861f51cc6SBreno Leitao	echo "${DEFAULT_PRINTK_VALUES}" > /proc/sys/kernel/printk
13961f51cc6SBreno Leitao}
14061f51cc6SBreno Leitao
14161f51cc6SBreno Leitaofunction set_user_data() {
14261f51cc6SBreno Leitao	if [[ ! -d "${NETCONS_PATH}""/userdata" ]]
14361f51cc6SBreno Leitao	then
14461f51cc6SBreno Leitao		echo "Userdata path not available in ${NETCONS_PATH}/userdata"
14561f51cc6SBreno Leitao		exit "${ksft_skip}"
14661f51cc6SBreno Leitao	fi
14761f51cc6SBreno Leitao
1487dcb6535SBreno Leitao	KEY_PATH="${NETCONS_PATH}/userdata/${USERDATA_KEY}"
14961f51cc6SBreno Leitao	mkdir -p "${KEY_PATH}"
15061f51cc6SBreno Leitao	VALUE_PATH="${KEY_PATH}""/value"
15161f51cc6SBreno Leitao	echo "${USERDATA_VALUE}" > "${VALUE_PATH}"
15261f51cc6SBreno Leitao}
15361f51cc6SBreno Leitao
15461f51cc6SBreno Leitaofunction listen_port_and_save_to() {
15561f51cc6SBreno Leitao	local OUTPUT=${1}
15661f51cc6SBreno Leitao	# Just wait for 2 seconds
15761f51cc6SBreno Leitao	timeout 2 ip netns exec "${NAMESPACE}" \
15861f51cc6SBreno Leitao		socat UDP-LISTEN:"${PORT}",fork "${OUTPUT}"
15961f51cc6SBreno Leitao}
16061f51cc6SBreno Leitao
16161f51cc6SBreno Leitaofunction validate_result() {
16261f51cc6SBreno Leitao	local TMPFILENAME="$1"
16361f51cc6SBreno Leitao
16461f51cc6SBreno Leitao	# TMPFILENAME will contain something like:
16561f51cc6SBreno Leitao	# 6.11.1-0_fbk0_rc13_509_g30d75cea12f7,13,1822,115075213798,-;netconsole selftest: netcons_gtJHM
16661f51cc6SBreno Leitao	#  key=value
16761f51cc6SBreno Leitao
16861f51cc6SBreno Leitao	# Check if the file exists
16961f51cc6SBreno Leitao	if [ ! -f "$TMPFILENAME" ]; then
17061f51cc6SBreno Leitao		echo "FAIL: File was not generated." >&2
17161f51cc6SBreno Leitao		exit "${ksft_fail}"
17261f51cc6SBreno Leitao	fi
17361f51cc6SBreno Leitao
17461f51cc6SBreno Leitao	if ! grep -q "${MSG}" "${TMPFILENAME}"; then
17561f51cc6SBreno Leitao		echo "FAIL: ${MSG} not found in ${TMPFILENAME}" >&2
17661f51cc6SBreno Leitao		cat "${TMPFILENAME}" >&2
17761f51cc6SBreno Leitao		exit "${ksft_fail}"
17861f51cc6SBreno Leitao	fi
17961f51cc6SBreno Leitao
18061f51cc6SBreno Leitao	if ! grep -q "${USERDATA_KEY}=${USERDATA_VALUE}" "${TMPFILENAME}"; then
18161f51cc6SBreno Leitao		echo "FAIL: ${USERDATA_KEY}=${USERDATA_VALUE} not found in ${TMPFILENAME}" >&2
18261f51cc6SBreno Leitao		cat "${TMPFILENAME}" >&2
18361f51cc6SBreno Leitao		exit "${ksft_fail}"
18461f51cc6SBreno Leitao	fi
18561f51cc6SBreno Leitao
18661f51cc6SBreno Leitao	# Delete the file once it is validated, otherwise keep it
18761f51cc6SBreno Leitao	# for debugging purposes
18861f51cc6SBreno Leitao	rm "${TMPFILENAME}"
18961f51cc6SBreno Leitao	exit "${ksft_pass}"
19061f51cc6SBreno Leitao}
19161f51cc6SBreno Leitao
19261f51cc6SBreno Leitaofunction check_for_dependencies() {
19361f51cc6SBreno Leitao	if [ "$(id -u)" -ne 0 ]; then
19461f51cc6SBreno Leitao		echo "This test must be run as root" >&2
19561f51cc6SBreno Leitao		exit "${ksft_skip}"
19661f51cc6SBreno Leitao	fi
19761f51cc6SBreno Leitao
19861f51cc6SBreno Leitao	if ! which socat > /dev/null ; then
19961f51cc6SBreno Leitao		echo "SKIP: socat(1) is not available" >&2
20061f51cc6SBreno Leitao		exit "${ksft_skip}"
20161f51cc6SBreno Leitao	fi
20261f51cc6SBreno Leitao
20361f51cc6SBreno Leitao	if ! which ip > /dev/null ; then
20461f51cc6SBreno Leitao		echo "SKIP: ip(1) is not available" >&2
20561f51cc6SBreno Leitao		exit "${ksft_skip}"
20661f51cc6SBreno Leitao	fi
20761f51cc6SBreno Leitao
20861f51cc6SBreno Leitao	if ! which udevadm > /dev/null ; then
20961f51cc6SBreno Leitao		echo "SKIP: udevadm(1) is not available" >&2
21061f51cc6SBreno Leitao		exit "${ksft_skip}"
21161f51cc6SBreno Leitao	fi
21261f51cc6SBreno Leitao
21361f51cc6SBreno Leitao	if [ ! -f "${NSIM_DEV_SYS_NEW}" ]; then
21461f51cc6SBreno Leitao		echo "SKIP: file ${NSIM_DEV_SYS_NEW} does not exist. Check if CONFIG_NETDEVSIM is enabled" >&2
21561f51cc6SBreno Leitao		exit "${ksft_skip}"
21661f51cc6SBreno Leitao	fi
21761f51cc6SBreno Leitao
21861f51cc6SBreno Leitao	if [ ! -d "${NETCONS_CONFIGFS}" ]; then
21961f51cc6SBreno Leitao		echo "SKIP: directory ${NETCONS_CONFIGFS} does not exist. Check if NETCONSOLE_DYNAMIC is enabled" >&2
22061f51cc6SBreno Leitao		exit "${ksft_skip}"
22161f51cc6SBreno Leitao	fi
22261f51cc6SBreno Leitao
22361f51cc6SBreno Leitao	if ip link show "${DSTIF}" 2> /dev/null; then
22461f51cc6SBreno Leitao		echo "SKIP: interface ${DSTIF} exists in the system. Not overwriting it." >&2
22561f51cc6SBreno Leitao		exit "${ksft_skip}"
22661f51cc6SBreno Leitao	fi
22761f51cc6SBreno Leitao
22861f51cc6SBreno Leitao	if ip addr list | grep -E "inet.*(${SRCIP}|${DSTIP})" 2> /dev/null; then
22961f51cc6SBreno Leitao		echo "SKIP: IPs already in use. Skipping it" >&2
23061f51cc6SBreno Leitao		exit "${ksft_skip}"
23161f51cc6SBreno Leitao	fi
23261f51cc6SBreno Leitao}
233*12fd83caSBreno Leitao
234*12fd83caSBreno Leitaofunction check_for_taskset() {
235*12fd83caSBreno Leitao	if ! which taskset > /dev/null ; then
236*12fd83caSBreno Leitao		echo "SKIP: taskset(1) is not available" >&2
237*12fd83caSBreno Leitao		exit "${ksft_skip}"
238*12fd83caSBreno Leitao	fi
239*12fd83caSBreno Leitao}
240*12fd83caSBreno Leitao
241*12fd83caSBreno Leitao# This is necessary if running multiple tests in a row
242*12fd83caSBreno Leitaofunction pkill_socat() {
243*12fd83caSBreno Leitao	PROCESS_NAME="socat UDP-LISTEN:6666,fork ${OUTPUT_FILE}"
244*12fd83caSBreno Leitao	# socat runs under timeout(1), kill it if it is still alive
245*12fd83caSBreno Leitao	# do not fail if socat doesn't exist anymore
246*12fd83caSBreno Leitao	set +e
247*12fd83caSBreno Leitao	pkill -f "${PROCESS_NAME}"
248*12fd83caSBreno Leitao	set -e
249*12fd83caSBreno Leitao}
250