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