1#!/bin/sh 2# 3# This test is for checking rtnetlink callpaths, and get as much coverage as possible. 4# 5# set -e 6 7devdummy="test-dummy0" 8ret=0 9 10# set global exit status, but never reset nonzero one. 11check_err() 12{ 13 if [ $ret -eq 0 ]; then 14 ret=$1 15 fi 16} 17 18# same but inverted -- used when command must fail for test to pass 19check_fail() 20{ 21 if [ $1 -eq 0 ]; then 22 ret=1 23 fi 24} 25 26kci_add_dummy() 27{ 28 ip link add name "$devdummy" type dummy 29 check_err $? 30 ip link set "$devdummy" up 31 check_err $? 32} 33 34kci_del_dummy() 35{ 36 ip link del dev "$devdummy" 37 check_err $? 38} 39 40# add a bridge with vlans on top 41kci_test_bridge() 42{ 43 devbr="test-br0" 44 vlandev="testbr-vlan1" 45 46 ret=0 47 ip link add name "$devbr" type bridge 48 check_err $? 49 50 ip link set dev "$devdummy" master "$devbr" 51 check_err $? 52 53 ip link set "$devbr" up 54 check_err $? 55 56 ip link add link "$devbr" name "$vlandev" type vlan id 1 57 check_err $? 58 ip addr add dev "$vlandev" 10.200.7.23/30 59 check_err $? 60 ip -6 addr add dev "$vlandev" dead:42::1234/64 61 check_err $? 62 ip -d link > /dev/null 63 check_err $? 64 ip r s t all > /dev/null 65 check_err $? 66 ip -6 addr del dev "$vlandev" dead:42::1234/64 67 check_err $? 68 69 ip link del dev "$vlandev" 70 check_err $? 71 ip link del dev "$devbr" 72 check_err $? 73 74 if [ $ret -ne 0 ];then 75 echo "FAIL: bridge setup" 76 return 1 77 fi 78 echo "PASS: bridge setup" 79 80} 81 82kci_test_gre() 83{ 84 gredev=neta 85 rem=10.42.42.1 86 loc=10.0.0.1 87 88 ret=0 89 ip tunnel add $gredev mode gre remote $rem local $loc ttl 1 90 check_err $? 91 ip link set $gredev up 92 check_err $? 93 ip addr add 10.23.7.10 dev $gredev 94 check_err $? 95 ip route add 10.23.8.0/30 dev $gredev 96 check_err $? 97 ip addr add dev "$devdummy" 10.23.7.11/24 98 check_err $? 99 ip link > /dev/null 100 check_err $? 101 ip addr > /dev/null 102 check_err $? 103 ip addr del dev "$devdummy" 10.23.7.11/24 104 check_err $? 105 106 ip link del $gredev 107 check_err $? 108 109 if [ $ret -ne 0 ];then 110 echo "FAIL: gre tunnel endpoint" 111 return 1 112 fi 113 echo "PASS: gre tunnel endpoint" 114} 115 116# tc uses rtnetlink too, for full tc testing 117# please see tools/testing/selftests/tc-testing. 118kci_test_tc() 119{ 120 dev=lo 121 ret=0 122 123 tc qdisc add dev "$dev" root handle 1: htb 124 check_err $? 125 tc class add dev "$dev" parent 1: classid 1:10 htb rate 1mbit 126 check_err $? 127 tc filter add dev "$dev" parent 1:0 prio 5 handle ffe: protocol ip u32 divisor 256 128 check_err $? 129 tc filter add dev "$dev" parent 1:0 prio 5 handle ffd: protocol ip u32 divisor 256 130 check_err $? 131 tc filter add dev "$dev" parent 1:0 prio 5 handle ffc: protocol ip u32 divisor 256 132 check_err $? 133 tc filter add dev "$dev" protocol ip parent 1: prio 5 handle ffe:2:3 u32 ht ffe:2: match ip src 10.0.0.3 flowid 1:10 134 check_err $? 135 tc filter add dev "$dev" protocol ip parent 1: prio 5 handle ffe:2:2 u32 ht ffe:2: match ip src 10.0.0.2 flowid 1:10 136 check_err $? 137 tc filter show dev "$dev" parent 1:0 > /dev/null 138 check_err $? 139 tc filter del dev "$dev" protocol ip parent 1: prio 5 handle ffe:2:3 u32 140 check_err $? 141 tc filter show dev "$dev" parent 1:0 > /dev/null 142 check_err $? 143 tc qdisc del dev "$dev" root handle 1: htb 144 check_err $? 145 146 if [ $ret -ne 0 ];then 147 echo "FAIL: tc htb hierarchy" 148 return 1 149 fi 150 echo "PASS: tc htb hierarchy" 151 152} 153 154kci_test_polrouting() 155{ 156 ret=0 157 ip rule add fwmark 1 lookup 100 158 check_err $? 159 ip route add local 0.0.0.0/0 dev lo table 100 160 check_err $? 161 ip r s t all > /dev/null 162 check_err $? 163 ip rule del fwmark 1 lookup 100 164 check_err $? 165 ip route del local 0.0.0.0/0 dev lo table 100 166 check_err $? 167 168 if [ $ret -ne 0 ];then 169 echo "FAIL: policy route test" 170 return 1 171 fi 172 echo "PASS: policy routing" 173} 174 175kci_test_route_get() 176{ 177 ret=0 178 179 ip route get 127.0.0.1 > /dev/null 180 check_err $? 181 ip route get 127.0.0.1 dev "$devdummy" > /dev/null 182 check_err $? 183 ip route get ::1 > /dev/null 184 check_err $? 185 ip route get fe80::1 dev "$devdummy" > /dev/null 186 check_err $? 187 ip route get 127.0.0.1 from 127.0.0.1 oif lo tos 0x1 mark 0x1 > /dev/null 188 check_err $? 189 ip route get ::1 from ::1 iif lo oif lo tos 0x1 mark 0x1 > /dev/null 190 check_err $? 191 ip addr add dev "$devdummy" 10.23.7.11/24 192 check_err $? 193 ip route get 10.23.7.11 from 10.23.7.12 iif "$devdummy" > /dev/null 194 check_err $? 195 ip addr del dev "$devdummy" 10.23.7.11/24 196 check_err $? 197 198 if [ $ret -ne 0 ];then 199 echo "FAIL: route get" 200 return 1 201 fi 202 203 echo "PASS: route get" 204} 205 206kci_test_addrlabel() 207{ 208 ret=0 209 210 ip addrlabel add prefix dead::/64 dev lo label 1 211 check_err $? 212 213 ip addrlabel list |grep -q "prefix dead::/64 dev lo label 1" 214 check_err $? 215 216 ip addrlabel del prefix dead::/64 dev lo label 1 2> /dev/null 217 check_err $? 218 219 ip addrlabel add prefix dead::/64 label 1 2> /dev/null 220 check_err $? 221 222 ip addrlabel del prefix dead::/64 label 1 2> /dev/null 223 check_err $? 224 225 # concurrent add/delete 226 for i in $(seq 1 1000); do 227 ip addrlabel add prefix 1c3::/64 label 12345 2>/dev/null 228 done & 229 230 for i in $(seq 1 1000); do 231 ip addrlabel del prefix 1c3::/64 label 12345 2>/dev/null 232 done 233 234 wait 235 236 ip addrlabel del prefix 1c3::/64 label 12345 2>/dev/null 237 238 if [ $ret -ne 0 ];then 239 echo "FAIL: ipv6 addrlabel" 240 return 1 241 fi 242 243 echo "PASS: ipv6 addrlabel" 244} 245 246kci_test_ifalias() 247{ 248 ret=0 249 namewant=$(uuidgen) 250 syspathname="/sys/class/net/$devdummy/ifalias" 251 252 ip link set dev "$devdummy" alias "$namewant" 253 check_err $? 254 255 if [ $ret -ne 0 ]; then 256 echo "FAIL: cannot set interface alias of $devdummy to $namewant" 257 return 1 258 fi 259 260 ip link show "$devdummy" | grep -q "alias $namewant" 261 check_err $? 262 263 if [ -r "$syspathname" ] ; then 264 read namehave < "$syspathname" 265 if [ "$namewant" != "$namehave" ]; then 266 echo "FAIL: did set ifalias $namewant but got $namehave" 267 return 1 268 fi 269 270 namewant=$(uuidgen) 271 echo "$namewant" > "$syspathname" 272 ip link show "$devdummy" | grep -q "alias $namewant" 273 check_err $? 274 275 # sysfs interface allows to delete alias again 276 echo "" > "$syspathname" 277 278 ip link show "$devdummy" | grep -q "alias $namewant" 279 check_fail $? 280 281 for i in $(seq 1 100); do 282 uuidgen > "$syspathname" & 283 done 284 285 wait 286 287 # re-add the alias -- kernel should free mem when dummy dev is removed 288 ip link set dev "$devdummy" alias "$namewant" 289 check_err $? 290 fi 291 292 if [ $ret -ne 0 ]; then 293 echo "FAIL: set interface alias $devdummy to $namewant" 294 return 1 295 fi 296 297 echo "PASS: set ifalias $namewant for $devdummy" 298} 299 300kci_test_vrf() 301{ 302 vrfname="test-vrf" 303 ret=0 304 305 ip link show type vrf 2>/dev/null 306 if [ $? -ne 0 ]; then 307 echo "SKIP: vrf: iproute2 too old" 308 return 0 309 fi 310 311 ip link add "$vrfname" type vrf table 10 312 check_err $? 313 if [ $ret -ne 0 ];then 314 echo "FAIL: can't add vrf interface, skipping test" 315 return 0 316 fi 317 318 ip -br link show type vrf | grep -q "$vrfname" 319 check_err $? 320 if [ $ret -ne 0 ];then 321 echo "FAIL: created vrf device not found" 322 return 1 323 fi 324 325 ip link set dev "$vrfname" up 326 check_err $? 327 328 ip link set dev "$devdummy" master "$vrfname" 329 check_err $? 330 ip link del dev "$vrfname" 331 check_err $? 332 333 if [ $ret -ne 0 ];then 334 echo "FAIL: vrf" 335 return 1 336 fi 337 338 echo "PASS: vrf" 339} 340 341kci_test_encap_vxlan() 342{ 343 ret=0 344 vxlan="test-vxlan0" 345 vlan="test-vlan0" 346 testns="$1" 347 348 ip netns exec "$testns" ip link add "$vxlan" type vxlan id 42 group 239.1.1.1 \ 349 dev "$devdummy" dstport 4789 2>/dev/null 350 if [ $? -ne 0 ]; then 351 echo "FAIL: can't add vxlan interface, skipping test" 352 return 0 353 fi 354 check_err $? 355 356 ip netns exec "$testns" ip addr add 10.2.11.49/24 dev "$vxlan" 357 check_err $? 358 359 ip netns exec "$testns" ip link set up dev "$vxlan" 360 check_err $? 361 362 ip netns exec "$testns" ip link add link "$vxlan" name "$vlan" type vlan id 1 363 check_err $? 364 365 ip netns exec "$testns" ip link del "$vxlan" 366 check_err $? 367 368 if [ $ret -ne 0 ]; then 369 echo "FAIL: vxlan" 370 return 1 371 fi 372 echo "PASS: vxlan" 373} 374 375kci_test_encap_fou() 376{ 377 ret=0 378 name="test-fou" 379 testns="$1" 380 381 ip fou help 2>&1 |grep -q 'Usage: ip fou' 382 if [ $? -ne 0 ];then 383 echo "SKIP: fou: iproute2 too old" 384 return 1 385 fi 386 387 ip netns exec "$testns" ip fou add port 7777 ipproto 47 2>/dev/null 388 if [ $? -ne 0 ];then 389 echo "FAIL: can't add fou port 7777, skipping test" 390 return 1 391 fi 392 393 ip netns exec "$testns" ip fou add port 8888 ipproto 4 394 check_err $? 395 396 ip netns exec "$testns" ip fou del port 9999 2>/dev/null 397 check_fail $? 398 399 ip netns exec "$testns" ip fou del port 7777 400 check_err $? 401 402 if [ $ret -ne 0 ]; then 403 echo "FAIL: fou" 404 return 1 405 fi 406 407 echo "PASS: fou" 408} 409 410# test various encap methods, use netns to avoid unwanted interference 411kci_test_encap() 412{ 413 testns="testns" 414 ret=0 415 416 ip netns add "$testns" 417 if [ $? -ne 0 ]; then 418 echo "SKIP encap tests: cannot add net namespace $testns" 419 return 1 420 fi 421 422 ip netns exec "$testns" ip link set lo up 423 check_err $? 424 425 ip netns exec "$testns" ip link add name "$devdummy" type dummy 426 check_err $? 427 ip netns exec "$testns" ip link set "$devdummy" up 428 check_err $? 429 430 kci_test_encap_vxlan "$testns" 431 kci_test_encap_fou "$testns" 432 433 ip netns del "$testns" 434} 435 436kci_test_rtnl() 437{ 438 kci_add_dummy 439 if [ $ret -ne 0 ];then 440 echo "FAIL: cannot add dummy interface" 441 return 1 442 fi 443 444 kci_test_polrouting 445 kci_test_route_get 446 kci_test_tc 447 kci_test_gre 448 kci_test_bridge 449 kci_test_addrlabel 450 kci_test_ifalias 451 kci_test_vrf 452 kci_test_encap 453 454 kci_del_dummy 455} 456 457#check for needed privileges 458if [ "$(id -u)" -ne 0 ];then 459 echo "SKIP: Need root privileges" 460 exit 0 461fi 462 463for x in ip tc;do 464 $x -Version 2>/dev/null >/dev/null 465 if [ $? -ne 0 ];then 466 echo "SKIP: Could not run test without the $x tool" 467 exit 0 468 fi 469done 470 471kci_test_rtnl 472 473exit $ret 474