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