1#!/bin/bash -e 2# 3# SPDX-License-Identifier: GPL-2.0 4# 5# Torture nftables' netdevice notifier callbacks and related code by frequent 6# renaming of interfaces which netdev-family chains and flowtables hook into. 7 8source lib.sh 9 10checktool "nft --version" "run test without nft tool" 11checktool "iperf3 --version" "run test without iperf3 tool" 12 13read kernel_tainted < /proc/sys/kernel/tainted 14 15# how many seconds to torture the kernel? 16# default to 80% of max run time but don't exceed 48s 17TEST_RUNTIME=$((${kselftest_timeout:-60} * 8 / 10)) 18[[ $TEST_RUNTIME -gt 48 ]] && TEST_RUNTIME=48 19 20trap "cleanup_all_ns" EXIT 21 22setup_ns nsc nsr nss 23 24ip -net $nsc link add cr0 type veth peer name rc0 netns $nsr 25ip -net $nsc addr add 10.0.0.1/24 dev cr0 26ip -net $nsc link set cr0 up 27ip -net $nsc route add default via 10.0.0.2 28 29ip -net $nss link add sr0 type veth peer name rs0 netns $nsr 30ip -net $nss addr add 10.1.0.1/24 dev sr0 31ip -net $nss link set sr0 up 32ip -net $nss route add default via 10.1.0.2 33 34ip -net $nsr addr add 10.0.0.2/24 dev rc0 35ip -net $nsr link set rc0 up 36ip -net $nsr addr add 10.1.0.2/24 dev rs0 37ip -net $nsr link set rs0 up 38ip netns exec $nsr sysctl -q net.ipv4.ip_forward=1 39ip netns exec $nsr sysctl -q net.ipv4.conf.all.forwarding=1 40 41{ 42 echo "table netdev t {" 43 for ((i = 0; i < 10; i++)); do 44 cat <<-EOF 45 chain chain_rc$i { 46 type filter hook ingress device rc$i priority 0 47 counter 48 } 49 chain chain_rs$i { 50 type filter hook ingress device rs$i priority 0 51 counter 52 } 53 EOF 54 done 55 echo "}" 56 echo "table ip t {" 57 for ((i = 0; i < 10; i++)); do 58 cat <<-EOF 59 flowtable ft_${i} { 60 hook ingress priority 0 61 devices = { rc$i, rs$i } 62 } 63 EOF 64 done 65 echo "chain c {" 66 echo "type filter hook forward priority 0" 67 for ((i = 0; i < 10; i++)); do 68 echo -n "iifname rc$i oifname rs$i " 69 echo "ip protocol tcp counter flow add @ft_${i}" 70 done 71 echo "counter" 72 echo "}" 73 echo "}" 74} | ip netns exec $nsr nft -f - || { 75 echo "SKIP: Could not load nft ruleset" 76 exit $ksft_skip 77} 78 79for ((o=0, n=1; ; o=n, n++, n %= 10)); do 80 ip -net $nsr link set rc$o name rc$n 81 ip -net $nsr link set rs$o name rs$n 82done & 83rename_loop_pid=$! 84 85while true; do ip netns exec $nsr nft list ruleset >/dev/null 2>&1; done & 86nft_list_pid=$! 87 88ip netns exec $nsr nft monitor >/dev/null & 89nft_monitor_pid=$! 90 91ip netns exec $nss iperf3 --server --daemon -1 92summary_expr='s,^\[SUM\] .* \([0-9\.]\+\) Kbits/sec .* receiver,\1,p' 93rate=$(ip netns exec $nsc iperf3 \ 94 --format k -c 10.1.0.1 --time $TEST_RUNTIME \ 95 --length 56 --parallel 10 -i 0 | sed -n "$summary_expr") 96 97kill $nft_list_pid 98kill $nft_monitor_pid 99kill $rename_loop_pid 100wait 101 102wildcard_prep() { 103 ip netns exec $nsr nft -f - <<EOF 104table ip t { 105 flowtable ft_wild { 106 hook ingress priority 0 107 devices = { wild* } 108 } 109} 110EOF 111} 112 113if ! wildcard_prep; then 114 echo "SKIP wildcard tests: not supported by host's nft?" 115else 116 for ((i = 0; i < 100; i++)); do 117 ip -net $nsr link add wild$i type dummy & 118 done 119 wait 120 for ((i = 80; i < 100; i++)); do 121 ip -net $nsr link del wild$i & 122 done 123 for ((i = 0; i < 80; i++)); do 124 ip -net $nsr link del wild$i & 125 done 126 wait 127 for ((i = 0; i < 100; i += 10)); do 128 ( 129 for ((j = 0; j < 10; j++)); do 130 ip -net $nsr link add wild$((i + j)) type dummy 131 done 132 for ((j = 0; j < 10; j++)); do 133 ip -net $nsr link del wild$((i + j)) 134 done 135 ) & 136 done 137 wait 138fi 139 140 141[[ $kernel_tainted -eq 0 && $(</proc/sys/kernel/tainted) -ne 0 ]] && { 142 echo "FAIL: Kernel is tainted!" 143 exit $ksft_fail 144} 145 146[[ $rate -gt 0 ]] || { 147 echo "FAIL: Zero throughput in iperf3" 148 exit $ksft_fail 149} 150 151[[ -f /sys/kernel/debug/kmemleak && \ 152 -n $(</sys/kernel/debug/kmemleak) ]] && { 153 echo "FAIL: non-empty kmemleak report" 154 exit $ksft_fail 155} 156 157exit $ksft_pass 158