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