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