1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4lib_dir=$(dirname $0)/../../../net/forwarding 5 6ALL_TESTS=" 7 ipv4_route_addition_test 8 ipv4_route_deletion_test 9 ipv4_route_replacement_test 10 ipv4_route_offload_failed_test 11 ipv6_route_addition_test 12 ipv6_route_deletion_test 13 ipv6_route_replacement_test 14 ipv6_route_offload_failed_test 15" 16 17NETDEVSIM_PATH=/sys/bus/netdevsim/ 18DEV_ADDR=1337 19DEV=netdevsim${DEV_ADDR} 20DEVLINK_DEV=netdevsim/${DEV} 21SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/ 22DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/ 23NUM_NETIFS=0 24source $lib_dir/lib.sh 25 26check_rt_offload_failed() 27{ 28 local outfile=$1; shift 29 local line 30 31 # Make sure that the first notification was emitted without 32 # RTM_F_OFFLOAD_FAILED flag and the second with RTM_F_OFFLOAD_FAILED 33 # flag 34 head -n 1 $outfile | grep -q "rt_offload_failed" 35 if [[ $? -eq 0 ]]; then 36 return 1 37 fi 38 39 head -n 2 $outfile | tail -n 1 | grep -q "rt_offload_failed" 40} 41 42check_rt_trap() 43{ 44 local outfile=$1; shift 45 local line 46 47 # Make sure that the first notification was emitted without RTM_F_TRAP 48 # flag and the second with RTM_F_TRAP flag 49 head -n 1 $outfile | grep -q "rt_trap" 50 if [[ $? -eq 0 ]]; then 51 return 1 52 fi 53 54 head -n 2 $outfile | tail -n 1 | grep -q "rt_trap" 55} 56 57route_notify_check() 58{ 59 local outfile=$1; shift 60 local expected_num_lines=$1; shift 61 local offload_failed=${1:-0}; shift 62 63 # check the monitor results 64 lines=`wc -l $outfile | cut "-d " -f1` 65 test $lines -eq $expected_num_lines 66 check_err $? "$expected_num_lines notifications were expected but $lines were received" 67 68 if [[ $expected_num_lines -eq 1 ]]; then 69 return 70 fi 71 72 if [[ $offload_failed -eq 0 ]]; then 73 check_rt_trap $outfile 74 check_err $? "Wrong RTM_F_TRAP flags in notifications" 75 else 76 check_rt_offload_failed $outfile 77 check_err $? "Wrong RTM_F_OFFLOAD_FAILED flags in notifications" 78 fi 79} 80 81route_addition_check() 82{ 83 local ip=$1; shift 84 local notify=$1; shift 85 local route=$1; shift 86 local expected_num_notifications=$1; shift 87 local offload_failed=${1:-0}; shift 88 89 ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify 90 91 local outfile=$(mktemp) 92 93 $IP monitor route &> $outfile & 94 sleep 1 95 $IP route add $route dev dummy1 96 sleep 1 97 kill %% && wait %% &> /dev/null 98 99 route_notify_check $outfile $expected_num_notifications $offload_failed 100 rm -f $outfile 101 102 $IP route del $route dev dummy1 103} 104 105ipv4_route_addition_test() 106{ 107 RET=0 108 109 local ip="ipv4" 110 local route=192.0.2.0/24 111 112 # Make sure a single notification will be emitted for the programmed 113 # route. 114 local notify=0 115 local expected_num_notifications=1 116 # route_addition_check will assign value to RET. 117 route_addition_check $ip $notify $route $expected_num_notifications 118 119 # Make sure two notifications will be emitted for the programmed route. 120 notify=1 121 expected_num_notifications=2 122 route_addition_check $ip $notify $route $expected_num_notifications 123 124 # notify=2 means emit notifications only for failed route installation, 125 # make sure a single notification will be emitted for the programmed 126 # route. 127 notify=2 128 expected_num_notifications=1 129 route_addition_check $ip $notify $route $expected_num_notifications 130 131 log_test "IPv4 route addition" 132} 133 134route_deletion_check() 135{ 136 local ip=$1; shift 137 local notify=$1; shift 138 local route=$1; shift 139 local expected_num_notifications=$1; shift 140 141 ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify 142 $IP route add $route dev dummy1 143 sleep 1 144 145 local outfile=$(mktemp) 146 147 $IP monitor route &> $outfile & 148 sleep 1 149 $IP route del $route dev dummy1 150 sleep 1 151 kill %% && wait %% &> /dev/null 152 153 route_notify_check $outfile $expected_num_notifications 154 rm -f $outfile 155} 156 157ipv4_route_deletion_test() 158{ 159 RET=0 160 161 local ip="ipv4" 162 local route=192.0.2.0/24 163 local expected_num_notifications=1 164 165 # Make sure a single notification will be emitted for the deleted route, 166 # regardless of fib_notify_on_flag_change value. 167 local notify=0 168 # route_deletion_check will assign value to RET. 169 route_deletion_check $ip $notify $route $expected_num_notifications 170 171 notify=1 172 route_deletion_check $ip $notify $route $expected_num_notifications 173 174 log_test "IPv4 route deletion" 175} 176 177route_replacement_check() 178{ 179 local ip=$1; shift 180 local notify=$1; shift 181 local route=$1; shift 182 local expected_num_notifications=$1; shift 183 184 ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify 185 $IP route add $route dev dummy1 186 sleep 1 187 188 local outfile=$(mktemp) 189 190 $IP monitor route &> $outfile & 191 sleep 1 192 $IP route replace $route dev dummy2 193 sleep 1 194 kill %% && wait %% &> /dev/null 195 196 route_notify_check $outfile $expected_num_notifications 197 rm -f $outfile 198 199 $IP route del $route dev dummy2 200} 201 202ipv4_route_replacement_test() 203{ 204 RET=0 205 206 local ip="ipv4" 207 local route=192.0.2.0/24 208 209 $IP link add name dummy2 type dummy 210 $IP link set dev dummy2 up 211 212 # Make sure a single notification will be emitted for the new route. 213 local notify=0 214 local expected_num_notifications=1 215 # route_replacement_check will assign value to RET. 216 route_replacement_check $ip $notify $route $expected_num_notifications 217 218 # Make sure two notifications will be emitted for the new route. 219 notify=1 220 expected_num_notifications=2 221 route_replacement_check $ip $notify $route $expected_num_notifications 222 223 # notify=2 means emit notifications only for failed route installation, 224 # make sure a single notification will be emitted for the new route. 225 notify=2 226 expected_num_notifications=1 227 route_replacement_check $ip $notify $route $expected_num_notifications 228 229 $IP link del name dummy2 230 231 log_test "IPv4 route replacement" 232} 233 234ipv4_route_offload_failed_test() 235{ 236 237 RET=0 238 239 local ip="ipv4" 240 local route=192.0.2.0/24 241 local offload_failed=1 242 243 echo "y"> $DEBUGFS_DIR/fib/fail_route_offload 244 check_err $? "Failed to setup route offload to fail" 245 246 # Make sure a single notification will be emitted for the programmed 247 # route. 248 local notify=0 249 local expected_num_notifications=1 250 route_addition_check $ip $notify $route $expected_num_notifications \ 251 $offload_failed 252 253 # Make sure two notifications will be emitted for the new route. 254 notify=1 255 expected_num_notifications=2 256 route_addition_check $ip $notify $route $expected_num_notifications \ 257 $offload_failed 258 259 # notify=2 means emit notifications only for failed route installation, 260 # make sure two notifications will be emitted for the new route. 261 notify=2 262 expected_num_notifications=2 263 route_addition_check $ip $notify $route $expected_num_notifications \ 264 $offload_failed 265 266 echo "n"> $DEBUGFS_DIR/fib/fail_route_offload 267 check_err $? "Failed to setup route offload not to fail" 268 269 log_test "IPv4 route offload failed" 270} 271 272ipv6_route_addition_test() 273{ 274 RET=0 275 276 local ip="ipv6" 277 local route=2001:db8:1::/64 278 279 # Make sure a single notification will be emitted for the programmed 280 # route. 281 local notify=0 282 local expected_num_notifications=1 283 route_addition_check $ip $notify $route $expected_num_notifications 284 285 # Make sure two notifications will be emitted for the programmed route. 286 notify=1 287 expected_num_notifications=2 288 route_addition_check $ip $notify $route $expected_num_notifications 289 290 # notify=2 means emit notifications only for failed route installation, 291 # make sure a single notification will be emitted for the programmed 292 # route. 293 notify=2 294 expected_num_notifications=1 295 route_addition_check $ip $notify $route $expected_num_notifications 296 297 log_test "IPv6 route addition" 298} 299 300ipv6_route_deletion_test() 301{ 302 RET=0 303 304 local ip="ipv6" 305 local route=2001:db8:1::/64 306 local expected_num_notifications=1 307 308 # Make sure a single notification will be emitted for the deleted route, 309 # regardless of fib_notify_on_flag_change value. 310 local notify=0 311 route_deletion_check $ip $notify $route $expected_num_notifications 312 313 notify=1 314 route_deletion_check $ip $notify $route $expected_num_notifications 315 316 log_test "IPv6 route deletion" 317} 318 319ipv6_route_replacement_test() 320{ 321 RET=0 322 323 local ip="ipv6" 324 local route=2001:db8:1::/64 325 326 $IP link add name dummy2 type dummy 327 $IP link set dev dummy2 up 328 329 # Make sure a single notification will be emitted for the new route. 330 local notify=0 331 local expected_num_notifications=1 332 route_replacement_check $ip $notify $route $expected_num_notifications 333 334 # Make sure two notifications will be emitted for the new route. 335 notify=1 336 expected_num_notifications=2 337 route_replacement_check $ip $notify $route $expected_num_notifications 338 339 # notify=2 means emit notifications only for failed route installation, 340 # make sure a single notification will be emitted for the new route. 341 notify=2 342 expected_num_notifications=1 343 route_replacement_check $ip $notify $route $expected_num_notifications 344 345 $IP link del name dummy2 346 347 log_test "IPv6 route replacement" 348} 349 350ipv6_route_offload_failed_test() 351{ 352 353 RET=0 354 355 local ip="ipv6" 356 local route=2001:db8:1::/64 357 local offload_failed=1 358 359 echo "y"> $DEBUGFS_DIR/fib/fail_route_offload 360 check_err $? "Failed to setup route offload to fail" 361 362 # Make sure a single notification will be emitted for the programmed 363 # route. 364 local notify=0 365 local expected_num_notifications=1 366 route_addition_check $ip $notify $route $expected_num_notifications \ 367 $offload_failed 368 369 # Make sure two notifications will be emitted for the new route. 370 notify=1 371 expected_num_notifications=2 372 route_addition_check $ip $notify $route $expected_num_notifications \ 373 $offload_failed 374 375 # notify=2 means emit notifications only for failed route installation, 376 # make sure two notifications will be emitted for the new route. 377 notify=2 378 expected_num_notifications=2 379 route_addition_check $ip $notify $route $expected_num_notifications \ 380 $offload_failed 381 382 echo "n"> $DEBUGFS_DIR/fib/fail_route_offload 383 check_err $? "Failed to setup route offload not to fail" 384 385 log_test "IPv6 route offload failed" 386} 387 388setup_prepare() 389{ 390 modprobe netdevsim &> /dev/null 391 echo "$DEV_ADDR 1" > ${NETDEVSIM_PATH}/new_device 392 while [ ! -d $SYSFS_NET_DIR ] ; do :; done 393 394 ip netns add testns1 395 396 if [ $? -ne 0 ]; then 397 echo "Failed to add netns \"testns1\"" 398 exit 1 399 fi 400 401 devlink dev reload $DEVLINK_DEV netns testns1 402 403 if [ $? -ne 0 ]; then 404 echo "Failed to reload into netns \"testns1\"" 405 exit 1 406 fi 407 408 IP="ip -n testns1" 409 410 $IP link add name dummy1 type dummy 411 $IP link set dev dummy1 up 412} 413 414cleanup() 415{ 416 pre_cleanup 417 418 $IP link del name dummy1 419 ip netns del testns1 420 echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device 421 modprobe -r netdevsim &> /dev/null 422} 423 424trap cleanup EXIT 425 426setup_prepare 427 428tests_run 429 430exit $EXIT_STATUS 431