selftests: xfrm: add block rules with adjacent/overlapping subnets
The existing script lacks a policy pattern that triggers 'tree node merges' in the kernel. Consider adding policy affecting following subnet: pol1: dst 10.0.0.0/22 pol2: dst 10.0.0.0/23 # adds to existing 10.0.0.0/22 node -> no problems here. But now, lets consider reverse order: pol1: dst 10.0.0.0/24 pol2: dst 10.0.0.0/23 # CANNOT add to existing node When second policy gets added, the kernel must check that the new node ("10.0.0.0/23") doesn't overlap with any existing subnet. Example: dst 10.0.0.0/24 dst 10.0.0.1/24 dst 10.0.0.0/23 When the third policy gets added, the kernel must replace the nodes for the 10.0.0.0/24 and 10.0.0.1/24 policies with a single one and must merge all the subtrees/lists stored in those nodes into the new node. The existing test cases only have overlaps with a single node, so no merging takes place (we can always remove the 'old' node and replace it with the new subnet prefix). Add a few 'block policies' in a pattern that triggers this, with a priority that will make kernel prefer the 'esp' rules. Make sure the 'tunnel ping' tests still pass after they have been added. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
d972f3dce8
commit
0977b2383d
|
@ -46,6 +46,58 @@ do_esp() {
|
|||
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
|
||||
}
|
||||
|
||||
# add policies with different netmasks, to make sure kernel carries
|
||||
# the policies contained within new netmask over when search tree is
|
||||
# re-built.
|
||||
# peer netns that are supposed to be encapsulated via esp have addresses
|
||||
# in the 10.0.1.0/24 and 10.0.2.0/24 subnets, respectively.
|
||||
#
|
||||
# Adding a policy for '10.0.1.0/23' will make it necessary to
|
||||
# alter the prefix of 10.0.1.0 subnet.
|
||||
# In case new prefix overlaps with existing node, the node and all
|
||||
# policies it carries need to be merged with the existing one(s).
|
||||
#
|
||||
# Do that here.
|
||||
do_overlap()
|
||||
{
|
||||
local ns=$1
|
||||
|
||||
# adds new nodes to tree (neither network exists yet in policy database).
|
||||
ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/24 dir fwd priority 200 action block
|
||||
|
||||
# adds a new node in the 10.0.0.0/24 tree (dst node exists).
|
||||
ip -net $ns xfrm policy add src 10.2.0.0/24 dst 10.0.0.0/24 dir fwd priority 200 action block
|
||||
|
||||
# adds a 10.2.0.0/24 node, but for different dst.
|
||||
ip -net $ns xfrm policy add src 10.2.0.0/24 dst 10.0.1.0/24 dir fwd priority 200 action block
|
||||
|
||||
# dst now overlaps with the 10.0.1.0/24 ESP policy in fwd.
|
||||
# kernel must 'promote' existing one (10.0.0.0/24) to 10.0.0.0/23.
|
||||
# But 10.0.0.0/23 also includes existing 10.0.1.0/24, so that node
|
||||
# also has to be merged too, including source-sorted subtrees.
|
||||
# old:
|
||||
# 10.0.0.0/24 (node 1 in dst tree of the bin)
|
||||
# 10.1.0.0/24 (node in src tree of dst node 1)
|
||||
# 10.2.0.0/24 (node in src tree of dst node 1)
|
||||
# 10.0.1.0/24 (node 2 in dst tree of the bin)
|
||||
# 10.0.2.0/24 (node in src tree of dst node 2)
|
||||
# 10.2.0.0/24 (node in src tree of dst node 2)
|
||||
#
|
||||
# The next 'policy add' adds dst '10.0.0.0/23', which means
|
||||
# that dst node 1 and dst node 2 have to be merged including
|
||||
# the sub-tree. As no duplicates are allowed, policies in
|
||||
# the two '10.0.2.0/24' are also merged.
|
||||
#
|
||||
# after the 'add', internal search tree should look like this:
|
||||
# 10.0.0.0/23 (node in dst tree of bin)
|
||||
# 10.0.2.0/24 (node in src tree of dst node)
|
||||
# 10.1.0.0/24 (node in src tree of dst node)
|
||||
# 10.2.0.0/24 (node in src tree of dst node)
|
||||
#
|
||||
# 10.0.0.0/24 and 10.0.1.0/24 nodes have been merged as 10.0.0.0/23.
|
||||
ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/23 dir fwd priority 200 action block
|
||||
}
|
||||
|
||||
do_esp_policy_get_check() {
|
||||
local ns=$1
|
||||
local lnet=$2
|
||||
|
@ -160,6 +212,41 @@ check_xfrm() {
|
|||
return $lret
|
||||
}
|
||||
|
||||
check_exceptions()
|
||||
{
|
||||
logpostfix="$1"
|
||||
local lret=0
|
||||
|
||||
# ping to .254 should be excluded from the tunnel (exception is in place).
|
||||
check_xfrm 0 254
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: expected ping to .254 to fail ($logpostfix)"
|
||||
lret=1
|
||||
else
|
||||
echo "PASS: ping to .254 bypassed ipsec tunnel ($logpostfix)"
|
||||
fi
|
||||
|
||||
# ping to .253 should use use ipsec due to direct policy exception.
|
||||
check_xfrm 1 253
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: expected ping to .253 to use ipsec tunnel ($logpostfix)"
|
||||
lret=1
|
||||
else
|
||||
echo "PASS: direct policy matches ($logpostfix)"
|
||||
fi
|
||||
|
||||
# ping to .2 should use ipsec.
|
||||
check_xfrm 1 2
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: expected ping to .2 to use ipsec tunnel ($logpostfix)"
|
||||
lret=1
|
||||
else
|
||||
echo "PASS: policy matches ($logpostfix)"
|
||||
fi
|
||||
|
||||
return $lret
|
||||
}
|
||||
|
||||
#check for needed privileges
|
||||
if [ "$(id -u)" -ne 0 ];then
|
||||
echo "SKIP: Need root privileges"
|
||||
|
@ -270,31 +357,17 @@ do_exception ns4 10.0.3.10 10.0.3.1 10.0.1.253 10.0.1.240/28
|
|||
do_exception ns3 dead:3::1 dead:3::10 dead:2::fd dead:2:f0::/96
|
||||
do_exception ns4 dead:3::10 dead:3::1 dead:1::fd dead:1:f0::/96
|
||||
|
||||
# ping to .254 should now be excluded from the tunnel
|
||||
check_xfrm 0 254
|
||||
check_exceptions "exceptions"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: expected ping to .254 to fail"
|
||||
ret=1
|
||||
else
|
||||
echo "PASS: ping to .254 bypassed ipsec tunnel"
|
||||
fi
|
||||
|
||||
# ping to .253 should use use ipsec due to direct policy exception.
|
||||
check_xfrm 1 253
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: expected ping to .253 to use ipsec tunnel"
|
||||
ret=1
|
||||
else
|
||||
echo "PASS: direct policy matches"
|
||||
fi
|
||||
# insert block policies with adjacent/overlapping netmasks
|
||||
do_overlap ns3
|
||||
|
||||
# ping to .2 should use ipsec.
|
||||
check_xfrm 1 2
|
||||
check_exceptions "exceptions and block policies"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: expected ping to .2 to use ipsec tunnel"
|
||||
ret=1
|
||||
else
|
||||
echo "PASS: policy matches"
|
||||
fi
|
||||
|
||||
for i in 1 2 3 4;do ip netns del ns$i;done
|
||||
|
|
Loading…
Reference in New Issue