xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/net/xfrm_policy.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/bash
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# Check xfrm policy resolution.  Topology:
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun# 1.2   1.1   3.1  3.10    2.1   2.2
7*4882a593Smuzhiyun# eth1  eth1 veth0 veth0 eth1   eth1
8*4882a593Smuzhiyun# ns1 ---- ns3 ----- ns4 ---- ns2
9*4882a593Smuzhiyun#
10*4882a593Smuzhiyun# ns3 and ns4 are connected via ipsec tunnel.
11*4882a593Smuzhiyun# pings from ns1 to ns2 (and vice versa) are supposed to work like this:
12*4882a593Smuzhiyun# ns1: ping 10.0.2.2: passes via ipsec tunnel.
13*4882a593Smuzhiyun# ns2: ping 10.0.1.2: passes via ipsec tunnel.
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun# ns1: ping 10.0.1.253: passes via ipsec tunnel (direct policy)
16*4882a593Smuzhiyun# ns2: ping 10.0.2.253: passes via ipsec tunnel (direct policy)
17*4882a593Smuzhiyun#
18*4882a593Smuzhiyun# ns1: ping 10.0.2.254: does NOT pass via ipsec tunnel (exception)
19*4882a593Smuzhiyun# ns2: ping 10.0.1.254: does NOT pass via ipsec tunnel (exception)
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun# Kselftest framework requirement - SKIP code is 4.
22*4882a593Smuzhiyunksft_skip=4
23*4882a593Smuzhiyunret=0
24*4882a593Smuzhiyunpolicy_checks_ok=1
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunKEY_SHA=0xdeadbeef1234567890abcdefabcdefabcdefabcd
27*4882a593SmuzhiyunKEY_AES=0x0123456789abcdef0123456789012345
28*4882a593SmuzhiyunSPI1=0x1
29*4882a593SmuzhiyunSPI2=0x2
30*4882a593Smuzhiyun
31*4882a593Smuzhiyundo_esp_policy() {
32*4882a593Smuzhiyun    local ns=$1
33*4882a593Smuzhiyun    local me=$2
34*4882a593Smuzhiyun    local remote=$3
35*4882a593Smuzhiyun    local lnet=$4
36*4882a593Smuzhiyun    local rnet=$5
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun    # to encrypt packets as they go out (includes forwarded packets that need encapsulation)
39*4882a593Smuzhiyun    ip -net $ns xfrm policy add src $lnet dst $rnet dir out tmpl src $me dst $remote proto esp mode tunnel priority 100 action allow
40*4882a593Smuzhiyun    # to fwd decrypted packets after esp processing:
41*4882a593Smuzhiyun    ip -net $ns xfrm policy add src $rnet dst $lnet dir fwd tmpl src $remote dst $me proto esp mode tunnel priority 100 action allow
42*4882a593Smuzhiyun}
43*4882a593Smuzhiyun
44*4882a593Smuzhiyundo_esp() {
45*4882a593Smuzhiyun    local ns=$1
46*4882a593Smuzhiyun    local me=$2
47*4882a593Smuzhiyun    local remote=$3
48*4882a593Smuzhiyun    local lnet=$4
49*4882a593Smuzhiyun    local rnet=$5
50*4882a593Smuzhiyun    local spi_out=$6
51*4882a593Smuzhiyun    local spi_in=$7
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun    ip -net $ns xfrm state add src $remote dst $me proto esp spi $spi_in  enc aes $KEY_AES  auth sha1 $KEY_SHA  mode tunnel sel src $rnet dst $lnet
54*4882a593Smuzhiyun    ip -net $ns xfrm state add src $me  dst $remote proto esp spi $spi_out enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $lnet dst $rnet
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun    do_esp_policy $ns $me $remote $lnet $rnet
57*4882a593Smuzhiyun}
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun# add policies with different netmasks, to make sure kernel carries
60*4882a593Smuzhiyun# the policies contained within new netmask over when search tree is
61*4882a593Smuzhiyun# re-built.
62*4882a593Smuzhiyun# peer netns that are supposed to be encapsulated via esp have addresses
63*4882a593Smuzhiyun# in the 10.0.1.0/24 and 10.0.2.0/24 subnets, respectively.
64*4882a593Smuzhiyun#
65*4882a593Smuzhiyun# Adding a policy for '10.0.1.0/23' will make it necessary to
66*4882a593Smuzhiyun# alter the prefix of 10.0.1.0 subnet.
67*4882a593Smuzhiyun# In case new prefix overlaps with existing node, the node and all
68*4882a593Smuzhiyun# policies it carries need to be merged with the existing one(s).
69*4882a593Smuzhiyun#
70*4882a593Smuzhiyun# Do that here.
71*4882a593Smuzhiyundo_overlap()
72*4882a593Smuzhiyun{
73*4882a593Smuzhiyun    local ns=$1
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun    # adds new nodes to tree (neither network exists yet in policy database).
76*4882a593Smuzhiyun    ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/24 dir fwd priority 200 action block
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun    # adds a new node in the 10.0.0.0/24 tree (dst node exists).
79*4882a593Smuzhiyun    ip -net $ns xfrm policy add src 10.2.0.0/24 dst 10.0.0.0/24 dir fwd priority 200 action block
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun    # adds a 10.2.0.0/23 node, but for different dst.
82*4882a593Smuzhiyun    ip -net $ns xfrm policy add src 10.2.0.0/23 dst 10.0.1.0/24 dir fwd priority 200 action block
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun    # dst now overlaps with the 10.0.1.0/24 ESP policy in fwd.
85*4882a593Smuzhiyun    # kernel must 'promote' existing one (10.0.0.0/24) to 10.0.0.0/23.
86*4882a593Smuzhiyun    # But 10.0.0.0/23 also includes existing 10.0.1.0/24, so that node
87*4882a593Smuzhiyun    # also has to be merged too, including source-sorted subtrees.
88*4882a593Smuzhiyun    # old:
89*4882a593Smuzhiyun    # 10.0.0.0/24 (node 1 in dst tree of the bin)
90*4882a593Smuzhiyun    #    10.1.0.0/24 (node in src tree of dst node 1)
91*4882a593Smuzhiyun    #    10.2.0.0/24 (node in src tree of dst node 1)
92*4882a593Smuzhiyun    # 10.0.1.0/24 (node 2 in dst tree of the bin)
93*4882a593Smuzhiyun    #    10.0.2.0/24 (node in src tree of dst node 2)
94*4882a593Smuzhiyun    #    10.2.0.0/24 (node in src tree of dst node 2)
95*4882a593Smuzhiyun    #
96*4882a593Smuzhiyun    # The next 'policy add' adds dst '10.0.0.0/23', which means
97*4882a593Smuzhiyun    # that dst node 1 and dst node 2 have to be merged including
98*4882a593Smuzhiyun    # the sub-tree.  As no duplicates are allowed, policies in
99*4882a593Smuzhiyun    # the two '10.0.2.0/24' are also merged.
100*4882a593Smuzhiyun    #
101*4882a593Smuzhiyun    # after the 'add', internal search tree should look like this:
102*4882a593Smuzhiyun    # 10.0.0.0/23 (node in dst tree of bin)
103*4882a593Smuzhiyun    #     10.0.2.0/24 (node in src tree of dst node)
104*4882a593Smuzhiyun    #     10.1.0.0/24 (node in src tree of dst node)
105*4882a593Smuzhiyun    #     10.2.0.0/24 (node in src tree of dst node)
106*4882a593Smuzhiyun    #
107*4882a593Smuzhiyun    # 10.0.0.0/24 and 10.0.1.0/24 nodes have been merged as 10.0.0.0/23.
108*4882a593Smuzhiyun    ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/23 dir fwd priority 200 action block
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun    # similar to above: add policies (with partially random address), with shrinking prefixes.
111*4882a593Smuzhiyun    for p in 29 28 27;do
112*4882a593Smuzhiyun      for k in $(seq 1 32); do
113*4882a593Smuzhiyun       ip -net $ns xfrm policy add src 10.253.1.$((RANDOM%255))/$p dst 10.254.1.$((RANDOM%255))/$p dir fwd priority $((200+k)) action block 2>/dev/null
114*4882a593Smuzhiyun      done
115*4882a593Smuzhiyun    done
116*4882a593Smuzhiyun}
117*4882a593Smuzhiyun
118*4882a593Smuzhiyundo_esp_policy_get_check() {
119*4882a593Smuzhiyun    local ns=$1
120*4882a593Smuzhiyun    local lnet=$2
121*4882a593Smuzhiyun    local rnet=$3
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun    ip -net $ns xfrm policy get src $lnet dst $rnet dir out > /dev/null
124*4882a593Smuzhiyun    if [ $? -ne 0 ] && [ $policy_checks_ok -eq 1 ] ;then
125*4882a593Smuzhiyun        policy_checks_ok=0
126*4882a593Smuzhiyun        echo "FAIL: ip -net $ns xfrm policy get src $lnet dst $rnet dir out"
127*4882a593Smuzhiyun        ret=1
128*4882a593Smuzhiyun    fi
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun    ip -net $ns xfrm policy get src $rnet dst $lnet dir fwd > /dev/null
131*4882a593Smuzhiyun    if [ $? -ne 0 ] && [ $policy_checks_ok -eq 1 ] ;then
132*4882a593Smuzhiyun        policy_checks_ok=0
133*4882a593Smuzhiyun        echo "FAIL: ip -net $ns xfrm policy get src $rnet dst $lnet dir fwd"
134*4882a593Smuzhiyun        ret=1
135*4882a593Smuzhiyun    fi
136*4882a593Smuzhiyun}
137*4882a593Smuzhiyun
138*4882a593Smuzhiyundo_exception() {
139*4882a593Smuzhiyun    local ns=$1
140*4882a593Smuzhiyun    local me=$2
141*4882a593Smuzhiyun    local remote=$3
142*4882a593Smuzhiyun    local encryptip=$4
143*4882a593Smuzhiyun    local plain=$5
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun    # network $plain passes without tunnel
146*4882a593Smuzhiyun    ip -net $ns xfrm policy add dst $plain dir out priority 10 action allow
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun    # direct policy for $encryptip, use tunnel, higher prio takes precedence
149*4882a593Smuzhiyun    ip -net $ns xfrm policy add dst $encryptip dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow
150*4882a593Smuzhiyun}
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun# policies that are not supposed to match any packets generated in this test.
153*4882a593Smuzhiyundo_dummies4() {
154*4882a593Smuzhiyun    local ns=$1
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun    for i in $(seq 10 16);do
157*4882a593Smuzhiyun      # dummy policy with wildcard src/dst.
158*4882a593Smuzhiyun      echo netns exec $ns ip xfrm policy add src 0.0.0.0/0 dst 10.$i.99.0/30 dir out action block
159*4882a593Smuzhiyun      echo netns exec $ns ip xfrm policy add src 10.$i.99.0/30 dst 0.0.0.0/0 dir out action block
160*4882a593Smuzhiyun      for j in $(seq 32 64);do
161*4882a593Smuzhiyun        echo netns exec $ns ip xfrm policy add src 10.$i.1.0/30 dst 10.$i.$j.0/30 dir out action block
162*4882a593Smuzhiyun        # silly, as it encompasses the one above too, but its allowed:
163*4882a593Smuzhiyun        echo netns exec $ns ip xfrm policy add src 10.$i.1.0/29 dst 10.$i.$j.0/29 dir out action block
164*4882a593Smuzhiyun        # and yet again, even more broad one.
165*4882a593Smuzhiyun        echo netns exec $ns ip xfrm policy add src 10.$i.1.0/24 dst 10.$i.$j.0/24 dir out action block
166*4882a593Smuzhiyun        echo netns exec $ns ip xfrm policy add src 10.$i.$j.0/24 dst 10.$i.1.0/24 dir fwd action block
167*4882a593Smuzhiyun      done
168*4882a593Smuzhiyun    done | ip -batch /dev/stdin
169*4882a593Smuzhiyun}
170*4882a593Smuzhiyun
171*4882a593Smuzhiyundo_dummies6() {
172*4882a593Smuzhiyun    local ns=$1
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun    for i in $(seq 10 16);do
175*4882a593Smuzhiyun      for j in $(seq 32 64);do
176*4882a593Smuzhiyun       echo netns exec $ns ip xfrm policy add src dead:$i::/64 dst dead:$i:$j::/64 dir out action block
177*4882a593Smuzhiyun       echo netns exec $ns ip xfrm policy add src dead:$i:$j::/64 dst dead:$i::/24 dir fwd action block
178*4882a593Smuzhiyun      done
179*4882a593Smuzhiyun    done | ip -batch /dev/stdin
180*4882a593Smuzhiyun}
181*4882a593Smuzhiyun
182*4882a593Smuzhiyuncheck_ipt_policy_count()
183*4882a593Smuzhiyun{
184*4882a593Smuzhiyun	ns=$1
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun	ip netns exec $ns iptables-save -c |grep policy | ( read c rest
187*4882a593Smuzhiyun		ip netns exec $ns iptables -Z
188*4882a593Smuzhiyun		if [ x"$c" = x'[0:0]' ]; then
189*4882a593Smuzhiyun			exit 0
190*4882a593Smuzhiyun		elif [ x"$c" = x ]; then
191*4882a593Smuzhiyun			echo "ERROR: No counters"
192*4882a593Smuzhiyun			ret=1
193*4882a593Smuzhiyun			exit 111
194*4882a593Smuzhiyun		else
195*4882a593Smuzhiyun			exit 1
196*4882a593Smuzhiyun		fi
197*4882a593Smuzhiyun	)
198*4882a593Smuzhiyun}
199*4882a593Smuzhiyun
200*4882a593Smuzhiyuncheck_xfrm() {
201*4882a593Smuzhiyun	# 0: iptables -m policy rule count == 0
202*4882a593Smuzhiyun	# 1: iptables -m policy rule count != 0
203*4882a593Smuzhiyun	rval=$1
204*4882a593Smuzhiyun	ip=$2
205*4882a593Smuzhiyun	local lret=0
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun	ip netns exec ns1 ping -q -c 1 10.0.2.$ip > /dev/null
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun	check_ipt_policy_count ns3
210*4882a593Smuzhiyun	if [ $? -ne $rval ] ; then
211*4882a593Smuzhiyun		lret=1
212*4882a593Smuzhiyun	fi
213*4882a593Smuzhiyun	check_ipt_policy_count ns4
214*4882a593Smuzhiyun	if [ $? -ne $rval ] ; then
215*4882a593Smuzhiyun		lret=1
216*4882a593Smuzhiyun	fi
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun	ip netns exec ns2 ping -q -c 1 10.0.1.$ip > /dev/null
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun	check_ipt_policy_count ns3
221*4882a593Smuzhiyun	if [ $? -ne $rval ] ; then
222*4882a593Smuzhiyun		lret=1
223*4882a593Smuzhiyun	fi
224*4882a593Smuzhiyun	check_ipt_policy_count ns4
225*4882a593Smuzhiyun	if [ $? -ne $rval ] ; then
226*4882a593Smuzhiyun		lret=1
227*4882a593Smuzhiyun	fi
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun	return $lret
230*4882a593Smuzhiyun}
231*4882a593Smuzhiyun
232*4882a593Smuzhiyuncheck_exceptions()
233*4882a593Smuzhiyun{
234*4882a593Smuzhiyun	logpostfix="$1"
235*4882a593Smuzhiyun	local lret=0
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun	# ping to .254 should be excluded from the tunnel (exception is in place).
238*4882a593Smuzhiyun	check_xfrm 0 254
239*4882a593Smuzhiyun	if [ $? -ne 0 ]; then
240*4882a593Smuzhiyun		echo "FAIL: expected ping to .254 to fail ($logpostfix)"
241*4882a593Smuzhiyun		lret=1
242*4882a593Smuzhiyun	else
243*4882a593Smuzhiyun		echo "PASS: ping to .254 bypassed ipsec tunnel ($logpostfix)"
244*4882a593Smuzhiyun	fi
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun	# ping to .253 should use use ipsec due to direct policy exception.
247*4882a593Smuzhiyun	check_xfrm 1 253
248*4882a593Smuzhiyun	if [ $? -ne 0 ]; then
249*4882a593Smuzhiyun		echo "FAIL: expected ping to .253 to use ipsec tunnel ($logpostfix)"
250*4882a593Smuzhiyun		lret=1
251*4882a593Smuzhiyun	else
252*4882a593Smuzhiyun		echo "PASS: direct policy matches ($logpostfix)"
253*4882a593Smuzhiyun	fi
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun	# ping to .2 should use ipsec.
256*4882a593Smuzhiyun	check_xfrm 1 2
257*4882a593Smuzhiyun	if [ $? -ne 0 ]; then
258*4882a593Smuzhiyun		echo "FAIL: expected ping to .2 to use ipsec tunnel ($logpostfix)"
259*4882a593Smuzhiyun		lret=1
260*4882a593Smuzhiyun	else
261*4882a593Smuzhiyun		echo "PASS: policy matches ($logpostfix)"
262*4882a593Smuzhiyun	fi
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun	return $lret
265*4882a593Smuzhiyun}
266*4882a593Smuzhiyun
267*4882a593Smuzhiyuncheck_hthresh_repeat()
268*4882a593Smuzhiyun{
269*4882a593Smuzhiyun	local log=$1
270*4882a593Smuzhiyun	i=0
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun	for i in $(seq 1 10);do
273*4882a593Smuzhiyun		ip -net ns1 xfrm policy update src e000:0001::0000 dst ff01::0014:0000:0001 dir in tmpl src :: dst :: proto esp mode tunnel priority 100 action allow || break
274*4882a593Smuzhiyun		ip -net ns1 xfrm policy set hthresh6 0 28 || break
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun		ip -net ns1 xfrm policy update src e000:0001::0000 dst ff01::01 dir in tmpl src :: dst :: proto esp mode tunnel priority 100 action allow || break
277*4882a593Smuzhiyun		ip -net ns1 xfrm policy set hthresh6 0 28 || break
278*4882a593Smuzhiyun	done
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun	if [ $i -ne 10 ] ;then
281*4882a593Smuzhiyun		echo "FAIL: $log" 1>&2
282*4882a593Smuzhiyun		ret=1
283*4882a593Smuzhiyun		return 1
284*4882a593Smuzhiyun	fi
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun	echo "PASS: $log"
287*4882a593Smuzhiyun	return 0
288*4882a593Smuzhiyun}
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun# insert non-overlapping policies in a random order and check that
291*4882a593Smuzhiyun# all of them can be fetched using the traffic selectors.
292*4882a593Smuzhiyuncheck_random_order()
293*4882a593Smuzhiyun{
294*4882a593Smuzhiyun	local ns=$1
295*4882a593Smuzhiyun	local log=$2
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun	for i in $(seq 100); do
298*4882a593Smuzhiyun		ip -net $ns xfrm policy flush
299*4882a593Smuzhiyun		for j in $(seq 0 16 255 | sort -R); do
300*4882a593Smuzhiyun			ip -net $ns xfrm policy add dst $j.0.0.0/24 dir out priority 10 action allow
301*4882a593Smuzhiyun		done
302*4882a593Smuzhiyun		for j in $(seq 0 16 255); do
303*4882a593Smuzhiyun			if ! ip -net $ns xfrm policy get dst $j.0.0.0/24 dir out > /dev/null; then
304*4882a593Smuzhiyun				echo "FAIL: $log" 1>&2
305*4882a593Smuzhiyun				return 1
306*4882a593Smuzhiyun			fi
307*4882a593Smuzhiyun		done
308*4882a593Smuzhiyun	done
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun	for i in $(seq 100); do
311*4882a593Smuzhiyun		ip -net $ns xfrm policy flush
312*4882a593Smuzhiyun		for j in $(seq 0 16 255 | sort -R); do
313*4882a593Smuzhiyun			local addr=$(printf "e000:0000:%02x00::/56" $j)
314*4882a593Smuzhiyun			ip -net $ns xfrm policy add dst $addr dir out priority 10 action allow
315*4882a593Smuzhiyun		done
316*4882a593Smuzhiyun		for j in $(seq 0 16 255); do
317*4882a593Smuzhiyun			local addr=$(printf "e000:0000:%02x00::/56" $j)
318*4882a593Smuzhiyun			if ! ip -net $ns xfrm policy get dst $addr dir out > /dev/null; then
319*4882a593Smuzhiyun				echo "FAIL: $log" 1>&2
320*4882a593Smuzhiyun				return 1
321*4882a593Smuzhiyun			fi
322*4882a593Smuzhiyun		done
323*4882a593Smuzhiyun	done
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun	ip -net $ns xfrm policy flush
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun	echo "PASS: $log"
328*4882a593Smuzhiyun	return 0
329*4882a593Smuzhiyun}
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun#check for needed privileges
332*4882a593Smuzhiyunif [ "$(id -u)" -ne 0 ];then
333*4882a593Smuzhiyun	echo "SKIP: Need root privileges"
334*4882a593Smuzhiyun	exit $ksft_skip
335*4882a593Smuzhiyunfi
336*4882a593Smuzhiyun
337*4882a593Smuzhiyunip -Version 2>/dev/null >/dev/null
338*4882a593Smuzhiyunif [ $? -ne 0 ];then
339*4882a593Smuzhiyun	echo "SKIP: Could not run test without the ip tool"
340*4882a593Smuzhiyun	exit $ksft_skip
341*4882a593Smuzhiyunfi
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun# needed to check if policy lookup got valid ipsec result
344*4882a593Smuzhiyuniptables --version 2>/dev/null >/dev/null
345*4882a593Smuzhiyunif [ $? -ne 0 ];then
346*4882a593Smuzhiyun	echo "SKIP: Could not run test without iptables tool"
347*4882a593Smuzhiyun	exit $ksft_skip
348*4882a593Smuzhiyunfi
349*4882a593Smuzhiyun
350*4882a593Smuzhiyunfor i in 1 2 3 4; do
351*4882a593Smuzhiyun    ip netns add ns$i
352*4882a593Smuzhiyun    ip -net ns$i link set lo up
353*4882a593Smuzhiyundone
354*4882a593Smuzhiyun
355*4882a593SmuzhiyunDEV=veth0
356*4882a593Smuzhiyunip link add $DEV netns ns1 type veth peer name eth1 netns ns3
357*4882a593Smuzhiyunip link add $DEV netns ns2 type veth peer name eth1 netns ns4
358*4882a593Smuzhiyun
359*4882a593Smuzhiyunip link add $DEV netns ns3 type veth peer name veth0 netns ns4
360*4882a593Smuzhiyun
361*4882a593SmuzhiyunDEV=veth0
362*4882a593Smuzhiyunfor i in 1 2; do
363*4882a593Smuzhiyun    ip -net ns$i link set $DEV up
364*4882a593Smuzhiyun    ip -net ns$i addr add 10.0.$i.2/24 dev $DEV
365*4882a593Smuzhiyun    ip -net ns$i addr add dead:$i::2/64 dev $DEV
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun    ip -net ns$i addr add 10.0.$i.253 dev $DEV
368*4882a593Smuzhiyun    ip -net ns$i addr add 10.0.$i.254 dev $DEV
369*4882a593Smuzhiyun    ip -net ns$i addr add dead:$i::fd dev $DEV
370*4882a593Smuzhiyun    ip -net ns$i addr add dead:$i::fe dev $DEV
371*4882a593Smuzhiyundone
372*4882a593Smuzhiyun
373*4882a593Smuzhiyunfor i in 3 4; do
374*4882a593Smuzhiyunip -net ns$i link set eth1 up
375*4882a593Smuzhiyunip -net ns$i link set veth0 up
376*4882a593Smuzhiyundone
377*4882a593Smuzhiyun
378*4882a593Smuzhiyunip -net ns1 route add default via 10.0.1.1
379*4882a593Smuzhiyunip -net ns2 route add default via 10.0.2.1
380*4882a593Smuzhiyun
381*4882a593Smuzhiyunip -net ns3 addr add 10.0.1.1/24 dev eth1
382*4882a593Smuzhiyunip -net ns3 addr add 10.0.3.1/24 dev veth0
383*4882a593Smuzhiyunip -net ns3 addr add 2001:1::1/64 dev eth1
384*4882a593Smuzhiyunip -net ns3 addr add 2001:3::1/64 dev veth0
385*4882a593Smuzhiyun
386*4882a593Smuzhiyunip -net ns3 route add default via 10.0.3.10
387*4882a593Smuzhiyun
388*4882a593Smuzhiyunip -net ns4 addr add 10.0.2.1/24 dev eth1
389*4882a593Smuzhiyunip -net ns4 addr add 10.0.3.10/24 dev veth0
390*4882a593Smuzhiyunip -net ns4 addr add 2001:2::1/64 dev eth1
391*4882a593Smuzhiyunip -net ns4 addr add 2001:3::10/64 dev veth0
392*4882a593Smuzhiyunip -net ns4 route add default via 10.0.3.1
393*4882a593Smuzhiyun
394*4882a593Smuzhiyunfor j in 4 6; do
395*4882a593Smuzhiyun	for i in 3 4;do
396*4882a593Smuzhiyun		ip netns exec ns$i sysctl net.ipv$j.conf.eth1.forwarding=1 > /dev/null
397*4882a593Smuzhiyun		ip netns exec ns$i sysctl net.ipv$j.conf.veth0.forwarding=1 > /dev/null
398*4882a593Smuzhiyun	done
399*4882a593Smuzhiyundone
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun# abuse iptables rule counter to check if ping matches a policy
402*4882a593Smuzhiyunip netns exec ns3 iptables -p icmp -A FORWARD -m policy --dir out --pol ipsec
403*4882a593Smuzhiyunip netns exec ns4 iptables -p icmp -A FORWARD -m policy --dir out --pol ipsec
404*4882a593Smuzhiyunif [ $? -ne 0 ];then
405*4882a593Smuzhiyun	echo "SKIP: Could not insert iptables rule"
406*4882a593Smuzhiyun	for i in 1 2 3 4;do ip netns del ns$i;done
407*4882a593Smuzhiyun	exit $ksft_skip
408*4882a593Smuzhiyunfi
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun#          localip  remoteip  localnet    remotenet
411*4882a593Smuzhiyundo_esp ns3 10.0.3.1 10.0.3.10 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2
412*4882a593Smuzhiyundo_esp ns3 dead:3::1 dead:3::10 dead:1::/64 dead:2::/64 $SPI1 $SPI2
413*4882a593Smuzhiyundo_esp ns4 10.0.3.10 10.0.3.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1
414*4882a593Smuzhiyundo_esp ns4 dead:3::10 dead:3::1 dead:2::/64 dead:1::/64 $SPI2 $SPI1
415*4882a593Smuzhiyun
416*4882a593Smuzhiyundo_dummies4 ns3
417*4882a593Smuzhiyundo_dummies6 ns4
418*4882a593Smuzhiyun
419*4882a593Smuzhiyundo_esp_policy_get_check ns3 10.0.1.0/24 10.0.2.0/24
420*4882a593Smuzhiyundo_esp_policy_get_check ns4 10.0.2.0/24 10.0.1.0/24
421*4882a593Smuzhiyundo_esp_policy_get_check ns3 dead:1::/64 dead:2::/64
422*4882a593Smuzhiyundo_esp_policy_get_check ns4 dead:2::/64 dead:1::/64
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun# ping to .254 should use ipsec, exception is not installed.
425*4882a593Smuzhiyuncheck_xfrm 1 254
426*4882a593Smuzhiyunif [ $? -ne 0 ]; then
427*4882a593Smuzhiyun	echo "FAIL: expected ping to .254 to use ipsec tunnel"
428*4882a593Smuzhiyun	ret=1
429*4882a593Smuzhiyunelse
430*4882a593Smuzhiyun	echo "PASS: policy before exception matches"
431*4882a593Smuzhiyunfi
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun# installs exceptions
434*4882a593Smuzhiyun#                localip  remoteip   encryptdst  plaindst
435*4882a593Smuzhiyundo_exception ns3 10.0.3.1 10.0.3.10 10.0.2.253 10.0.2.240/28
436*4882a593Smuzhiyundo_exception ns4 10.0.3.10 10.0.3.1 10.0.1.253 10.0.1.240/28
437*4882a593Smuzhiyun
438*4882a593Smuzhiyundo_exception ns3 dead:3::1 dead:3::10 dead:2::fd  dead:2:f0::/96
439*4882a593Smuzhiyundo_exception ns4 dead:3::10 dead:3::1 dead:1::fd  dead:1:f0::/96
440*4882a593Smuzhiyun
441*4882a593Smuzhiyuncheck_exceptions "exceptions"
442*4882a593Smuzhiyunif [ $? -ne 0 ]; then
443*4882a593Smuzhiyun	ret=1
444*4882a593Smuzhiyunfi
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun# insert block policies with adjacent/overlapping netmasks
447*4882a593Smuzhiyundo_overlap ns3
448*4882a593Smuzhiyun
449*4882a593Smuzhiyuncheck_exceptions "exceptions and block policies"
450*4882a593Smuzhiyunif [ $? -ne 0 ]; then
451*4882a593Smuzhiyun	ret=1
452*4882a593Smuzhiyunfi
453*4882a593Smuzhiyun
454*4882a593Smuzhiyunfor n in ns3 ns4;do
455*4882a593Smuzhiyun	ip -net $n xfrm policy set hthresh4 28 24 hthresh6 126 125
456*4882a593Smuzhiyun	sleep $((RANDOM%5))
457*4882a593Smuzhiyundone
458*4882a593Smuzhiyun
459*4882a593Smuzhiyuncheck_exceptions "exceptions and block policies after hresh changes"
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun# full flush of policy db, check everything gets freed incl. internal meta data
462*4882a593Smuzhiyunip -net ns3 xfrm policy flush
463*4882a593Smuzhiyun
464*4882a593Smuzhiyundo_esp_policy ns3 10.0.3.1 10.0.3.10 10.0.1.0/24 10.0.2.0/24
465*4882a593Smuzhiyundo_exception ns3 10.0.3.1 10.0.3.10 10.0.2.253 10.0.2.240/28
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun# move inexact policies to hash table
468*4882a593Smuzhiyunip -net ns3 xfrm policy set hthresh4 16 16
469*4882a593Smuzhiyun
470*4882a593Smuzhiyunsleep $((RANDOM%5))
471*4882a593Smuzhiyuncheck_exceptions "exceptions and block policies after hthresh change in ns3"
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun# restore original hthresh settings -- move policies back to tables
474*4882a593Smuzhiyunfor n in ns3 ns4;do
475*4882a593Smuzhiyun	ip -net $n xfrm policy set hthresh4 32 32 hthresh6 128 128
476*4882a593Smuzhiyun	sleep $((RANDOM%5))
477*4882a593Smuzhiyundone
478*4882a593Smuzhiyuncheck_exceptions "exceptions and block policies after htresh change to normal"
479*4882a593Smuzhiyun
480*4882a593Smuzhiyuncheck_hthresh_repeat "policies with repeated htresh change"
481*4882a593Smuzhiyun
482*4882a593Smuzhiyuncheck_random_order ns3 "policies inserted in random order"
483*4882a593Smuzhiyun
484*4882a593Smuzhiyunfor i in 1 2 3 4;do ip netns del ns$i;done
485*4882a593Smuzhiyun
486*4882a593Smuzhiyunexit $ret
487