xref: /linux/tools/testing/selftests/net/rtnetlink.sh (revision 82f78acd5a9270370ef4aa3f032ede25f3dc91ee)
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 $?
1521