1#!/usr/bin/env bash 2# SPDX-License-Identifier: GPL-2.0 3 4# This file contains functions and helpers to support the netconsole 5# selftests 6# 7# Author: Breno Leitao <[email protected]> 8 9set -euo pipefail 10 11LIBDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") 12 13SRCIF="" # to be populated later 14SRCIP=192.0.2.1 15DSTIF="" # to be populated later 16DSTIP=192.0.2.2 17 18PORT="6666" 19MSG="netconsole selftest" 20USERDATA_KEY="key" 21USERDATA_VALUE="value" 22TARGET=$(mktemp -u netcons_XXXXX) 23DEFAULT_PRINTK_VALUES=$(cat /proc/sys/kernel/printk) 24NETCONS_CONFIGFS="/sys/kernel/config/netconsole" 25NETCONS_PATH="${NETCONS_CONFIGFS}"/"${TARGET}" 26# NAMESPACE will be populated by setup_ns with a random value 27NAMESPACE="" 28 29# IDs for netdevsim 30NSIM_DEV_1_ID=$((256 + RANDOM % 256)) 31NSIM_DEV_2_ID=$((512 + RANDOM % 256)) 32NSIM_DEV_SYS_NEW="/sys/bus/netdevsim/new_device" 33 34# Used to create and delete namespaces 35source "${LIBDIR}"/../../../../net/lib.sh 36source "${LIBDIR}"/../../../../net/net_helper.sh 37 38# Create netdevsim interfaces 39create_ifaces() { 40 41 echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_NEW" 42 echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_NEW" 43 udevadm settle 2> /dev/null || true 44 45 local NSIM1=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_1_ID" 46 local NSIM2=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_2_ID" 47 48 # These are global variables 49 SRCIF=$(find "$NSIM1"/net -maxdepth 1 -type d ! \ 50 -path "$NSIM1"/net -exec basename {} \;) 51 DSTIF=$(find "$NSIM2"/net -maxdepth 1 -type d ! \ 52 -path "$NSIM2"/net -exec basename {} \;) 53} 54 55link_ifaces() { 56 local NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device" 57 local SRCIF_IFIDX=$(cat /sys/class/net/"$SRCIF"/ifindex) 58 local DSTIF_IFIDX=$(cat /sys/class/net/"$DSTIF"/ifindex) 59 60 exec {NAMESPACE_FD}</var/run/netns/"${NAMESPACE}" 61 exec {INITNS_FD}</proc/self/ns/net 62 63 # Bind the dst interface to namespace 64 ip link set "${DSTIF}" netns "${NAMESPACE}" 65 66 # Linking one device to the other one (on the other namespace} 67 if ! echo "${INITNS_FD}:$SRCIF_IFIDX $NAMESPACE_FD:$DSTIF_IFIDX" > $NSIM_DEV_SYS_LINK 68 then 69 echo "linking netdevsim1 with netdevsim2 should succeed" 70 cleanup 71 exit "${ksft_skip}" 72 fi 73} 74 75function configure_ip() { 76 # Configure the IPs for both interfaces 77 ip netns exec "${NAMESPACE}" ip addr add "${DSTIP}"/24 dev "${DSTIF}" 78 ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" up 79 80 ip addr add "${SRCIP}"/24 dev "${SRCIF}" 81 ip link set "${SRCIF}" up 82} 83 84function set_network() { 85 # setup_ns function is coming from lib.sh 86 setup_ns NAMESPACE 87 88 # Create both interfaces, and assign the destination to a different 89 # namespace 90 create_ifaces 91 92 # Link both interfaces back to back 93 link_ifaces 94 95 configure_ip 96} 97 98function create_dynamic_target() { 99 DSTMAC=$(ip netns exec "${NAMESPACE}" \ 100 ip link show "${DSTIF}" | awk '/ether/ {print $2}') 101 102 # Create a dynamic target 103 mkdir "${NETCONS_PATH}" 104 105 echo "${DSTIP}" > "${NETCONS_PATH}"/remote_ip 106 echo "${SRCIP}" > "${NETCONS_PATH}"/local_ip 107 echo "${DSTMAC}" > "${NETCONS_PATH}"/remote_mac 108 echo "${SRCIF}" > "${NETCONS_PATH}"/dev_name 109 110 echo 1 > "${NETCONS_PATH}"/enabled 111} 112 113function cleanup() { 114 local NSIM_DEV_SYS_DEL="/sys/bus/netdevsim/del_device" 115 116 # delete netconsole dynamic reconfiguration 117 echo 0 > "${NETCONS_PATH}"/enabled 118 # Remove all the keys that got created during the selftest 119 find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete 120 # Remove the configfs entry 121 rmdir "${NETCONS_PATH}" 122 123 # Delete netdevsim devices 124 echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_DEL" 125 echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_DEL" 126 127 # this is coming from lib.sh 128 cleanup_all_ns 129 130 # Restoring printk configurations 131 echo "${DEFAULT_PRINTK_VALUES}" > /proc/sys/kernel/printk 132} 133 134function set_user_data() { 135 if [[ ! -d "${NETCONS_PATH}""/userdata" ]] 136 then 137 echo "Userdata path not available in ${NETCONS_PATH}/userdata" 138 exit "${ksft_skip}" 139 fi 140 141 KEY_PATH="${NETCONS_PATH}/userdata/${USERDATA_KEY}" 142 mkdir -p "${KEY_PATH}" 143 VALUE_PATH="${KEY_PATH}""/value" 144 echo "${USERDATA_VALUE}" > "${VALUE_PATH}" 145} 146 147function listen_port_and_save_to() { 148 local OUTPUT=${1} 149 # Just wait for 2 seconds 150 timeout 2 ip netns exec "${NAMESPACE}" \ 151 socat UDP-LISTEN:"${PORT}",fork "${OUTPUT}" 152} 153 154function validate_result() { 155 local TMPFILENAME="$1" 156 157 # TMPFILENAME will contain something like: 158 # 6.11.1-0_fbk0_rc13_509_g30d75cea12f7,13,1822,115075213798,-;netconsole selftest: netcons_gtJHM 159 # key=value 160 161 # Check if the file exists 162 if [ ! -f "$TMPFILENAME" ]; then 163 echo "FAIL: File was not generated." >&2 164 exit "${ksft_fail}" 165 fi 166 167 if ! grep -q "${MSG}" "${TMPFILENAME}"; then 168 echo "FAIL: ${MSG} not found in ${TMPFILENAME}" >&2 169 cat "${TMPFILENAME}" >&2 170 exit "${ksft_fail}" 171 fi 172 173 if ! grep -q "${USERDATA_KEY}=${USERDATA_VALUE}" "${TMPFILENAME}"; then 174 echo "FAIL: ${USERDATA_KEY}=${USERDATA_VALUE} not found in ${TMPFILENAME}" >&2 175 cat "${TMPFILENAME}" >&2 176 exit "${ksft_fail}" 177 fi 178 179 # Delete the file once it is validated, otherwise keep it 180 # for debugging purposes 181 rm "${TMPFILENAME}" 182 exit "${ksft_pass}" 183} 184 185function check_for_dependencies() { 186 if [ "$(id -u)" -ne 0 ]; then 187 echo "This test must be run as root" >&2 188 exit "${ksft_skip}" 189 fi 190 191 if ! which socat > /dev/null ; then 192 echo "SKIP: socat(1) is not available" >&2 193 exit "${ksft_skip}" 194 fi 195 196 if ! which ip > /dev/null ; then 197 echo "SKIP: ip(1) is not available" >&2 198 exit "${ksft_skip}" 199 fi 200 201 if ! which udevadm > /dev/null ; then 202 echo "SKIP: udevadm(1) is not available" >&2 203 exit "${ksft_skip}" 204 fi 205 206 if [ ! -f "${NSIM_DEV_SYS_NEW}" ]; then 207 echo "SKIP: file ${NSIM_DEV_SYS_NEW} does not exist. Check if CONFIG_NETDEVSIM is enabled" >&2 208 exit "${ksft_skip}" 209 fi 210 211 if [ ! -d "${NETCONS_CONFIGFS}" ]; then 212 echo "SKIP: directory ${NETCONS_CONFIGFS} does not exist. Check if NETCONSOLE_DYNAMIC is enabled" >&2 213 exit "${ksft_skip}" 214 fi 215 216 if ip link show "${DSTIF}" 2> /dev/null; then 217 echo "SKIP: interface ${DSTIF} exists in the system. Not overwriting it." >&2 218 exit "${ksft_skip}" 219 fi 220 221 if ip addr list | grep -E "inet.*(${SRCIP}|${DSTIP})" 2> /dev/null; then 222 echo "SKIP: IPs already in use. Skipping it" >&2 223 exit "${ksft_skip}" 224 fi 225} 226