File Index
Files and directories
Sign in
FILE

rtnetlink.sh

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/rtnetlink.sh BASH
   1#!/bin/bash
   2#
   3# This test is for checking rtnetlink callpaths, and get as much coverage as possible.
   4#
   5# set -e
   6
   7ALL_TESTS="
   8	kci_test_polrouting
   9	kci_test_route_get
  10	kci_test_addrlft
  11	kci_test_addrlft_route_cleanup
  12	kci_test_promote_secondaries
  13	kci_test_tc
  14	kci_test_gre
  15	kci_test_gretap
  16	kci_test_ip6gretap
  17	kci_test_erspan
  18	kci_test_ip6erspan
  19	kci_test_bridge
  20	kci_test_addrlabel
  21	kci_test_ifalias
  22	kci_test_vrf
  23	kci_test_encap
  24	kci_test_macsec
  25	kci_test_macsec_vlan
  26	kci_test_ipsec
  27	kci_test_ipsec_offload
  28	kci_test_fdb_get
  29	kci_test_fdb_del
  30	kci_test_neigh_get
  31	kci_test_bridge_parent_id
  32	kci_test_address_proto
  33	kci_test_enslave_bonding
  34	kci_test_mngtmpaddr
  35	kci_test_operstate
  36"
  37
  38devdummy="test-dummy0"
  39VERBOSE=0
  40PAUSE=no
  41PAUSE_ON_FAIL=no
  42
  43source lib.sh
  44
  45# set global exit status, but never reset nonzero one.
  46check_err()
  47{
  48	if [ $ret -eq 0 ]; then
  49		ret=$1
  50	fi
  51	[ -n "$2" ] && echo "$2"
  52}
  53
  54# same but inverted -- used when command must fail for test to pass
  55check_fail()
  56{
  57	if [ $1 -eq 0 ]; then
  58		ret=1
  59	fi
  60}
  61
  62run_cmd_common()
  63{
  64	local cmd="$*"
  65	local out
  66	if [ "$VERBOSE" = "1" ]; then
  67		echo "COMMAND: ${cmd}"
  68	fi
  69	out=$($cmd 2>&1)
  70	rc=$?
  71	if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  72		echo "    $out"
  73	fi
  74	return $rc
  75}
  76
  77run_cmd() {
  78	run_cmd_common "$@"
  79	rc=$?
  80	check_err $rc
  81	return $rc
  82}
  83run_cmd_fail()
  84{
  85	run_cmd_common "$@"
  86	rc=$?
  87	check_fail $rc
  88	return $rc
  89}
  90
  91run_cmd_grep_common()
  92{
  93	local find="$1"; shift
  94	local cmd="$*"
  95	local out
  96	if [ "$VERBOSE" = "1" ]; then
  97		echo "COMMAND: ${cmd} 2>&1 | grep -q '${find}'"
  98	fi
  99	out=$($cmd 2>&1 | grep -q "${find}" 2>&1)
 100	return $?
 101}
 102
 103run_cmd_grep() {
 104	run_cmd_grep_common "$@"
 105	rc=$?
 106	check_err $rc
 107	return $rc
 108}
 109
 110run_cmd_grep_fail()
 111{
 112	run_cmd_grep_common "$@"
 113	rc=$?
 114	check_fail $rc
 115	return $rc
 116}
 117
 118end_test()
 119{
 120	echo "$*"
 121	[ "${VERBOSE}" = "1" ] && echo
 122
 123	if [[ $ret -ne 0 ]] && [[ "${PAUSE_ON_FAIL}" = "yes" ]]; then
 124		echo "Hit enter to continue"
 125		read a
 126	fi;
 127
 128	if [ "${PAUSE}" = "yes" ]; then
 129		echo "Hit enter to continue"
 130		read a
 131	fi
 132
 133}
 134
 135
 136kci_add_dummy()
 137{
 138	run_cmd ip link add name "$devdummy" type dummy
 139	run_cmd ip link set "$devdummy" up
 140}
 141
 142kci_del_dummy()
 143{
 144	run_cmd ip link del dev "$devdummy"
 145}
 146
 147kci_test_netconf()
 148{
 149	dev="$1"
 150	r=$ret
 151	run_cmd ip netconf show dev "$dev"
 152	for f in 4 6; do
 153		run_cmd ip -$f netconf show dev "$dev"
 154	done
 155
 156	if [ $ret -ne 0 ] ;then
 157		end_test "FAIL: ip netconf show $dev"
 158		test $r -eq 0 && ret=0
 159		return 1
 160	fi
 161}
 162
 163# add a bridge with vlans on top
 164kci_test_bridge()
 165{
 166	devbr="test-br0"
 167	vlandev="testbr-vlan1"
 168
 169	local ret=0
 170	run_cmd ip link add name "$devbr" type bridge
 171	run_cmd ip link set dev "$devdummy" master "$devbr"
 172	run_cmd ip link set "$devbr" up
 173	run_cmd ip link add link "$devbr" name "$vlandev" type vlan id 1
 174	run_cmd ip addr add dev "$vlandev" 10.200.7.23/30
 175	run_cmd ip -6 addr add dev "$vlandev" dead:42::1234/64
 176	run_cmd ip -d link
 177	run_cmd ip r s t all
 178
 179	for name in "$devbr" "$vlandev" "$devdummy" ; do
 180		kci_test_netconf "$name"
 181	done
 182	run_cmd ip -6 addr del dev "$vlandev" dead:42::1234/64
 183	run_cmd ip link del dev "$vlandev"
 184	run_cmd ip link del dev "$devbr"
 185
 186	if [ $ret -ne 0 ];then
 187		end_test "FAIL: bridge setup"
 188		return 1
 189	fi
 190	end_test "PASS: bridge setup"
 191
 192}
 193
 194kci_test_gre()
 195{
 196	gredev=neta
 197	rem=10.42.42.1
 198	loc=10.0.0.1
 199
 200	local ret=0
 201	run_cmd ip tunnel add $gredev mode gre remote $rem local $loc ttl 1
 202	run_cmd ip link set $gredev up
 203	run_cmd ip addr add 10.23.7.10 dev $gredev
 204	run_cmd ip route add 10.23.8.0/30 dev $gredev
 205	run_cmd ip addr add dev "$devdummy" 10.23.7.11/24
 206	run_cmd ip link
 207	run_cmd ip addr
 208
 209	kci_test_netconf "$gredev"
 210	run_cmd ip addr del dev "$devdummy" 10.23.7.11/24
 211	run_cmd ip link del $gredev
 212
 213	if [ $ret -ne 0 ];then
 214		end_test "FAIL: gre tunnel endpoint"
 215		return 1
 216	fi
 217	end_test "PASS: gre tunnel endpoint"
 218}
 219
 220# tc uses rtnetlink too, for full tc testing
 221# please see tools/testing/selftests/tc-testing.
 222kci_test_tc()
 223{
 224	dev=lo
 225	local ret=0
 226
 227	run_cmd tc qdisc add dev "$dev" root handle 1: htb
 228	run_cmd tc class add dev "$dev" parent 1: classid 1:10 htb rate 1mbit
 229	run_cmd tc filter add dev "$dev" parent 1:0 prio 5 handle ffe: protocol ip u32 divisor 256
 230	run_cmd tc filter add dev "$dev" parent 1:0 prio 5 handle ffd: protocol ip u32 divisor 256
 231	run_cmd tc filter add dev "$dev" parent 1:0 prio 5 handle ffc: protocol ip u32 divisor 256
 232	run_cmd 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
 233	run_cmd 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
 234	run_cmd tc filter show dev "$dev" parent  1:0
 235	run_cmd tc filter del dev "$dev" protocol ip parent 1: prio 5 handle ffe:2:3 u32
 236	run_cmd tc filter show dev "$dev" parent  1:0
 237	run_cmd tc qdisc del dev "$dev" root handle 1: htb
 238
 239	if [ $ret -ne 0 ];then
 240		end_test "FAIL: tc htb hierarchy"
 241		return 1
 242	fi
 243	end_test "PASS: tc htb hierarchy"
 244
 245}
 246
 247kci_test_polrouting()
 248{
 249	local ret=0
 250	run_cmd ip rule add fwmark 1 lookup 100
 251	run_cmd ip route add local 0.0.0.0/0 dev lo table 100
 252	run_cmd ip r s t all
 253	run_cmd ip rule del fwmark 1 lookup 100
 254	run_cmd ip route del local 0.0.0.0/0 dev lo table 100
 255
 256	if [ $ret -ne 0 ];then
 257		end_test "FAIL: policy route test"
 258		return 1
 259	fi
 260	end_test "PASS: policy routing"
 261}
 262
 263kci_test_route_get()
 264{
 265	local hash_policy=$(sysctl -n net.ipv4.fib_multipath_hash_policy)
 266
 267	local ret=0
 268	run_cmd ip route get 127.0.0.1
 269	run_cmd ip route get 127.0.0.1 dev "$devdummy"
 270	run_cmd ip route get ::1
 271	run_cmd ip route get fe80::1 dev "$devdummy"
 272	run_cmd ip route get 127.0.0.1 from 127.0.0.1 oif lo tos 0x10 mark 0x1
 273	run_cmd ip route get ::1 from ::1 iif lo oif lo tos 0x10 mark 0x1
 274	run_cmd ip addr add dev "$devdummy" 10.23.7.11/24
 275	run_cmd ip route get 10.23.7.11 from 10.23.7.12 iif "$devdummy"
 276	run_cmd ip route add 10.23.8.0/24 \
 277		nexthop via 10.23.7.13 dev "$devdummy" \
 278		nexthop via 10.23.7.14 dev "$devdummy"
 279
 280	sysctl -wq net.ipv4.fib_multipath_hash_policy=0
 281	run_cmd ip route get 10.23.8.11
 282	sysctl -wq net.ipv4.fib_multipath_hash_policy=1
 283	run_cmd ip route get 10.23.8.11
 284	sysctl -wq net.ipv4.fib_multipath_hash_policy="$hash_policy"
 285	run_cmd ip route del 10.23.8.0/24
 286	run_cmd ip addr del dev "$devdummy" 10.23.7.11/24
 287
 288
 289	if [ $ret -ne 0 ];then
 290		end_test "FAIL: route get"
 291		return 1
 292	fi
 293
 294	end_test "PASS: route get"
 295}
 296
 297check_addr_not_exist()
 298{
 299	dev=$1
 300	addr=$2
 301	if ip addr show dev $dev | grep -q $addr; then
 302		return 1
 303	else
 304		return 0
 305	fi
 306}
 307
 308kci_test_addrlft()
 309{
 310	for i in $(seq 10 100) ;do
 311		lft=$(((RANDOM%3) + 1))
 312		run_cmd ip addr add 10.23.11.$i/32 dev "$devdummy" preferred_lft $lft valid_lft $((lft+1))
 313	done
 314
 315	slowwait 5 check_addr_not_exist "$devdummy" "10.23.11."
 316	if [ $? -eq 1 ]; then
 317		# troubleshoot the reason for our failure
 318		run_cmd ip addr show dev "$devdummy"
 319		check_err 1
 320		end_test "FAIL: preferred_lft addresses remaining"
 321		return
 322	fi
 323
 324	end_test "PASS: preferred_lft addresses have expired"
 325}
 326
 327kci_test_addrlft_route_cleanup()
 328{
 329	local ret=0
 330	local test_addr="2001:db8:99::1/64"
 331	local test_prefix="2001:db8:99::/64"
 332
 333	run_cmd ip -6 addr add $test_addr dev "$devdummy" valid_lft 300 preferred_lft 300
 334	run_cmd_grep "$test_prefix proto kernel" ip -6 route show dev "$devdummy"
 335	run_cmd ip -6 addr del $test_addr dev "$devdummy"
 336	run_cmd_grep_fail "$test_prefix" ip -6 route show dev "$devdummy"
 337
 338	if [ $ret -ne 0 ]; then
 339		end_test "FAIL: route not cleaned up when address with valid_lft deleted"
 340		return 1
 341	fi
 342
 343	end_test "PASS: route cleaned up when address with valid_lft deleted"
 344}
 345
 346kci_test_promote_secondaries()
 347{
 348	run_cmd ifconfig "$devdummy"
 349	if [ $ret -ne 0 ]; then
 350		end_test "SKIP: ifconfig not installed"
 351		return $ksft_skip
 352	fi
 353	promote=$(sysctl -n net.ipv4.conf.$devdummy.promote_secondaries)
 354
 355	sysctl -q net.ipv4.conf.$devdummy.promote_secondaries=1
 356
 357	for i in $(seq 2 254);do
 358		IP="10.23.11.$i"
 359		ip -f inet addr add $IP/16 brd + dev "$devdummy"
 360		ifconfig "$devdummy" $IP netmask 255.255.0.0
 361	done
 362
 363	ip addr flush dev "$devdummy"
 364
 365	[ $promote -eq 0 ] && sysctl -q net.ipv4.conf.$devdummy.promote_secondaries=0
 366
 367	end_test "PASS: promote_secondaries complete"
 368}
 369
 370kci_test_addrlabel()
 371{
 372	local ret=0
 373	run_cmd ip addrlabel add prefix dead::/64 dev lo label 1
 374	run_cmd_grep "prefix dead::/64 dev lo label 1" ip addrlabel list
 375	run_cmd ip addrlabel del prefix dead::/64 dev lo label 1
 376	run_cmd ip addrlabel add prefix dead::/64 label 1
 377	run_cmd ip addrlabel del prefix dead::/64 label 1
 378
 379	# concurrent add/delete
 380	for i in $(seq 1 1000); do
 381		ip addrlabel add prefix 1c3::/64 label 12345 2>/dev/null
 382	done &
 383
 384	for i in $(seq 1 1000); do
 385		ip addrlabel del prefix 1c3::/64 label 12345 2>/dev/null
 386	done
 387
 388	wait
 389
 390	ip addrlabel del prefix 1c3::/64 label 12345 2>/dev/null
 391
 392	if [ $ret -ne 0 ];then
 393		end_test "FAIL: ipv6 addrlabel"
 394		return 1
 395	fi
 396
 397	end_test "PASS: ipv6 addrlabel"
 398}
 399
 400kci_test_ifalias()
 401{
 402	local ret=0
 403	namewant=$(uuidgen)
 404	syspathname="/sys/class/net/$devdummy/ifalias"
 405	run_cmd ip link set dev "$devdummy" alias "$namewant"
 406
 407	if [ $ret -ne 0 ]; then
 408		end_test "FAIL: cannot set interface alias of $devdummy to $namewant"
 409		return 1
 410	fi
 411	run_cmd_grep "alias $namewant" ip link show "$devdummy"
 412
 413	if [ -r "$syspathname" ] ; then
 414		read namehave < "$syspathname"
 415		if [ "$namewant" != "$namehave" ]; then
 416			end_test "FAIL: did set ifalias $namewant but got $namehave"
 417			return 1
 418		fi
 419
 420		namewant=$(uuidgen)
 421		echo "$namewant" > "$syspathname"
 422	        run_cmd_grep "alias $namewant" ip link show "$devdummy"
 423
 424		# sysfs interface allows to delete alias again
 425		echo "" > "$syspathname"
 426	        run_cmd_grep_fail "alias $namewant" ip link show "$devdummy"
 427
 428		for i in $(seq 1 100); do
 429			uuidgen > "$syspathname" &
 430		done
 431
 432		wait
 433
 434		# re-add the alias -- kernel should free mem when dummy dev is removed
 435		run_cmd ip link set dev "$devdummy" alias "$namewant"
 436
 437	fi
 438
 439	if [ $ret -ne 0 ]; then
 440		end_test "FAIL: set interface alias $devdummy to $namewant"
 441		return 1
 442	fi
 443
 444	end_test "PASS: set ifalias $namewant for $devdummy"
 445}
 446
 447kci_test_vrf()
 448{
 449	vrfname="test-vrf"
 450	local ret=0
 451	run_cmd ip link show type vrf
 452	if [ $? -ne 0 ]; then
 453		end_test "SKIP: vrf: iproute2 too old"
 454		return $ksft_skip
 455	fi
 456	run_cmd ip link add "$vrfname" type vrf table 10
 457	if [ $ret -ne 0 ];then
 458		end_test "FAIL: can't add vrf interface, skipping test"
 459		return 0
 460	fi
 461	run_cmd_grep "$vrfname" ip -br link show type vrf
 462	if [ $ret -ne 0 ];then
 463		end_test "FAIL: created vrf device not found"
 464		return 1
 465	fi
 466
 467	run_cmd ip link set dev "$vrfname" up
 468	run_cmd ip link set dev "$devdummy" master "$vrfname"
 469	run_cmd ip link del dev "$vrfname"
 470
 471	if [ $ret -ne 0 ];then
 472		end_test "FAIL: vrf"
 473		return 1
 474	fi
 475
 476	end_test "PASS: vrf"
 477}
 478
 479kci_test_encap_vxlan()
 480{
 481	local ret=0
 482	vxlan="test-vxlan0"
 483	vlan="test-vlan0"
 484	run_cmd ip -netns "$testns" link add "$vxlan" type vxlan id 42 group 239.1.1.1 \
 485		dev "$devdummy" dstport 4789
 486	if [ $? -ne 0 ]; then
 487		end_test "FAIL: can't add vxlan interface, skipping test"
 488		return 0
 489	fi
 490
 491	run_cmd ip -netns "$testns" addr add 10.2.11.49/24 dev "$vxlan"
 492	run_cmd ip -netns "$testns" link set up dev "$vxlan"
 493	run_cmd ip -netns "$testns" link add link "$vxlan" name "$vlan" type vlan id 1
 494
 495	# changelink testcases
 496	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan vni 43
 497	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan group ffe5::5 dev "$devdummy"
 498	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan ttl inherit
 499
 500	run_cmd ip -netns "$testns" link set dev "$vxlan" type vxlan ttl 64
 501	run_cmd ip -netns "$testns" link set dev "$vxlan" type vxlan nolearning
 502
 503	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan proxy
 504	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan norsc
 505	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan l2miss
 506	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan l3miss
 507	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan external
 508	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan udpcsum
 509	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan udp6zerocsumtx
 510	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan udp6zerocsumrx
 511	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan remcsumtx
 512	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan remcsumrx
 513	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan gbp
 514	run_cmd_fail ip -netns "$testns" link set dev "$vxlan" type vxlan gpe
 515	run_cmd ip -netns "$testns" link del "$vxlan"
 516
 517	if [ $ret -ne 0 ]; then
 518		end_test "FAIL: vxlan"
 519		return 1
 520	fi
 521	end_test "PASS: vxlan"
 522}
 523
 524kci_test_encap_fou()
 525{
 526	local ret=0
 527	name="test-fou"
 528	run_cmd_grep 'Usage: ip fou' ip fou help
 529	if [ $? -ne 0 ];then
 530		end_test "SKIP: fou: iproute2 too old"
 531		return $ksft_skip
 532	fi
 533
 534	if ! /sbin/modprobe -q -n fou; then
 535		end_test "SKIP: module fou is not found"
 536		return $ksft_skip
 537	fi
 538	/sbin/modprobe -q fou
 539
 540	run_cmd ip -netns "$testns" fou add port 7777 ipproto 47
 541	if [ $? -ne 0 ];then
 542		end_test "FAIL: can't add fou port 7777, skipping test"
 543		return 1
 544	fi
 545	run_cmd ip -netns "$testns" fou add port 8888 ipproto 4
 546	run_cmd_fail ip -netns "$testns" fou del port 9999
 547	run_cmd ip -netns "$testns" fou del port 7777
 548	if [ $ret -ne 0 ]; then
 549		end_test "FAIL: fou"
 550		return 1
 551	fi
 552
 553	end_test "PASS: fou"
 554}
 555
 556# test various encap methods, use netns to avoid unwanted interference
 557kci_test_encap()
 558{
 559	local ret=0
 560	setup_ns testns
 561	if [ $? -ne 0 ]; then
 562		end_test "SKIP encap tests: cannot add net namespace $testns"
 563		return $ksft_skip
 564	fi
 565	run_cmd ip -netns "$testns" link set lo up
 566	run_cmd ip -netns "$testns" link add name "$devdummy" type dummy
 567	run_cmd ip -netns "$testns" link set "$devdummy" up
 568	run_cmd kci_test_encap_vxlan
 569	run_cmd kci_test_encap_fou
 570
 571	ip netns del "$testns"
 572	return $ret
 573}
 574
 575kci_test_macsec()
 576{
 577	msname="test_macsec0"
 578	local ret=0
 579	run_cmd_grep "^Usage: ip macsec" ip macsec help
 580	if [ $? -ne 0 ]; then
 581		end_test "SKIP: macsec: iproute2 too old"
 582		return $ksft_skip
 583	fi
 584	run_cmd ip link add link "$devdummy" "$msname" type macsec port 42 encrypt on
 585	if [ $ret -ne 0 ];then
 586		end_test "FAIL: can't add macsec interface, skipping test"
 587		return 1
 588	fi
 589	run_cmd ip macsec add "$msname" tx sa 0 pn 1024 on key 01 12345678901234567890123456789012
 590	run_cmd ip macsec add "$msname" rx port 1234 address "1c:ed:de:ad:be:ef"
 591	run_cmd ip macsec add "$msname" rx port 1234 address "1c:ed:de:ad:be:ef" sa 0 pn 1 on key 00 0123456789abcdef0123456789abcdef
 592	run_cmd ip macsec show
 593	run_cmd ip link del dev "$msname"
 594
 595	if [ $ret -ne 0 ];then
 596		end_test "FAIL: macsec"
 597		return 1
 598	fi
 599
 600	end_test "PASS: macsec"
 601}
 602
 603# Test __dev_set_rx_mode call from dev_uc_add under addr_list_lock spinlock.
 604# Make sure __dev_set_promiscuity is not grabbing (sleeping) netdev instance
 605# lock.
 606# https://lore.kernel.org/netdev/2aff4342b0f5b1539c02ffd8df4c7e58dd9746e7.camel@nvidia.com/
 607kci_test_macsec_vlan()
 608{
 609	msname="test_macsec1"
 610	vlanname="test_vlan1"
 611	local ret=0
 612	run_cmd_grep "^Usage: ip macsec" ip macsec help
 613	if [ $? -ne 0 ]; then
 614		end_test "SKIP: macsec: iproute2 too old"
 615		return $ksft_skip
 616	fi
 617	run_cmd ip link add link "$devdummy" "$msname" type macsec port 42 encrypt on
 618	if [ $ret -ne 0 ];then
 619		end_test "FAIL: can't add macsec interface, skipping test"
 620		return 1
 621	fi
 622
 623	run_cmd ip link set dev "$msname" up
 624	ip link add link "$msname" name "$vlanname" type vlan id 1
 625	ip link set dev "$vlanname" address 00:11:22:33:44:88
 626	ip link set dev "$vlanname" up
 627	run_cmd ip link del dev "$vlanname"
 628	run_cmd ip link del dev "$msname"
 629
 630	if [ $ret -ne 0 ];then
 631		end_test "FAIL: macsec_vlan"
 632		return 1
 633	fi
 634
 635	end_test "PASS: macsec_vlan"
 636}
 637
 638#-------------------------------------------------------------------
 639# Example commands
 640#   ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 \
 641#            spi 0x07 mode transport reqid 0x07 replay-window 32 \
 642#            aead 'rfc4106(gcm(aes))' 1234567890123456dcba 128 \
 643#            sel src 14.0.0.52/24 dst 14.0.0.70/24
 644#   ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 \
 645#            tmpl proto esp src 14.0.0.52 dst 14.0.0.70 \
 646#            spi 0x07 mode transport reqid 0x07
 647#
 648# Subcommands not tested
 649#    ip x s update
 650#    ip x s allocspi
 651#    ip x s deleteall
 652#    ip x p update
 653#    ip x p deleteall
 654#    ip x p set
 655#-------------------------------------------------------------------
 656kci_test_ipsec()
 657{
 658	local ret=0
 659	algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128"
 660	srcip=192.168.123.1
 661	dstip=192.168.123.2
 662	spi=7
 663
 664	ip addr add $srcip dev $devdummy
 665
 666	# flush to be sure there's nothing configured
 667	run_cmd ip x s flush ; ip x p flush
 668
 669	# start the monitor in the background
 670	tmpfile=`mktemp /var/run/ipsectestXXX`
 671	mpid=`(ip x m > $tmpfile & echo $!) 2>/dev/null`
 672	sleep 0.2
 673
 674	ipsecid="proto esp src $srcip dst $dstip spi 0x07"
 675	run_cmd ip x s add $ipsecid \
 676            mode transport reqid 0x07 replay-window 32 \
 677            $algo sel src $srcip/24 dst $dstip/24
 678
 679
 680	lines=`ip x s list | grep $srcip | grep $dstip | wc -l`
 681	run_cmd test $lines -eq 2
 682	run_cmd_grep "SAD count 1" ip x s count
 683
 684	lines=`ip x s get $ipsecid | grep $srcip | grep $dstip | wc -l`
 685	run_cmd test $lines -eq 2
 686	run_cmd ip x s delete $ipsecid
 687
 688	lines=`ip x s list | wc -l`
 689	run_cmd test $lines -eq 0
 690
 691	ipsecsel="dir out src $srcip/24 dst $dstip/24"
 692	run_cmd ip x p add $ipsecsel \
 693		    tmpl proto esp src $srcip dst $dstip \
 694		    spi 0x07 mode transport reqid 0x07
 695
 696
 697	lines=`ip x p list | grep $srcip | grep $dstip | wc -l`
 698	run_cmd test $lines -eq 2
 699
 700	run_cmd_grep "SPD IN  0 OUT 1 FWD 0" ip x p count
 701
 702	lines=`ip x p get $ipsecsel | grep $srcip | grep $dstip | wc -l`
 703	run_cmd test $lines -eq 2
 704
 705	run_cmd ip x p delete $ipsecsel
 706
 707	lines=`ip x p list | wc -l`
 708	run_cmd test $lines -eq 0
 709
 710	# check the monitor results
 711	kill $mpid
 712	lines=`wc -l $tmpfile | cut "-d " -f1`
 713	run_cmd test $lines -eq 20
 714	rm -rf $tmpfile
 715
 716	# clean up any leftovers
 717	run_cmd ip x s flush
 718	run_cmd ip x p flush
 719	ip addr del $srcip/32 dev $devdummy
 720
 721	if [ $ret -ne 0 ]; then
 722		end_test "FAIL: ipsec"
 723		return 1
 724	fi
 725	end_test "PASS: ipsec"
 726}
 727
 728#-------------------------------------------------------------------
 729# Example commands
 730#   ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 \
 731#            spi 0x07 mode transport reqid 0x07 replay-window 32 \
 732#            aead 'rfc4106(gcm(aes))' 1234567890123456dcba 128 \
 733#            sel src 14.0.0.52/24 dst 14.0.0.70/24
 734#            offload dev sim1 dir out
 735#   ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 \
 736#            tmpl proto esp src 14.0.0.52 dst 14.0.0.70 \
 737#            spi 0x07 mode transport reqid 0x07
 738#
 739#-------------------------------------------------------------------
 740kci_test_ipsec_offload()
 741{
 742	local ret=0
 743	algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128"
 744	srcip=192.168.123.3
 745	dstip=192.168.123.4
 746	sysfsd=/sys/kernel/debug/netdevsim/netdevsim0/ports/0/
 747	sysfsf=$sysfsd/ipsec
 748	sysfsnet=/sys/bus/netdevsim/devices/netdevsim0/net/
 749	probed=false
 750	esp4_offload_probed_default=false
 751
 752	if lsmod | grep -q esp4_offload; then
 753		esp4_offload_probed_default=true
 754	fi
 755
 756	if ! mount | grep -q debugfs; then
 757		mount -t debugfs none /sys/kernel/debug/ &> /dev/null
 758	fi
 759
 760	# setup netdevsim since dummydev doesn't have offload support
 761	if [ ! -w /sys/bus/netdevsim/new_device ] ; then
 762		run_cmd modprobe -q netdevsim
 763		if [ $ret -ne 0 ]; then
 764			end_test "SKIP: ipsec_offload can't load netdevsim"
 765			return $ksft_skip
 766		fi
 767		probed=true
 768	fi
 769
 770	echo "0" > /sys/bus/netdevsim/new_device
 771	while [ ! -d $sysfsnet ] ; do :; done
 772	udevadm settle
 773	dev=`ls $sysfsnet`
 774
 775	ip addr add $srcip dev $dev
 776	ip link set $dev up
 777	if [ ! -d $sysfsd ] ; then
 778		end_test "FAIL: ipsec_offload can't create device $dev"
 779		return 1
 780	fi
 781	if [ ! -f $sysfsf ] ; then
 782		end_test "FAIL: ipsec_offload netdevsim doesn't support IPsec offload"
 783		return 1
 784	fi
 785
 786	# flush to be sure there's nothing configured
 787	ip x s flush ; ip x p flush
 788
 789	# create offloaded SAs, both in and out
 790	run_cmd ip x p add dir out src $srcip/24 dst $dstip/24 \
 791	    tmpl proto esp src $srcip dst $dstip spi 9 \
 792	    mode transport reqid 42
 793
 794	run_cmd ip x p add dir in src $dstip/24 dst $srcip/24 \
 795	    tmpl proto esp src $dstip dst $srcip spi 9 \
 796	    mode transport reqid 42
 797
 798	run_cmd ip x s add proto esp src $srcip dst $dstip spi 9 \
 799	    mode transport reqid 42 $algo sel src $srcip/24 dst $dstip/24 \
 800	    offload dev $dev dir out
 801
 802	run_cmd ip x s add proto esp src $dstip dst $srcip spi 9 \
 803	    mode transport reqid 42 $algo sel src $dstip/24 dst $srcip/24 \
 804	    offload dev $dev dir in
 805
 806	if [ $ret -ne 0 ]; then
 807		end_test "FAIL: ipsec_offload can't create SA"
 808		return 1
 809	fi
 810
 811	# does offload show up in ip output
 812	lines=`ip x s list | grep -c "crypto offload parameters: dev $dev dir"`
 813	if [ $lines -ne 2 ] ; then
 814		check_err 1
 815		end_test "FAIL: ipsec_offload SA offload missing from list output"
 816	fi
 817
 818	# we didn't create a peer, make sure we can Tx
 819	ip neigh add $dstip dev $dev lladdr 00:11:22:33:44:55
 820	# use ping to exercise the Tx path
 821	ping -I $dev -c 3 -W 1 -i 0 $dstip >/dev/null
 822
 823	# does driver have correct offload info
 824	run_cmd diff $sysfsf - << EOF
 825SA count=2 tx=3
 826sa[0] tx ipaddr=$dstip
 827sa[0]    spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1
 828sa[0]    key=0x34333231 38373635 32313039 36353433
 829sa[1] rx ipaddr=$srcip
 830sa[1]    spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1
 831sa[1]    key=0x34333231 38373635 32313039 36353433
 832EOF
 833	if [ $? -ne 0 ] ; then
 834		end_test "FAIL: ipsec_offload incorrect driver data"
 835		check_err 1
 836	fi
 837
 838	# does offload get removed from driver
 839	ip x s flush
 840	ip x p flush
 841	lines=`grep -c "SA count=0" $sysfsf`
 842	if [ $lines -ne 1 ] ; then
 843		check_err 1
 844		end_test "FAIL: ipsec_offload SA not removed from driver"
 845	fi
 846
 847	# clean up any leftovers
 848	! "$esp4_offload_probed_default" && lsmod | grep -q esp4_offload && rmmod esp4_offload
 849	echo 0 > /sys/bus/netdevsim/del_device
 850	$probed && rmmod netdevsim
 851
 852	if [ $ret -ne 0 ]; then
 853		end_test "FAIL: ipsec_offload"
 854		return 1
 855	fi
 856	end_test "PASS: ipsec_offload"
 857}
 858
 859kci_test_gretap()
 860{
 861	DEV_NS=gretap00
 862	local ret=0
 863
 864	setup_ns testns
 865	if [ $? -ne 0 ]; then
 866		end_test "SKIP gretap tests: cannot add net namespace $testns"
 867		return $ksft_skip
 868	fi
 869
 870	run_cmd_grep "^Usage:" ip link help gretap
 871	if [ $? -ne 0 ];then
 872		end_test "SKIP: gretap: iproute2 too old"
 873		ip netns del "$testns"
 874		return $ksft_skip
 875	fi
 876
 877	# test native tunnel
 878	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type gretap seq \
 879		key 102 local 172.16.1.100 remote 172.16.1.200
 880
 881
 882	run_cmd ip -netns "$testns" addr add dev "$DEV_NS" 10.1.1.100/24
 883	run_cmd ip -netns "$testns" link set dev $DEV_NS up
 884	run_cmd ip -netns "$testns" link del "$DEV_NS"
 885
 886	# test external mode
 887	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type gretap external
 888	run_cmd ip -netns "$testns" link del "$DEV_NS"
 889
 890	if [ $ret -ne 0 ]; then
 891		end_test "FAIL: gretap"
 892		ip netns del "$testns"
 893		return 1
 894	fi
 895	end_test "PASS: gretap"
 896
 897	ip netns del "$testns"
 898}
 899
 900kci_test_ip6gretap()
 901{
 902	DEV_NS=ip6gretap00
 903	local ret=0
 904
 905	setup_ns testns
 906	if [ $? -ne 0 ]; then
 907		end_test "SKIP ip6gretap tests: cannot add net namespace $testns"
 908		return $ksft_skip
 909	fi
 910
 911	run_cmd_grep "^Usage:" ip link help ip6gretap
 912	if [ $? -ne 0 ];then
 913		end_test "SKIP: ip6gretap: iproute2 too old"
 914		ip netns del "$testns"
 915		return $ksft_skip
 916	fi
 917
 918	# test native tunnel
 919	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type ip6gretap seq \
 920		key 102 local fc00:100::1 remote fc00:100::2
 921
 922
 923	run_cmd ip -netns "$testns" addr add dev "$DEV_NS" fc00:200::1/96
 924	run_cmd ip -netns "$testns" link set dev $DEV_NS up
 925	run_cmd ip -netns "$testns" link del "$DEV_NS"
 926
 927	# test external mode
 928	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type ip6gretap external
 929	run_cmd ip -netns "$testns" link del "$DEV_NS"
 930
 931	if [ $ret -ne 0 ]; then
 932		end_test "FAIL: ip6gretap"
 933		ip netns del "$testns"
 934		return 1
 935	fi
 936	end_test "PASS: ip6gretap"
 937
 938	ip netns del "$testns"
 939}
 940
 941kci_test_erspan()
 942{
 943	DEV_NS=erspan00
 944	local ret=0
 945	run_cmd_grep "^Usage:" ip link help erspan
 946	if [ $? -ne 0 ];then
 947		end_test "SKIP: erspan: iproute2 too old"
 948		return $ksft_skip
 949	fi
 950	setup_ns testns
 951	if [ $? -ne 0 ]; then
 952		end_test "SKIP erspan tests: cannot add net namespace $testns"
 953		return $ksft_skip
 954	fi
 955
 956	# test native tunnel erspan v1
 957	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type erspan seq \
 958		key 102 local 172.16.1.100 remote 172.16.1.200 \
 959		erspan_ver 1 erspan 488
 960
 961
 962	run_cmd ip -netns "$testns" addr add dev "$DEV_NS" 10.1.1.100/24
 963	run_cmd ip -netns "$testns" link set dev $DEV_NS up
 964	run_cmd ip -netns "$testns" link del "$DEV_NS"
 965
 966	# test native tunnel erspan v2
 967	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type erspan seq \
 968		key 102 local 172.16.1.100 remote 172.16.1.200 \
 969		erspan_ver 2 erspan_dir ingress erspan_hwid 7
 970
 971
 972	run_cmd ip -netns "$testns" addr add dev "$DEV_NS" 10.1.1.100/24
 973	run_cmd ip -netns "$testns" link set dev $DEV_NS up
 974	run_cmd ip -netns "$testns" link del "$DEV_NS"
 975
 976	# test external mode
 977	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type erspan external
 978	run_cmd ip -netns "$testns" link del "$DEV_NS"
 979
 980	if [ $ret -ne 0 ]; then
 981		end_test "FAIL: erspan"
 982		ip netns del "$testns"
 983		return 1
 984	fi
 985	end_test "PASS: erspan"
 986
 987	ip netns del "$testns"
 988}
 989
 990kci_test_ip6erspan()
 991{
 992	DEV_NS=ip6erspan00
 993	local ret=0
 994	run_cmd_grep "^Usage:" ip link help ip6erspan
 995	if [ $? -ne 0 ];then
 996		end_test "SKIP: ip6erspan: iproute2 too old"
 997		return $ksft_skip
 998	fi
 999	setup_ns testns
1000	if [ $? -ne 0 ]; then
1001		end_test "SKIP ip6erspan tests: cannot add net namespace $testns"
1002		return $ksft_skip
1003	fi
1004
1005	# test native tunnel ip6erspan v1
1006	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type ip6erspan seq \
1007		key 102 local fc00:100::1 remote fc00:100::2 \
1008		erspan_ver 1 erspan 488
1009
1010
1011	run_cmd ip -netns "$testns" addr add dev "$DEV_NS" 10.1.1.100/24
1012	run_cmd ip -netns "$testns" link set dev $DEV_NS up
1013	run_cmd ip -netns "$testns" link del "$DEV_NS"
1014
1015	# test native tunnel ip6erspan v2
1016	run_cmd ip -netns "$testns" link add dev "$DEV_NS" type ip6erspan seq \
1017		key 102 local fc00:100::1 remote fc00:100::2 \
1018		erspan_ver 2 erspan_dir ingress erspan_hwid 7
1019
1020
1021	run_cmd ip -netns "$testns" addr add dev "$DEV_NS" 10.1.1.100/24
1022	run_cmd ip -netns "$testns" link set dev $DEV_NS up
1023	run_cmd ip -netns "$testns" link del "$DEV_NS"
1024
1025	# test external mode
1026	run_cmd ip -netns "$testns" link add dev "$DEV_NS" \
1027		type ip6erspan external
1028
1029	run_cmd ip -netns "$testns" link del "$DEV_NS"
1030
1031	if [ $ret -ne 0 ]; then
1032		end_test "FAIL: ip6erspan"
1033		ip netns del "$testns"
1034		return 1
1035	fi
1036	end_test "PASS: ip6erspan"
1037
1038	ip netns del "$testns"
1039}
1040
1041kci_test_fdb_get()
1042{
1043	brdev="test-br0"
1044	vxlandev="vxlan10"
1045	test_mac=de:ad:be:ef:13:37
1046	localip="10.0.2.2"
1047	dstip="10.0.2.3"
1048	local ret=0
1049
1050	run_cmd_grep 'bridge fdb get' bridge fdb help
1051	if [ $? -ne 0 ];then
1052		end_test "SKIP: fdb get tests: iproute2 too old"
1053		return $ksft_skip
1054	fi
1055
1056	setup_ns testns
1057	if [ $? -ne 0 ]; then
1058		end_test "SKIP fdb get tests: cannot add net namespace $testns"
1059		return $ksft_skip
1060	fi
1061	IP="ip -netns $testns"
1062	BRIDGE="bridge -netns $testns"
1063	run_cmd $IP link add "$vxlandev" type vxlan id 10 local $localip \
1064                dstport 4789
1065	run_cmd $IP link add name "$brdev" type bridge
1066	run_cmd $IP link set dev "$vxlandev" master "$brdev"
1067	run_cmd $BRIDGE fdb add $test_mac dev "$vxlandev" master
1068	run_cmd $BRIDGE fdb add $test_mac dev "$vxlandev" dst $dstip self
1069	run_cmd_grep "dev $vxlandev master $brdev" $BRIDGE fdb get $test_mac brport "$vxlandev"
1070	run_cmd_grep "dev $vxlandev master $brdev" $BRIDGE fdb get $test_mac br "$brdev"
1071	run_cmd_grep "dev $vxlandev dst $dstip" $BRIDGE fdb get $test_mac dev "$vxlandev" self
1072
1073	ip netns del $testns &>/dev/null
1074
1075	if [ $ret -ne 0 ]; then
1076		end_test "FAIL: bridge fdb get"
1077		return 1
1078	fi
1079
1080	end_test "PASS: bridge fdb get"
1081}
1082
1083kci_test_fdb_del()
1084{
1085	local test_mac=de:ad:be:ef:13:37
1086	local dummydev="dummy1"
1087	local brdev="test-br0"
1088	local ret=0
1089
1090	run_cmd_grep 'bridge fdb get' bridge fdb help
1091	if [ $? -ne 0 ]; then
1092		end_test "SKIP: fdb del tests: iproute2 too old"
1093		return $ksft_skip
1094	fi
1095
1096	setup_ns testns
1097	if [ $? -ne 0 ]; then
1098		end_test "SKIP fdb del tests: cannot add net namespace $testns"
1099		return $ksft_skip
1100	fi
1101	IP="ip -netns $testns"
1102	BRIDGE="bridge -netns $testns"
1103	run_cmd $IP link add $dummydev type dummy
1104	run_cmd $IP link add name $brdev type bridge vlan_filtering 1
1105	run_cmd $IP link set dev $dummydev master $brdev
1106	run_cmd $BRIDGE fdb add $test_mac dev $dummydev master static vlan 1
1107	run_cmd $BRIDGE vlan del vid 1 dev $dummydev
1108	run_cmd $BRIDGE fdb get $test_mac br $brdev vlan 1
1109	run_cmd $BRIDGE fdb del $test_mac dev $dummydev master vlan 1
1110	run_cmd_fail $BRIDGE fdb get $test_mac br $brdev vlan 1
1111
1112	ip netns del $testns &>/dev/null
1113
1114	if [ $ret -ne 0 ]; then
1115		end_test "FAIL: bridge fdb del"
1116		return 1
1117	fi
1118
1119	end_test "PASS: bridge fdb del"
1120}
1121
1122kci_test_neigh_get()
1123{
1124	dstmac=de:ad:be:ef:13:37
1125	dstip=10.0.2.4
1126	dstip6=dead::2
1127	local ret=0
1128
1129	run_cmd_grep 'ip neigh get' ip neigh help
1130	if [ $? -ne 0 ];then
1131		end_test "SKIP: fdb get tests: iproute2 too old"
1132		return $ksft_skip
1133	fi
1134
1135	# ipv4
1136	run_cmd ip neigh add $dstip lladdr $dstmac dev "$devdummy"
1137	run_cmd_grep "$dstmac" ip neigh get $dstip dev "$devdummy"
1138	run_cmd ip neigh del $dstip lladdr $dstmac dev "$devdummy"
1139
1140	# ipv4 proxy
1141	run_cmd ip neigh add proxy $dstip dev "$devdummy"
1142	run_cmd_grep "$dstip" ip neigh get proxy $dstip dev "$devdummy"
1143	run_cmd ip neigh del proxy $dstip dev "$devdummy"
1144
1145	# ipv6
1146	run_cmd ip neigh add $dstip6 lladdr $dstmac dev "$devdummy"
1147	run_cmd_grep "$dstmac" ip neigh get $dstip6 dev "$devdummy"
1148	run_cmd ip neigh del $dstip6 lladdr $dstmac dev "$devdummy"
1149
1150	# ipv6 proxy
1151	run_cmd ip neigh add proxy $dstip6 dev "$devdummy"
1152	run_cmd_grep "$dstip6" ip neigh get proxy $dstip6 dev "$devdummy"
1153	run_cmd ip neigh del proxy $dstip6 dev "$devdummy"
1154
1155	if [ $ret -ne 0 ];then
1156		end_test "FAIL: neigh get"
1157		return 1
1158	fi
1159
1160	end_test "PASS: neigh get"
1161}
1162
1163kci_test_bridge_parent_id()
1164{
1165	local ret=0
1166	sysfsnet=/sys/bus/netdevsim/devices/netdevsim
1167	probed=false
1168
1169	if [ ! -w /sys/bus/netdevsim/new_device ] ; then
1170		run_cmd modprobe -q netdevsim
1171		if [ $ret -ne 0 ]; then
1172			end_test "SKIP: bridge_parent_id can't load netdevsim"
1173			return $ksft_skip
1174		fi
1175		probed=true
1176	fi
1177
1178	echo "10 1" > /sys/bus/netdevsim/new_device
1179	while [ ! -d ${sysfsnet}10 ] ; do :; done
1180	echo "20 1" > /sys/bus/netdevsim/new_device
1181	while [ ! -d ${sysfsnet}20 ] ; do :; done
1182	udevadm settle
1183	dev10=`ls ${sysfsnet}10/net/`
1184	dev20=`ls ${sysfsnet}20/net/`
1185	run_cmd ip link add name test-bond0 type bond mode 802.3ad
1186	run_cmd ip link set dev $dev10 master test-bond0
1187	run_cmd ip link set dev $dev20 master test-bond0
1188	run_cmd ip link add name test-br0 type bridge
1189	run_cmd ip link set dev test-bond0 master test-br0
1190
1191	# clean up any leftovers
1192	ip link del dev test-br0
1193	ip link del dev test-bond0
1194	echo 20 > /sys/bus/netdevsim/del_device
1195	echo 10 > /sys/bus/netdevsim/del_device
1196	$probed && rmmod netdevsim
1197
1198	if [ $ret -ne 0 ]; then
1199		end_test "FAIL: bridge_parent_id"
1200		return 1
1201	fi
1202	end_test "PASS: bridge_parent_id"
1203}
1204
1205address_get_proto()
1206{
1207	local addr=$1; shift
1208
1209	ip -N -j address show dev "$devdummy" |
1210	    jq -e -r --arg addr "${addr%/*}" \
1211	       '.[].addr_info[] | select(.local == $addr) | .protocol'
1212}
1213
1214address_count()
1215{
1216	ip -N -j address show dev "$devdummy" "$@" |
1217	    jq -e -r '[.[].addr_info[] | .local | select(. != null)] | length'
1218}
1219
1220do_test_address_proto()
1221{
1222	local what=$1; shift
1223	local addr=$1; shift
1224	local addr2=${addr%/*}2/${addr#*/}
1225	local addr3=${addr%/*}3/${addr#*/}
1226	local proto
1227	local count
1228	local ret=0
1229	local err
1230
1231	run_cmd_grep 'proto' ip address help
1232	if [ $? -ne 0 ];then
1233		end_test "SKIP: addr proto ${what}: iproute2 too old"
1234		return $ksft_skip
1235	fi
1236
1237	ip address add dev "$devdummy" "$addr3"
1238	check_err $?
1239	proto=$(address_get_proto "$addr3")
1240	[[ "$proto" == null ]]
1241	check_err $?
1242
1243	ip address add dev "$devdummy" "$addr2" proto 0x99
1244	check_err $?
1245	proto=$(address_get_proto "$addr2")
1246	[[ "$proto" == 0x99 ]]
1247	check_err $?
1248
1249	ip address add dev "$devdummy" "$addr" proto 0xab
1250	check_err $?
1251	proto=$(address_get_proto "$addr")
1252	[[ "$proto" == 0xab ]]
1253	check_err $?
1254
1255	ip address replace dev "$devdummy" "$addr" proto 0x11
1256	proto=$(address_get_proto "$addr")
1257	check_err $?
1258	[[ "$proto" == 0x11 ]]
1259	check_err $?
1260
1261	count=$(address_count)
1262	check_err $?
1263	(( count >= 3 )) # $addr, $addr2 and $addr3 plus any kernel addresses
1264	check_err $?
1265
1266	count=$(address_count proto 0)
1267	check_err $?
1268	(( count == 1 )) # just $addr3
1269	check_err $?
1270
1271	count=$(address_count proto 0x11)
1272	check_err $?
1273	(( count == 2 )) # $addr and $addr3
1274	check_err $?
1275
1276	count=$(address_count proto 0xab)
1277	check_err $?
1278	(( count == 1 )) # just $addr3
1279	check_err $?
1280
1281	ip address del dev "$devdummy" "$addr"
1282	ip address del dev "$devdummy" "$addr2"
1283	ip address del dev "$devdummy" "$addr3"
1284
1285	if [ $ret -ne 0 ]; then
1286		end_test "FAIL: address proto $what"
1287		return 1
1288	fi
1289	end_test "PASS: address proto $what"
1290}
1291
1292kci_test_address_proto()
1293{
1294	local ret=0
1295
1296	do_test_address_proto IPv4 192.0.2.1/28
1297	check_err $?
1298
1299	do_test_address_proto IPv6 2001:db8:1::1/64
1300	check_err $?
1301
1302	return $ret
1303}
1304
1305kci_test_enslave_bonding()
1306{
1307	local bond="bond123"
1308	local ret=0
1309
1310	setup_ns testns
1311	if [ $? -ne 0 ]; then
1312		end_test "SKIP bonding tests: cannot add net namespace $testns"
1313		return $ksft_skip
1314	fi
1315
1316	run_cmd ip -netns $testns link add dev $bond type bond mode balance-rr
1317	run_cmd ip -netns $testns link add dev $devdummy type dummy
1318	run_cmd ip -netns $testns link set dev $devdummy up
1319	run_cmd ip -netns $testns link set dev $devdummy master $bond down
1320	if [ $ret -ne 0 ]; then
1321		end_test "FAIL: initially up interface added to a bond and set down"
1322		ip netns del "$testns"
1323		return 1
1324	fi
1325
1326	end_test "PASS: enslave interface in a bond"
1327	ip netns del "$testns"
1328}
1329
1330# Called to validate the addresses on $IFNAME:
1331#
1332# 1. Every `temporary` address must have a matching `mngtmpaddr`
1333# 2. Every `mngtmpaddr` address must have some un`deprecated` `temporary`
1334#
1335# If the mngtmpaddr or tempaddr checking failed, return 0 and stop slowwait
1336validate_mngtmpaddr()
1337{
1338	local dev=$1
1339	local prefix=""
1340	local addr_list=$(ip -j -n $testns addr show dev ${dev})
1341	local temp_addrs=$(echo ${addr_list} | \
1342		jq -r '.[].addr_info[] | select(.temporary == true) | .local')
1343	local mng_prefixes=$(echo ${addr_list} | \
1344		jq -r '.[].addr_info[] | select(.mngtmpaddr == true) | .local' | \
1345		cut -d: -f1-4 | tr '\n' ' ')
1346	local undep_prefixes=$(echo ${addr_list} | \
1347		jq -r '.[].addr_info[] | select(.temporary == true and .deprecated != true) | .local' | \
1348		cut -d: -f1-4 | tr '\n' ' ')
1349
1350	# 1. All temporary addresses (temp and dep) must have a matching mngtmpaddr
1351	for address in ${temp_addrs}; do
1352		prefix=$(echo ${address} | cut -d: -f1-4)
1353		if [[ ! " ${mng_prefixes} " =~ " $prefix " ]]; then
1354			check_err 1 "FAIL: Temporary $address with no matching mngtmpaddr!";
1355			return 0
1356		fi
1357	done
1358
1359	# 2. All mngtmpaddr addresses must have a temporary address (not dep)
1360	for prefix in ${mng_prefixes}; do
1361		if [[ ! " ${undep_prefixes} " =~ " $prefix " ]]; then
1362			check_err 1 "FAIL: No undeprecated temporary in $prefix!";
1363			return 0
1364		fi
1365	done
1366
1367	return 1
1368}
1369
1370kci_test_mngtmpaddr()
1371{
1372	local ret=0
1373
1374	setup_ns testns
1375	if [ $? -ne 0 ]; then
1376		end_test "SKIP mngtmpaddr tests: cannot add net namespace $testns"
1377		return $ksft_skip
1378	fi
1379
1380	# 1. Create a dummy Ethernet interface
1381	run_cmd ip -n $testns link add ${devdummy} type dummy
1382	run_cmd ip -n $testns link set ${devdummy} up
1383	run_cmd ip netns exec $testns sysctl -w net.ipv6.conf.${devdummy}.use_tempaddr=1
1384	run_cmd ip netns exec $testns sysctl -w net.ipv6.conf.${devdummy}.temp_prefered_lft=10
1385	run_cmd ip netns exec $testns sysctl -w net.ipv6.conf.${devdummy}.temp_valid_lft=25
1386	run_cmd ip netns exec $testns sysctl -w net.ipv6.conf.${devdummy}.max_desync_factor=1
1387
1388	# 2. Create several mngtmpaddr addresses on that interface.
1389	# with temp_*_lft configured to be pretty short (10 and 35 seconds
1390	# for prefer/valid respectively)
1391	for i in $(seq 1 9); do
1392		run_cmd ip -n $testns addr add 2001:db8:7e57:${i}::1/64 mngtmpaddr dev ${devdummy}
1393	done
1394
1395	# 3. Confirm that a preferred temporary address exists for each mngtmpaddr
1396	# address at all times, polling once per second for 30 seconds.
1397	slowwait 30 validate_mngtmpaddr ${devdummy}
1398
1399	# 4. Delete each mngtmpaddr address, one at a time (alternating between
1400	# deleting and merely un-mngtmpaddr-ing), and confirm that the other
1401	# mngtmpaddr addresses still have preferred temporaries.
1402	for i in $(seq 1 9); do
1403		(( $i % 4 == 0 )) && mng_flag="mngtmpaddr" || mng_flag=""
1404		if (( $i % 2 == 0 )); then
1405			run_cmd ip -n $testns addr del 2001:db8:7e57:${i}::1/64 $mng_flag dev ${devdummy}
1406		else
1407			run_cmd ip -n $testns addr change 2001:db8:7e57:${i}::1/64 dev ${devdummy}
1408		fi
1409		# the temp addr should be deleted
1410		validate_mngtmpaddr ${devdummy}
1411	done
1412
1413	if [ $ret -ne 0 ]; then
1414		end_test "FAIL: mngtmpaddr add/remove incorrect"
1415	else
1416		end_test "PASS: mngtmpaddr add/remove correctly"
1417	fi
1418
1419	ip netns del "$testns"
1420	return $ret
1421}
1422
1423kci_test_operstate()
1424{
1425	local ret=0
1426
1427	# Check that it is possible to set operational state during device
1428	# creation and that it is preserved when the administrative state of
1429	# the device is toggled.
1430	run_cmd ip link add name vx0 up state up type vxlan id 10010 dstport 4789
1431	run_cmd_grep "state UP" ip link show dev vx0
1432	run_cmd ip link set dev vx0 down
1433	run_cmd_grep "state DOWN" ip link show dev vx0
1434	run_cmd ip link set dev vx0 up
1435	run_cmd_grep "state UP" ip link show dev vx0
1436
1437	run_cmd ip link del dev vx0
1438
1439	# Check that it is possible to set the operational state of the device
1440	# after creation.
1441	run_cmd ip link add name vx0 up type vxlan id 10010 dstport 4789
1442	run_cmd_grep "state UNKNOWN" ip link show dev vx0
1443	run_cmd ip link set dev vx0 state up
1444	run_cmd_grep "state UP" ip link show dev vx0
1445
1446	run_cmd ip link del dev vx0
1447
1448	if [ "$ret" -ne 0 ]; then
1449		end_test "FAIL: operstate"
1450		return 1
1451	fi
1452
1453	end_test "PASS: operstate"
1454}
1455
1456kci_test_rtnl()
1457{
1458	local current_test
1459	local ret=0
1460
1461	kci_add_dummy
1462	if [ $ret -ne 0 ];then
1463		end_test "FAIL: cannot add dummy interface"
1464		return 1
1465	fi
1466
1467	for current_test in ${TESTS:-$ALL_TESTS}; do
1468		$current_test
1469		check_err $?
1470	done
1471
1472	kci_del_dummy
1473	return $ret
1474}
1475
1476usage()
1477{
1478	cat <<EOF
1479usage: ${0##*/} OPTS
1480
1481        -t <test>   Test(s) to run (default: all)
1482                    (options: $(echo $ALL_TESTS))
1483        -v          Verbose mode (show commands and output)
1484        -P          Pause after every test
1485        -p          Pause after every failing test before cleanup (for debugging)
1486EOF
1487}
1488
1489require_command jq
1490
1491#check for needed privileges
1492if [ "$(id -u)" -ne 0 ];then
1493	end_test "SKIP: Need root privileges"
1494	exit $ksft_skip
1495fi
1496
1497for x in ip tc;do
1498	$x -Version 2>/dev/null >/dev/null
1499	if [ $? -ne 0 ];then
1500		end_test "SKIP: Could not run test without the $x tool"
1501		exit $ksft_skip
1502	fi
1503done
1504
1505while getopts t:hvpP o; do
1506	case $o in
1507		t) TESTS=$OPTARG;;
1508		v) VERBOSE=1;;
1509		p) PAUSE_ON_FAIL=yes;;
1510		P) PAUSE=yes;;
1511		h) usage; exit 0;;
1512		*) usage; exit 1;;
1513	esac
1514done
1515
1516[ $PAUSE = "yes" ] && PAUSE_ON_FAIL="no"
1517
1518kci_test_rtnl
1519
1520exit $?
~/ Read-only file preview.