Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-netpoll-fix-memory-leak-and-add-comprehensive-selftests'

Breno Leitao says:

====================
net: netpoll: fix memory leak and add comprehensive selftests

Fix a memory leak in netpoll and introduce netconsole selftests that
expose the issue when running with kmemleak detection enabled.

This patchset includes a selftest for netpoll with multiple concurrent
users (netconsole + bonding), which simulates the scenario from test[1]
that originally demonstrated the issue allegedly fixed by commit
efa95b01da18 ("netpoll: fix use after free") - a commit that is now
being reverted.

Sending this to "net" branch because this is a fix, and the selftest
might help with the backports validation.

Link: https://lore.kernel.org/lkml/96b940137a50e5c387687bb4f57de8b0435a653f.1404857349.git.decot@googlers.com/ [1]
====================

Link: https://patch.msgid.link/20251107-netconsole_torture-v10-0-749227b55f63@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+566 -17
+5 -2
net/core/netpoll.c
··· 811 811 if (!npinfo) 812 812 return; 813 813 814 + /* At this point, there is a single npinfo instance per netdevice, and 815 + * its refcnt tracks how many netpoll structures are linked to it. We 816 + * only perform npinfo cleanup when the refcnt decrements to zero. 817 + */ 814 818 if (refcount_dec_and_test(&npinfo->refcnt)) { 815 819 const struct net_device_ops *ops; 816 820 ··· 824 820 825 821 RCU_INIT_POINTER(np->dev->npinfo, NULL); 826 822 call_rcu(&npinfo->rcu, rcu_cleanup_netpoll_info); 827 - } else 828 - RCU_INIT_POINTER(np->dev->npinfo, NULL); 823 + } 829 824 830 825 skb_pool_flush(np); 831 826 }
+1
tools/testing/selftests/drivers/net/Makefile
··· 18 18 netcons_fragmented_msg.sh \ 19 19 netcons_overflow.sh \ 20 20 netcons_sysdata.sh \ 21 + netcons_torture.sh \ 21 22 netpoll_basic.py \ 22 23 ping.py \ 23 24 psp.py \
+2
tools/testing/selftests/drivers/net/bonding/Makefile
··· 14 14 dev_addr_lists.sh \ 15 15 mode-1-recovery-updelay.sh \ 16 16 mode-2-recovery-updelay.sh \ 17 + netcons_over_bonding.sh \ 17 18 # end of TEST_PROGS 18 19 19 20 TEST_FILES := \ ··· 25 24 26 25 TEST_INCLUDES := \ 27 26 ../../../net/lib.sh \ 27 + ../lib/sh/lib_netcons.sh \ 28 28 ../../../net/forwarding/lib.sh \ 29 29 # end of TEST_INCLUDES 30 30
+4
tools/testing/selftests/drivers/net/bonding/config
··· 1 1 CONFIG_BONDING=y 2 2 CONFIG_BRIDGE=y 3 + CONFIG_CONFIGFS_FS=y 3 4 CONFIG_DUMMY=y 4 5 CONFIG_INET_ESP=y 5 6 CONFIG_INET_ESP_OFFLOAD=y ··· 10 9 CONFIG_NET_ACT_GACT=y 11 10 CONFIG_NET_CLS_FLOWER=y 12 11 CONFIG_NET_CLS_MATCHALL=m 12 + CONFIG_NETCONSOLE=m 13 + CONFIG_NETCONSOLE_DYNAMIC=y 14 + CONFIG_NETCONSOLE_EXTENDED_LOG=y 13 15 CONFIG_NETDEVSIM=m 14 16 CONFIG_NET_SCH_INGRESS=y 15 17 CONFIG_NLMON=y
+361
tools/testing/selftests/drivers/net/bonding/netcons_over_bonding.sh
··· 1 + #!/usr/bin/env bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # This selftest exercises trying to have multiple netpoll users at the same 5 + # time. 6 + # 7 + # This selftest has multiple smalls test inside, and the goal is to 8 + # get interfaces with bonding and netconsole in different orders in order 9 + # to catch any possible issue. 10 + # 11 + # The main test composes of four interfaces being created using netdevsim; two 12 + # of them are bonded to serve as the netconsole's transmit interface. The 13 + # remaining two interfaces are similarly bonded and assigned to a separate 14 + # network namespace, which acts as the receive interface, where socat monitors 15 + # for incoming messages. 16 + # 17 + # A netconsole message is then sent to ensure it is properly received across 18 + # this configuration. 19 + # 20 + # Later, run a few other tests, to make sure that bonding and netconsole 21 + # cannot coexist. 22 + # 23 + # The test's objective is to exercise netpoll usage when managed simultaneously 24 + # by multiple subsystems (netconsole and bonding). 25 + # 26 + # Author: Breno Leitao <leitao@debian.org> 27 + 28 + set -euo pipefail 29 + 30 + SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") 31 + 32 + source "${SCRIPTDIR}"/../lib/sh/lib_netcons.sh 33 + 34 + modprobe netdevsim 2> /dev/null || true 35 + modprobe netconsole 2> /dev/null || true 36 + modprobe bonding 2> /dev/null || true 37 + modprobe veth 2> /dev/null || true 38 + 39 + # The content of kmsg will be save to the following file 40 + OUTPUT_FILE="/tmp/${TARGET}" 41 + 42 + # Check for basic system dependency and exit if not found 43 + check_for_dependencies 44 + # Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5) 45 + echo "6 5" > /proc/sys/kernel/printk 46 + # Remove the namespace, interfaces and netconsole target on exit 47 + trap cleanup_bond EXIT 48 + 49 + FORMAT="extended" 50 + IP_VERSION="ipv4" 51 + VETH0="veth"$(( RANDOM % 256)) 52 + VETH1="veth"$((256 + RANDOM % 256)) 53 + TXNS="" 54 + RXNS="" 55 + 56 + # Create "bond_tx_XX" and "bond_rx_XX" interfaces, and set DSTIF and SRCIF with 57 + # the bonding interfaces 58 + function setup_bonding_ifaces() { 59 + local RAND=$(( RANDOM % 100 )) 60 + BOND_TX_MAIN_IF="bond_tx_$RAND" 61 + BOND_RX_MAIN_IF="bond_rx_$RAND" 62 + 63 + # Setup TX 64 + if ! ip -n "${TXNS}" link add "${BOND_TX_MAIN_IF}" type bond mode balance-rr 65 + then 66 + echo "Failed to create bond TX interface. Is CONFIG_BONDING set?" >&2 67 + # only clean nsim ifaces and namespace. Nothing else has been 68 + # initialized 69 + cleanup_bond_nsim 70 + trap - EXIT 71 + exit "${ksft_skip}" 72 + fi 73 + 74 + # create_netdevsim() got the interface up, but it needs to be down 75 + # before being enslaved. 76 + ip -n "${TXNS}" \ 77 + link set "${BOND_TX1_SLAVE_IF}" down 78 + ip -n "${TXNS}" \ 79 + link set "${BOND_TX2_SLAVE_IF}" down 80 + ip -n "${TXNS}" \ 81 + link set "${BOND_TX1_SLAVE_IF}" master "${BOND_TX_MAIN_IF}" 82 + ip -n "${TXNS}" \ 83 + link set "${BOND_TX2_SLAVE_IF}" master "${BOND_TX_MAIN_IF}" 84 + ip -n "${TXNS}" \ 85 + link set "${BOND_TX_MAIN_IF}" up 86 + 87 + # Setup RX 88 + ip -n "${RXNS}" \ 89 + link add "${BOND_RX_MAIN_IF}" type bond mode balance-rr 90 + ip -n "${RXNS}" \ 91 + link set "${BOND_RX1_SLAVE_IF}" down 92 + ip -n "${RXNS}" \ 93 + link set "${BOND_RX2_SLAVE_IF}" down 94 + ip -n "${RXNS}" \ 95 + link set "${BOND_RX1_SLAVE_IF}" master "${BOND_RX_MAIN_IF}" 96 + ip -n "${RXNS}" \ 97 + link set "${BOND_RX2_SLAVE_IF}" master "${BOND_RX_MAIN_IF}" 98 + ip -n "${RXNS}" \ 99 + link set "${BOND_RX_MAIN_IF}" up 100 + 101 + export DSTIF="${BOND_RX_MAIN_IF}" 102 + export SRCIF="${BOND_TX_MAIN_IF}" 103 + } 104 + 105 + # Create 4 netdevsim interfaces. Two of them will be bound to TX bonding iface 106 + # and the other two will be bond to the RX interface (on the other namespace) 107 + function create_ifaces_bond() { 108 + BOND_TX1_SLAVE_IF=$(create_netdevsim "${NSIM_BOND_TX_1}" "${TXNS}") 109 + BOND_TX2_SLAVE_IF=$(create_netdevsim "${NSIM_BOND_TX_2}" "${TXNS}") 110 + BOND_RX1_SLAVE_IF=$(create_netdevsim "${NSIM_BOND_RX_1}" "${RXNS}") 111 + BOND_RX2_SLAVE_IF=$(create_netdevsim "${NSIM_BOND_RX_2}" "${RXNS}") 112 + } 113 + 114 + # netdevsim link BOND_TX to BOND_RX interfaces 115 + function link_ifaces_bond() { 116 + local BOND_TX1_SLAVE_IFIDX 117 + local BOND_TX2_SLAVE_IFIDX 118 + local BOND_RX1_SLAVE_IFIDX 119 + local BOND_RX2_SLAVE_IFIDX 120 + local TXNS_FD 121 + local RXNS_FD 122 + 123 + BOND_TX1_SLAVE_IFIDX=$(ip netns exec "${TXNS}" \ 124 + cat /sys/class/net/"$BOND_TX1_SLAVE_IF"/ifindex) 125 + BOND_TX2_SLAVE_IFIDX=$(ip netns exec "${TXNS}" \ 126 + cat /sys/class/net/"$BOND_TX2_SLAVE_IF"/ifindex) 127 + BOND_RX1_SLAVE_IFIDX=$(ip netns exec "${RXNS}" \ 128 + cat /sys/class/net/"$BOND_RX1_SLAVE_IF"/ifindex) 129 + BOND_RX2_SLAVE_IFIDX=$(ip netns exec "${RXNS}" \ 130 + cat /sys/class/net/"$BOND_RX2_SLAVE_IF"/ifindex) 131 + 132 + exec {TXNS_FD}</var/run/netns/"${TXNS}" 133 + exec {RXNS_FD}</var/run/netns/"${RXNS}" 134 + 135 + # Linking TX ifaces to the RX ones (on the other namespace) 136 + echo "${TXNS_FD}:$BOND_TX1_SLAVE_IFIDX $RXNS_FD:$BOND_RX1_SLAVE_IFIDX" \ 137 + > "$NSIM_DEV_SYS_LINK" 138 + echo "${TXNS_FD}:$BOND_TX2_SLAVE_IFIDX $RXNS_FD:$BOND_RX2_SLAVE_IFIDX" \ 139 + > "$NSIM_DEV_SYS_LINK" 140 + 141 + exec {TXNS_FD}<&- 142 + exec {RXNS_FD}<&- 143 + } 144 + 145 + function create_all_ifaces() { 146 + # setup_ns function is coming from lib.sh 147 + setup_ns TXNS RXNS 148 + export NAMESPACE="${RXNS}" 149 + 150 + # Create two interfaces for RX and two for TX 151 + create_ifaces_bond 152 + # Link netlink ifaces 153 + link_ifaces_bond 154 + } 155 + 156 + # configure DSTIF and SRCIF IPs 157 + function configure_ifaces_ips() { 158 + local IP_VERSION=${1:-"ipv4"} 159 + select_ipv4_or_ipv6 "${IP_VERSION}" 160 + 161 + ip -n "${RXNS}" addr add "${DSTIP}"/24 dev "${DSTIF}" 162 + ip -n "${RXNS}" link set "${DSTIF}" up 163 + 164 + ip -n "${TXNS}" addr add "${SRCIP}"/24 dev "${SRCIF}" 165 + ip -n "${TXNS}" link set "${SRCIF}" up 166 + } 167 + 168 + function test_enable_netpoll_on_enslaved_iface() { 169 + echo 0 > "${NETCONS_PATH}"/enabled 170 + 171 + # At this stage, BOND_TX1_SLAVE_IF is enslaved to BOND_TX_MAIN_IF, and 172 + # linked to BOND_RX1_SLAVE_IF inside the namespace. 173 + echo "${BOND_TX1_SLAVE_IF}" > "${NETCONS_PATH}"/dev_name 174 + 175 + # This should fail with the following message in dmesg: 176 + # netpoll: netconsole: ethX is a slave device, aborting 177 + set +e 178 + enable_netcons_ns 2> /dev/null 179 + set -e 180 + 181 + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 1 ]] 182 + then 183 + echo "test failed: Bonding and netpoll cannot co-exists." >&2 184 + exit "${ksft_fail}" 185 + fi 186 + } 187 + 188 + function test_delete_bond_and_reenable_target() { 189 + ip -n "${TXNS}" \ 190 + link delete "${BOND_TX_MAIN_IF}" type bond 191 + 192 + # BOND_TX1_SLAVE_IF is not attached to a bond interface anymore 193 + # netpoll can be plugged in there 194 + echo "${BOND_TX1_SLAVE_IF}" > "${NETCONS_PATH}"/dev_name 195 + 196 + # this should work, since the interface is not enslaved 197 + enable_netcons_ns 198 + 199 + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 0 ]] 200 + then 201 + echo "test failed: Unable to start netpoll on an unbond iface." >&2 202 + exit "${ksft_fail}" 203 + fi 204 + } 205 + 206 + # Send a netconsole message to the netconsole target 207 + function test_send_netcons_msg_through_bond_iface() { 208 + # Listen for netconsole port inside the namespace and 209 + # destination interface 210 + listen_port_and_save_to "${OUTPUT_FILE}" "${IP_VERSION}" & 211 + # Wait for socat to start and listen to the port. 212 + wait_for_port "${RXNS}" "${PORT}" "${IP_VERSION}" 213 + # Send the message 214 + echo "${MSG}: ${TARGET}" > /dev/kmsg 215 + # Wait until socat saves the file to disk 216 + busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}" 217 + # Make sure the message was received in the dst part 218 + # and exit 219 + validate_result "${OUTPUT_FILE}" "${FORMAT}" 220 + # kill socat in case it is still running 221 + pkill_socat 222 + } 223 + 224 + # BOND_TX1_SLAVE_IF has netconsole enabled on it, bind it to BOND_TX_MAIN_IF. 225 + # Given BOND_TX_MAIN_IF was deleted, recreate it first 226 + function test_enslave_netcons_enabled_iface { 227 + # netconsole got disabled while the interface was down 228 + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 0 ]] 229 + then 230 + echo "test failed: netconsole expected to be enabled against BOND_TX1_SLAVE_IF" >&2 231 + exit "${ksft_fail}" 232 + fi 233 + 234 + # recreate the bonding iface. it got deleted by previous 235 + # test (test_delete_bond_and_reenable_target) 236 + ip -n "${TXNS}" \ 237 + link add "${BOND_TX_MAIN_IF}" type bond mode balance-rr 238 + 239 + # sub-interface need to be down before attaching to bonding 240 + # This will also disable netconsole. 241 + ip -n "${TXNS}" \ 242 + link set "${BOND_TX1_SLAVE_IF}" down 243 + ip -n "${TXNS}" \ 244 + link set "${BOND_TX1_SLAVE_IF}" master "${BOND_TX_MAIN_IF}" 245 + ip -n "${TXNS}" \ 246 + link set "${BOND_TX_MAIN_IF}" up 247 + 248 + # netconsole got disabled while the interface was down 249 + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 1 ]] 250 + then 251 + echo "test failed: Device is part of a bond iface, cannot have netcons enabled" >&2 252 + exit "${ksft_fail}" 253 + fi 254 + } 255 + 256 + # Get netconsole enabled on a bonding interface and attach a second 257 + # sub-interface. 258 + function test_enslave_iface_to_bond { 259 + # BOND_TX_MAIN_IF has only BOND_TX1_SLAVE_IF right now 260 + echo "${BOND_TX_MAIN_IF}" > "${NETCONS_PATH}"/dev_name 261 + enable_netcons_ns 262 + 263 + # netcons is attached to bond0 and BOND_TX1_SLAVE_IF is 264 + # part of BOND_TX_MAIN_IF. Attach BOND_TX2_SLAVE_IF to BOND_TX_MAIN_IF. 265 + ip -n "${TXNS}" \ 266 + link set "${BOND_TX2_SLAVE_IF}" master "${BOND_TX_MAIN_IF}" 267 + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 0 ]] 268 + then 269 + echo "test failed: Netconsole should be enabled on bonding interface. Failed" >&2 270 + exit "${ksft_fail}" 271 + fi 272 + } 273 + 274 + function test_enslave_iff_disabled_netpoll_iface { 275 + local ret 276 + 277 + # Create two interfaces. veth interfaces it known to have 278 + # IFF_DISABLE_NETPOLL set 279 + if ! ip link add "${VETH0}" type veth peer name "${VETH1}" 280 + then 281 + echo "Failed to create veth TX interface. Is CONFIG_VETH set?" >&2 282 + exit "${ksft_skip}" 283 + fi 284 + set +e 285 + # This will print RTNETLINK answers: Device or resource busy 286 + ip link set "${VETH0}" master "${BOND_TX_MAIN_IF}" 2> /dev/null 287 + ret=$? 288 + set -e 289 + if [[ $ret -eq 0 ]] 290 + then 291 + echo "test failed: veth interface could not be enslaved" 292 + exit "${ksft_fail}" 293 + fi 294 + } 295 + 296 + # Given that netconsole picks the current net namespace, we need to enable it 297 + # from inside the TXNS namespace 298 + function enable_netcons_ns() { 299 + ip netns exec "${TXNS}" sh -c \ 300 + "mount -t configfs configfs /sys/kernel/config && echo 1 > $NETCONS_PATH/enabled" 301 + } 302 + 303 + #################### 304 + # Tests start here # 305 + #################### 306 + 307 + # Create regular interfaces using netdevsim and link them 308 + create_all_ifaces 309 + 310 + # Setup the bonding interfaces 311 + # BOND_RX_MAIN_IF has BOND_RX{1,2}_SLAVE_IF 312 + # BOND_TX_MAIN_IF has BOND_TX{1,2}_SLAVE_IF 313 + setup_bonding_ifaces 314 + 315 + # Configure the ips as BOND_RX1_SLAVE_IF and BOND_TX1_SLAVE_IF 316 + configure_ifaces_ips "${IP_VERSION}" 317 + 318 + _create_dynamic_target "${FORMAT}" "${NETCONS_PATH}" 319 + enable_netcons_ns 320 + set_user_data 321 + 322 + # Test #1 : Create an bonding interface and attach netpoll into 323 + # the bonding interface. Netconsole/netpoll should work on 324 + # the bonding interface. 325 + test_send_netcons_msg_through_bond_iface 326 + echo "test #1: netpoll on bonding interface worked. Test passed" >&2 327 + 328 + # Test #2: Attach netpoll to an enslaved interface 329 + # Try to attach netpoll to an enslaved sub-interface (while still being part of 330 + # a bonding interface), which shouldn't be allowed 331 + test_enable_netpoll_on_enslaved_iface 332 + echo "test #2: netpoll correctly rejected enslaved interface (expected behavior). Test passed." >&2 333 + 334 + # Test #3: Unplug the sub-interface from bond and enable netconsole 335 + # Detach the interface from a bonding interface and attach netpoll again 336 + test_delete_bond_and_reenable_target 337 + echo "test #3: Able to attach to an unbound interface. Test passed." >&2 338 + 339 + # Test #4: Enslave a sub-interface that had netconsole enabled 340 + # Try to enslave an interface that has netconsole/netpoll enabled. 341 + # Previous test has netconsole enabled in BOND_TX1_SLAVE_IF, try to enslave it 342 + test_enslave_netcons_enabled_iface 343 + echo "test #4: Enslaving an interface with netpoll attached. Test passed." >&2 344 + 345 + # Test #5: Enslave a sub-interface to a bonding interface 346 + # Enslave an interface to a bond interface that has netpoll attached 347 + # At this stage, BOND_TX_MAIN_IF is created and BOND_TX1_SLAVE_IF is part of 348 + # it. Netconsole is currently disabled 349 + test_enslave_iface_to_bond 350 + echo "test #5: Enslaving an interface to bond+netpoll. Test passed." >&2 351 + 352 + # Test #6: Enslave a IFF_DISABLE_NETPOLL sub-interface to a bonding interface 353 + # At this stage, BOND_TX_MAIN_IF has both sub interface and netconsole is 354 + # enabled. This test will try to enslave an a veth (IFF_DISABLE_NETPOLL) interface 355 + # and it should fail, with netpoll: veth0 doesn't support polling 356 + test_enslave_iff_disabled_netpoll_iface 357 + echo "test #6: Enslaving IFF_DISABLE_NETPOLL ifaces to bond iface is not supported. Test passed." >&2 358 + 359 + cleanup_bond 360 + trap - EXIT 361 + exit "${EXIT_STATUS}"
+63 -15
tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
··· 11 11 LIBDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") 12 12 13 13 SRCIF="" # to be populated later 14 + SRCIP="" # to be populated later 14 15 SRCIP4="192.0.2.1" 15 16 SRCIP6="fc00::1" 16 17 DSTIF="" # to be populated later 18 + DSTIP="" # to be populated later 17 19 DSTIP4="192.0.2.2" 18 20 DSTIP6="fc00::2" 19 21 ··· 30 28 # NAMESPACE will be populated by setup_ns with a random value 31 29 NAMESPACE="" 32 30 33 - # IDs for netdevsim 31 + # IDs for netdevsim. We either use NSIM_DEV_{1,2}_ID for standard test 32 + # or NSIM_BOND_{T,R}X_{1,2} for the bonding tests. Not both at the 33 + # same time. 34 34 NSIM_DEV_1_ID=$((256 + RANDOM % 256)) 35 35 NSIM_DEV_2_ID=$((512 + RANDOM % 256)) 36 + NSIM_BOND_TX_1=$((768 + RANDOM % 256)) 37 + NSIM_BOND_TX_2=$((1024 + RANDOM % 256)) 38 + NSIM_BOND_RX_1=$((1280 + RANDOM % 256)) 39 + NSIM_BOND_RX_2=$((1536 + RANDOM % 256)) 36 40 NSIM_DEV_SYS_NEW="/sys/bus/netdevsim/new_device" 41 + NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device" 37 42 38 43 # Used to create and delete namespaces 39 44 source "${LIBDIR}"/../../../../net/lib.sh 40 45 41 46 # Create netdevsim interfaces 42 47 create_ifaces() { 43 - 44 48 echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_NEW" 45 49 echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_NEW" 46 50 udevadm settle 2> /dev/null || true ··· 121 113 configure_ip 122 114 } 123 115 124 - function create_dynamic_target() { 125 - local FORMAT=${1:-"extended"} 116 + function _create_dynamic_target() { 117 + local FORMAT="${1:?FORMAT parameter required}" 118 + local NCPATH="${2:?NCPATH parameter required}" 126 119 127 120 DSTMAC=$(ip netns exec "${NAMESPACE}" \ 128 121 ip link show "${DSTIF}" | awk '/ether/ {print $2}') 129 122 130 123 # Create a dynamic target 131 - mkdir "${NETCONS_PATH}" 124 + mkdir "${NCPATH}" 132 125 133 - echo "${DSTIP}" > "${NETCONS_PATH}"/remote_ip 134 - echo "${SRCIP}" > "${NETCONS_PATH}"/local_ip 135 - echo "${DSTMAC}" > "${NETCONS_PATH}"/remote_mac 136 - echo "${SRCIF}" > "${NETCONS_PATH}"/dev_name 126 + echo "${DSTIP}" > "${NCPATH}"/remote_ip 127 + echo "${SRCIP}" > "${NCPATH}"/local_ip 128 + echo "${DSTMAC}" > "${NCPATH}"/remote_mac 129 + echo "${SRCIF}" > "${NCPATH}"/dev_name 137 130 138 131 if [ "${FORMAT}" == "basic" ] 139 132 then 140 133 # Basic target does not support release 141 - echo 0 > "${NETCONS_PATH}"/release 142 - echo 0 > "${NETCONS_PATH}"/extended 134 + echo 0 > "${NCPATH}"/release 135 + echo 0 > "${NCPATH}"/extended 143 136 elif [ "${FORMAT}" == "extended" ] 144 137 then 145 - echo 1 > "${NETCONS_PATH}"/extended 138 + echo 1 > "${NCPATH}"/extended 146 139 fi 140 + } 147 141 148 - echo 1 > "${NETCONS_PATH}"/enabled 142 + function create_dynamic_target() { 143 + local FORMAT=${1:-"extended"} 144 + local NCPATH=${2:-"$NETCONS_PATH"} 145 + _create_dynamic_target "${FORMAT}" "${NCPATH}" 146 + 147 + echo 1 > "${NCPATH}"/enabled 149 148 150 149 # This will make sure that the kernel was able to 151 150 # load the netconsole driver configuration. The console message ··· 200 185 echo "${DEFAULT_PRINTK_VALUES}" > /proc/sys/kernel/printk 201 186 } 202 187 203 - function cleanup() { 188 + function cleanup_netcons() { 204 189 # delete netconsole dynamic reconfiguration 205 - echo 0 > "${NETCONS_PATH}"/enabled 190 + # do not fail if the target is already disabled 191 + if [[ ! -d "${NETCONS_PATH}" ]] 192 + then 193 + # in some cases this is called before netcons path is created 194 + return 195 + fi 196 + if [[ $(cat "${NETCONS_PATH}"/enabled) != 0 ]] 197 + then 198 + echo 0 > "${NETCONS_PATH}"/enabled || true 199 + fi 206 200 # Remove all the keys that got created during the selftest 207 201 find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete 208 202 # Remove the configfs entry 209 203 rmdir "${NETCONS_PATH}" 204 + } 210 205 206 + function cleanup() { 207 + cleanup_netcons 211 208 do_cleanup 212 209 } 213 210 ··· 395 368 # otherwise the packet could be missed, and the test will fail. Happens 396 369 # more frequently on IPv6 397 370 sleep 1 371 + } 372 + 373 + # Clean up netdevsim ifaces created for bonding test 374 + function cleanup_bond_nsim() { 375 + ip -n "${TXNS}" \ 376 + link delete "${BOND_TX_MAIN_IF}" type bond || true 377 + ip -n "${RXNS}" \ 378 + link delete "${BOND_RX_MAIN_IF}" type bond || true 379 + 380 + cleanup_netdevsim "$NSIM_BOND_TX_1" 381 + cleanup_netdevsim "$NSIM_BOND_TX_2" 382 + cleanup_netdevsim "$NSIM_BOND_RX_1" 383 + cleanup_netdevsim "$NSIM_BOND_RX_2" 384 + } 385 + 386 + # cleanup tests that use bonding interfaces 387 + function cleanup_bond() { 388 + cleanup_netcons 389 + cleanup_bond_nsim 390 + cleanup_all_ns 391 + ip link delete "${VETH0}" || true 398 392 }
+130
tools/testing/selftests/drivers/net/netcons_torture.sh
··· 1 + #!/usr/bin/env bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # Repeatedly send kernel messages, toggles netconsole targets on and off, 5 + # creates and deletes targets in parallel, and toggles the source interface to 6 + # simulate stress conditions. 7 + # 8 + # This test aims to verify the robustness of netconsole under dynamic 9 + # configurations and concurrent operations. 10 + # 11 + # The major goal is to run this test with LOCKDEP, Kmemleak and KASAN to make 12 + # sure no issues is reported. 13 + # 14 + # Author: Breno Leitao <leitao@debian.org> 15 + 16 + set -euo pipefail 17 + 18 + SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") 19 + 20 + source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh 21 + 22 + # Number of times the main loop run 23 + ITERATIONS=${1:-150} 24 + 25 + # Only test extended format 26 + FORMAT="extended" 27 + # And ipv6 only 28 + IP_VERSION="ipv6" 29 + 30 + # Create, enable and delete some targets. 31 + create_and_delete_random_target() { 32 + COUNT=2 33 + RND_PREFIX=$(mktemp -u netcons_rnd_XXXX_) 34 + 35 + if [ -d "${NETCONS_CONFIGFS}/${RND_PREFIX}${COUNT}" ] || \ 36 + [ -d "${NETCONS_CONFIGFS}/${RND_PREFIX}0" ]; then 37 + echo "Function didn't finish yet, skipping it." >&2 38 + return 39 + fi 40 + 41 + # enable COUNT targets 42 + for i in $(seq ${COUNT}) 43 + do 44 + RND_TARGET="${RND_PREFIX}"${i} 45 + RND_TARGET_PATH="${NETCONS_CONFIGFS}"/"${RND_TARGET}" 46 + 47 + # Basic population so the target can come up 48 + _create_dynamic_target "${FORMAT}" "${RND_TARGET_PATH}" 49 + done 50 + 51 + echo "netconsole selftest: ${COUNT} additional targets were created" > /dev/kmsg 52 + # disable them all 53 + for i in $(seq ${COUNT}) 54 + do 55 + RND_TARGET="${RND_PREFIX}"${i} 56 + RND_TARGET_PATH="${NETCONS_CONFIGFS}"/"${RND_TARGET}" 57 + if [[ $(cat "${RND_TARGET_PATH}/enabled") -eq 1 ]] 58 + then 59 + echo 0 > "${RND_TARGET_PATH}"/enabled 60 + fi 61 + rmdir "${RND_TARGET_PATH}" 62 + done 63 + } 64 + 65 + # Disable and enable the target mid-air, while messages 66 + # are being transmitted. 67 + toggle_netcons_target() { 68 + for i in $(seq 2) 69 + do 70 + if [ ! -d "${NETCONS_PATH}" ] 71 + then 72 + break 73 + fi 74 + echo 0 > "${NETCONS_PATH}"/enabled 2> /dev/null || true 75 + # Try to enable a bit harder, given it might fail to enable 76 + # Write to `enabled` might fail depending on the lock, which is 77 + # highly contentious here 78 + for _ in $(seq 5) 79 + do 80 + echo 1 > "${NETCONS_PATH}"/enabled 2> /dev/null || true 81 + done 82 + done 83 + } 84 + 85 + toggle_iface(){ 86 + ip link set "${SRCIF}" down 87 + ip link set "${SRCIF}" up 88 + } 89 + 90 + # Start here 91 + 92 + modprobe netdevsim 2> /dev/null || true 93 + modprobe netconsole 2> /dev/null || true 94 + 95 + # Check for basic system dependency and exit if not found 96 + check_for_dependencies 97 + # Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5) 98 + echo "6 5" > /proc/sys/kernel/printk 99 + # Remove the namespace, interfaces and netconsole target on exit 100 + trap cleanup EXIT 101 + # Create one namespace and two interfaces 102 + set_network "${IP_VERSION}" 103 + # Create a dynamic target for netconsole 104 + create_dynamic_target "${FORMAT}" 105 + 106 + for i in $(seq "$ITERATIONS") 107 + do 108 + for _ in $(seq 10) 109 + do 110 + echo "${MSG}: ${TARGET} ${i}" > /dev/kmsg 111 + done 112 + wait 113 + 114 + if (( i % 30 == 0 )); then 115 + toggle_netcons_target & 116 + fi 117 + 118 + if (( i % 50 == 0 )); then 119 + # create some targets, enable them, send msg and disable 120 + # all in a parallel thread 121 + create_and_delete_random_target & 122 + fi 123 + 124 + if (( i % 70 == 0 )); then 125 + toggle_iface & 126 + fi 127 + done 128 + wait 129 + 130 + exit "${EXIT_STATUS}"