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 # re-add the alias -- kernel should free mem when dummy dev is removed 282 ip link set dev "$devdummy" alias "$namewant" 283 check_err $? 284 fi 285 286 if [ $ret -ne 0 ]; then 287 echo "FAIL: set interface alias $devdummy to $namewant" 288 return 1 289 fi 290 291 echo "PASS: set ifalias $namewant for $devdummy" 292} 293 294kci_test_vrf() 295{ 296 vrfname="test-vrf" 297 ret=0 298 299 ip link show type vrf 2>/dev/null 300 if [ $? -ne 0 ]; then 301 echo "SKIP: vrf: iproute2 too old" 302 return 0 303 fi 304 305 ip link add "$vrfname" type vrf table 10 306 check_err $? 307 if [ $ret -ne 0 ];then 308 echo "FAIL: can't add vrf interface, skipping test" 309 return 0 310 fi 311 312 ip -br link show type vrf | grep -q "$vrfname" 313 check_err $? 314 if [ $ret -ne 0 ];then 315 echo "FAIL: created vrf device not found" 316 return 1 317 fi 318 319 ip link set dev "$vrfname" up 320 check_err $? 321 322 ip link set dev "$devdummy" master "$vrfname" 323 check_err $? 324 ip link del dev "$vrfname" 325 check_err $? 326 327 if [ $ret -ne 0 ];then 328 echo "FAIL: vrf" 329 return 1 330 fi 331 332 echo "PASS: vrf" 333} 334 335kci_test_encap_vxlan() 336{ 337 ret=0 338 vxlan="test-vxlan0" 339 vlan="test-vlan0" 340 testns="$1" 341 342 ip netns exec "$testns" ip link add "$vxlan" type vxlan id 42 group 239.1.1.1 \ 343 dev "$devdummy" dstport 4789 2>/dev/null 344 if [ $? -ne 0 ]; then 345 echo "FAIL: can't add vxlan interface, skipping test" 346 return 0 347 fi 348 check_err $? 349 350 ip netns exec "$testns" ip addr add 10.2.11.49/24 dev "$vxlan" 351 check_err $? 352 353 ip netns exec "$testns" ip link set up dev "$vxlan" 354 check_err $? 355 356 ip netns exec "$testns" ip link add link "$vxlan" name "$vlan" type vlan id 1 357 check_err $? 358 359 ip netns exec "$testns" ip link del "$vxlan" 360 check_err $? 361 362 if [ $ret -ne 0 ]; then 363 echo "FAIL: vxlan" 364 return 1 365 fi 366 echo "PASS: vxlan" 367} 368 369kci_test_encap_fou() 370{ 371 ret=0 372 name="test-fou" 373 testns="$1" 374 375 ip fou help 2>&1 |grep -q 'Usage: ip fou' 376 if [ $? -ne 0 ];then 377 echo "SKIP: fou: iproute2 too old" 378 return 1 379 fi 380 381 ip netns exec "$testns" ip fou add port 7777 ipproto 47 2>/dev/null 382 if [ $? -ne 0 ];then 383 echo "FAIL: can't add fou port 7777, skipping test" 384 return 1 385 fi 386 387 ip netns exec "$testns" ip fou add port 8888 ipproto 4 388 check_err $? 389 390 ip netns exec "$testns" ip fou del port 9999 2>/dev/null 391 check_fail $? 392 393 ip netns exec "$testns" ip fou del port 7777 394 check_err $? 395 396 if [ $ret -ne 0 ]; then 397 echo "FAIL: fou" 398 return 1 399 fi 400 401 echo "PASS: fou" 402} 403 404# test various encap methods, use netns to avoid unwanted interference 405kci_test_encap() 406{ 407 testns="testns" 408 ret=0 409 410 ip netns add "$testns" 411 if [ $? -ne 0 ]; then 412 echo "SKIP encap tests: cannot add net namespace $testns" 413 return 1 414 fi 415 416 ip netns exec "$testns" ip link set lo up 417 check_err $? 418 419 ip netns exec "$testns" ip link add name "$devdummy" type dummy 420 check_err $? 421 ip netns exec "$testns" ip link set "$devdummy" up 422 check_err $? 423 424 kci_test_encap_vxlan "$testns" 425 kci_test_encap_fou "$testns" 426 427 ip netns del "$testns" 428} 429 430kci_test_rtnl() 431{ 432 kci_add_dummy 433 if [ $ret -ne 0 ];then 434 echo "FAIL: cannot add dummy interface" 435 return 1 436 fi 437 438 kci_test_polrouting 439 kci_test_route_get 440 kci_test_tc 441 kci_test_gre 442 kci_test_bridge 443 kci_test_addrlabel 444 kci_test_ifalias 445 kci_test_vrf 446 kci_test_encap 447 448 kci_del_dummy 449} 450 451#check for needed privileges 452if [ "$(id -u)" -ne 0 ];then 453 echo "SKIP: Need root privileges" 454 exit 0 455fi 456 457for x in ip tc;do 458 $x -Version 2>/dev/null >/dev/null 459 if [ $? -ne 0 ];then 460 echo "SKIP: Could not run test without the $x tool" 461 exit 0 462 fi 463done 464 465kci_test_rtnl 466 467exit $ret 468