forked from Minki/linux
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== pull request (net-next): ipsec-next 2018-12-18 1) Add xfrm policy selftest scripts. From Florian Westphal. 2) Split inexact policies into four different search list classes and use the rbtree infrastructure to store/lookup the policies. This is to improve the policy lookup performance after the flowcache removal. Patches from Florian Westphal. 3) Various coding style fixes, from Colin Ian King. 4) Fix policy lookup logic after adding the inexact policy search tree infrastructure. From Florian Westphal. 5) Remove a useless remove BUG_ON from xfrm6_dst_ifdown. From Li RongQing. 6) Use the correct policy direction for lookups on hash rebuilding. From Florian Westphal. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
77c7a7b3e7
@ -5,6 +5,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/rhashtable-types.h>
|
||||
#include <linux/xfrm.h>
|
||||
#include <net/dst_ops.h>
|
||||
|
||||
@ -53,6 +54,7 @@ struct netns_xfrm {
|
||||
unsigned int policy_count[XFRM_POLICY_MAX * 2];
|
||||
struct work_struct policy_hash_work;
|
||||
struct xfrm_policy_hthresh policy_hthresh;
|
||||
struct list_head inexact_bins;
|
||||
|
||||
|
||||
struct sock *nlsk;
|
||||
|
@ -577,6 +577,7 @@ struct xfrm_policy {
|
||||
/* This lock only affects elements except for entry. */
|
||||
rwlock_t lock;
|
||||
refcount_t refcnt;
|
||||
u32 pos;
|
||||
struct timer_list timer;
|
||||
|
||||
atomic_t genid;
|
||||
@ -589,6 +590,7 @@ struct xfrm_policy {
|
||||
struct xfrm_lifetime_cur curlft;
|
||||
struct xfrm_policy_walk_entry walk;
|
||||
struct xfrm_policy_queue polq;
|
||||
bool bydst_reinsert;
|
||||
u8 type;
|
||||
u8 action;
|
||||
u8 flags;
|
||||
@ -596,6 +598,7 @@ struct xfrm_policy {
|
||||
u16 family;
|
||||
struct xfrm_sec_ctx *security;
|
||||
struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
|
||||
struct hlist_node bydst_inexact_list;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
@ -1967,7 +1970,7 @@ static inline void xfrm_dev_state_delete(struct xfrm_state *x)
|
||||
static inline void xfrm_dev_state_free(struct xfrm_state *x)
|
||||
{
|
||||
struct xfrm_state_offload *xso = &x->xso;
|
||||
struct net_device *dev = xso->dev;
|
||||
struct net_device *dev = xso->dev;
|
||||
|
||||
if (dev && dev->xfrmdev_ops) {
|
||||
if (dev->xfrmdev_ops->xdo_dev_state_free)
|
||||
|
@ -262,7 +262,6 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
|
||||
if (xdst->u.rt6.rt6i_idev->dev == dev) {
|
||||
struct inet6_dev *loopback_idev =
|
||||
in6_dev_get(dev_net(dev)->loopback_dev);
|
||||
BUG_ON(!loopback_idev);
|
||||
|
||||
do {
|
||||
in6_dev_put(xdst->u.rt6.rt6i_idev);
|
||||
|
@ -2020,7 +2020,7 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol)
|
||||
|
||||
static inline int pfkey_xfrm_policy2sec_ctx_size(const struct xfrm_policy *xp)
|
||||
{
|
||||
struct xfrm_sec_ctx *xfrm_ctx = xp->security;
|
||||
struct xfrm_sec_ctx *xfrm_ctx = xp->security;
|
||||
|
||||
if (xfrm_ctx) {
|
||||
int len = sizeof(struct sadb_x_sec_ctx);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,8 @@
|
||||
CFLAGS = -Wall -Wl,--no-as-needed -O2 -g
|
||||
CFLAGS += -I../../../../usr/include/
|
||||
|
||||
TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh
|
||||
TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh \
|
||||
rtnetlink.sh xfrm_policy.sh
|
||||
TEST_PROGS += fib_tests.sh fib-onlink-tests.sh pmtu.sh udpgso.sh ip_defrag.sh
|
||||
TEST_PROGS += udpgso_bench.sh fib_rule_tests.sh msg_zerocopy.sh psock_snd.sh
|
||||
TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_any.sh
|
||||
|
302
tools/testing/selftests/net/xfrm_policy.sh
Executable file
302
tools/testing/selftests/net/xfrm_policy.sh
Executable file
@ -0,0 +1,302 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Check xfrm policy resolution. Topology:
|
||||
#
|
||||
# 1.2 1.1 3.1 3.10 2.1 2.2
|
||||
# eth1 eth1 veth0 veth0 eth1 eth1
|
||||
# ns1 ---- ns3 ----- ns4 ---- ns2
|
||||
#
|
||||
# ns3 and ns4 are connected via ipsec tunnel.
|
||||
# pings from ns1 to ns2 (and vice versa) are supposed to work like this:
|
||||
# ns1: ping 10.0.2.2: passes via ipsec tunnel.
|
||||
# ns2: ping 10.0.1.2: passes via ipsec tunnel.
|
||||
|
||||
# ns1: ping 10.0.1.253: passes via ipsec tunnel (direct policy)
|
||||
# ns2: ping 10.0.2.253: passes via ipsec tunnel (direct policy)
|
||||
#
|
||||
# ns1: ping 10.0.2.254: does NOT pass via ipsec tunnel (exception)
|
||||
# ns2: ping 10.0.1.254: does NOT pass via ipsec tunnel (exception)
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
ret=0
|
||||
policy_checks_ok=1
|
||||
|
||||
KEY_SHA=0xdeadbeef1234567890abcdefabcdefabcdefabcd
|
||||
KEY_AES=0x0123456789abcdef0123456789012345
|
||||
SPI1=0x1
|
||||
SPI2=0x2
|
||||
|
||||
do_esp() {
|
||||
local ns=$1
|
||||
local me=$2
|
||||
local remote=$3
|
||||
local lnet=$4
|
||||
local rnet=$5
|
||||
local spi_out=$6
|
||||
local spi_in=$7
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
# to encrypt packets as they go out (includes forwarded packets that need encapsulation)
|
||||
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
|
||||
# to fwd decrypted packets after esp processing:
|
||||
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
|
||||
}
|
||||
|
||||
do_esp_policy_get_check() {
|
||||
local ns=$1
|
||||
local lnet=$2
|
||||
local rnet=$3
|
||||
|
||||
ip -net $ns xfrm policy get src $lnet dst $rnet dir out > /dev/null
|
||||
if [ $? -ne 0 ] && [ $policy_checks_ok -eq 1 ] ;then
|
||||
policy_checks_ok=0
|
||||
echo "FAIL: ip -net $ns xfrm policy get src $lnet dst $rnet dir out"
|
||||
ret=1
|
||||
fi
|
||||
|
||||
ip -net $ns xfrm policy get src $rnet dst $lnet dir fwd > /dev/null
|
||||
if [ $? -ne 0 ] && [ $policy_checks_ok -eq 1 ] ;then
|
||||
policy_checks_ok=0
|
||||
echo "FAIL: ip -net $ns xfrm policy get src $rnet dst $lnet dir fwd"
|
||||
ret=1
|
||||
fi
|
||||
}
|
||||
|
||||
do_exception() {
|
||||
local ns=$1
|
||||
local me=$2
|
||||
local remote=$3
|
||||
local encryptip=$4
|
||||
local plain=$5
|
||||
|
||||
# network $plain passes without tunnel
|
||||
ip -net $ns xfrm policy add dst $plain dir out priority 10 action allow
|
||||
|
||||
# direct policy for $encryptip, use tunnel, higher prio takes precedence
|
||||
ip -net $ns xfrm policy add dst $encryptip dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow
|
||||
}
|
||||
|
||||
# policies that are not supposed to match any packets generated in this test.
|
||||
do_dummies4() {
|
||||
local ns=$1
|
||||
|
||||
for i in $(seq 10 16);do
|
||||
# dummy policy with wildcard src/dst.
|
||||
echo netns exec $ns ip xfrm policy add src 0.0.0.0/0 dst 10.$i.99.0/30 dir out action block
|
||||
echo netns exec $ns ip xfrm policy add src 10.$i.99.0/30 dst 0.0.0.0/0 dir out action block
|
||||
for j in $(seq 32 64);do
|
||||
echo netns exec $ns ip xfrm policy add src 10.$i.1.0/30 dst 10.$i.$j.0/30 dir out action block
|
||||
# silly, as it encompasses the one above too, but its allowed:
|
||||
echo netns exec $ns ip xfrm policy add src 10.$i.1.0/29 dst 10.$i.$j.0/29 dir out action block
|
||||
# and yet again, even more broad one.
|
||||
echo netns exec $ns ip xfrm policy add src 10.$i.1.0/24 dst 10.$i.$j.0/24 dir out action block
|
||||
echo netns exec $ns ip xfrm policy add src 10.$i.$j.0/24 dst 10.$i.1.0/24 dir fwd action block
|
||||
done
|
||||
done | ip -batch /dev/stdin
|
||||
}
|
||||
|
||||
do_dummies6() {
|
||||
local ns=$1
|
||||
|
||||
for i in $(seq 10 16);do
|
||||
for j in $(seq 32 64);do
|
||||
echo netns exec $ns ip xfrm policy add src dead:$i::/64 dst dead:$i:$j::/64 dir out action block
|
||||
echo netns exec $ns ip xfrm policy add src dead:$i:$j::/64 dst dead:$i::/24 dir fwd action block
|
||||
done
|
||||
done | ip -batch /dev/stdin
|
||||
}
|
||||
|
||||
check_ipt_policy_count()
|
||||
{
|
||||
ns=$1
|
||||
|
||||
ip netns exec $ns iptables-save -c |grep policy | ( read c rest
|
||||
ip netns exec $ns iptables -Z
|
||||
if [ x"$c" = x'[0:0]' ]; then
|
||||
exit 0
|
||||
elif [ x"$c" = x ]; then
|
||||
echo "ERROR: No counters"
|
||||
ret=1
|
||||
exit 111
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
}
|
||||
|
||||
check_xfrm() {
|
||||
# 0: iptables -m policy rule count == 0
|
||||
# 1: iptables -m policy rule count != 0
|
||||
rval=$1
|
||||
ip=$2
|
||||
lret=0
|
||||
|
||||
ip netns exec ns1 ping -q -c 1 10.0.2.$ip > /dev/null
|
||||
|
||||
check_ipt_policy_count ns3
|
||||
if [ $? -ne $rval ] ; then
|
||||
lret=1
|
||||
fi
|
||||
check_ipt_policy_count ns4
|
||||
if [ $? -ne $rval ] ; then
|
||||
lret=1
|
||||
fi
|
||||
|
||||
ip netns exec ns2 ping -q -c 1 10.0.1.$ip > /dev/null
|
||||
|
||||
check_ipt_policy_count ns3
|
||||
if [ $? -ne $rval ] ; then
|
||||
lret=1
|
||||
fi
|
||||
check_ipt_policy_count ns4
|
||||
if [ $? -ne $rval ] ; then
|
||||
lret=1
|
||||
fi
|
||||
|
||||
return $lret
|
||||
}
|
||||
|
||||
#check for needed privileges
|
||||
if [ "$(id -u)" -ne 0 ];then
|
||||
echo "SKIP: Need root privileges"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
|
||||
ip -Version 2>/dev/null >/dev/null
|
||||
if [ $? -ne 0 ];then
|
||||
echo "SKIP: Could not run test without the ip tool"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
|
||||
# needed to check if policy lookup got valid ipsec result
|
||||
iptables --version 2>/dev/null >/dev/null
|
||||
if [ $? -ne 0 ];then
|
||||
echo "SKIP: Could not run test without iptables tool"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
|
||||
for i in 1 2 3 4; do
|
||||
ip netns add ns$i
|
||||
ip -net ns$i link set lo up
|
||||
done
|
||||
|
||||
DEV=veth0
|
||||
ip link add $DEV netns ns1 type veth peer name eth1 netns ns3
|
||||
ip link add $DEV netns ns2 type veth peer name eth1 netns ns4
|
||||
|
||||
ip link add $DEV netns ns3 type veth peer name veth0 netns ns4
|
||||
|
||||
DEV=veth0
|
||||
for i in 1 2; do
|
||||
ip -net ns$i link set $DEV up
|
||||
ip -net ns$i addr add 10.0.$i.2/24 dev $DEV
|
||||
ip -net ns$i addr add dead:$i::2/64 dev $DEV
|
||||
|
||||
ip -net ns$i addr add 10.0.$i.253 dev $DEV
|
||||
ip -net ns$i addr add 10.0.$i.254 dev $DEV
|
||||
ip -net ns$i addr add dead:$i::fd dev $DEV
|
||||
ip -net ns$i addr add dead:$i::fe dev $DEV
|
||||
done
|
||||
|
||||
for i in 3 4; do
|
||||
ip -net ns$i link set eth1 up
|
||||
ip -net ns$i link set veth0 up
|
||||
done
|
||||
|
||||
ip -net ns1 route add default via 10.0.1.1
|
||||
ip -net ns2 route add default via 10.0.2.1
|
||||
|
||||
ip -net ns3 addr add 10.0.1.1/24 dev eth1
|
||||
ip -net ns3 addr add 10.0.3.1/24 dev veth0
|
||||
ip -net ns3 addr add 2001:1::1/64 dev eth1
|
||||
ip -net ns3 addr add 2001:3::1/64 dev veth0
|
||||
|
||||
ip -net ns3 route add default via 10.0.3.10
|
||||
|
||||
ip -net ns4 addr add 10.0.2.1/24 dev eth1
|
||||
ip -net ns4 addr add 10.0.3.10/24 dev veth0
|
||||
ip -net ns4 addr add 2001:2::1/64 dev eth1
|
||||
ip -net ns4 addr add 2001:3::10/64 dev veth0
|
||||
ip -net ns4 route add default via 10.0.3.1
|
||||
|
||||
for j in 4 6; do
|
||||
for i in 3 4;do
|
||||
ip netns exec ns$i sysctl net.ipv$j.conf.eth1.forwarding=1 > /dev/null
|
||||
ip netns exec ns$i sysctl net.ipv$j.conf.veth0.forwarding=1 > /dev/null
|
||||
done
|
||||
done
|
||||
|
||||
# abuse iptables rule counter to check if ping matches a policy
|
||||
ip netns exec ns3 iptables -p icmp -A FORWARD -m policy --dir out --pol ipsec
|
||||
ip netns exec ns4 iptables -p icmp -A FORWARD -m policy --dir out --pol ipsec
|
||||
if [ $? -ne 0 ];then
|
||||
echo "SKIP: Could not insert iptables rule"
|
||||
for i in 1 2 3 4;do ip netns del ns$i;done
|
||||
exit $ksft_skip
|
||||
fi
|
||||
|
||||
# localip remoteip localnet remotenet
|
||||
do_esp ns3 10.0.3.1 10.0.3.10 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2
|
||||
do_esp ns3 dead:3::1 dead:3::10 dead:1::/64 dead:2::/64 $SPI1 $SPI2
|
||||
do_esp ns4 10.0.3.10 10.0.3.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1
|
||||
do_esp ns4 dead:3::10 dead:3::1 dead:2::/64 dead:1::/64 $SPI2 $SPI1
|
||||
|
||||
do_dummies4 ns3
|
||||
do_dummies6 ns4
|
||||
|
||||
do_esp_policy_get_check ns3 10.0.1.0/24 10.0.2.0/24
|
||||
do_esp_policy_get_check ns4 10.0.2.0/24 10.0.1.0/24
|
||||
do_esp_policy_get_check ns3 dead:1::/64 dead:2::/64
|
||||
do_esp_policy_get_check ns4 dead:2::/64 dead:1::/64
|
||||
|
||||
# ping to .254 should use ipsec, exception is not installed.
|
||||
check_xfrm 1 254
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: expected ping to .254 to use ipsec tunnel"
|
||||
ret=1
|
||||
else
|
||||
echo "PASS: policy before exception matches"
|
||||
fi
|
||||
|
||||
# installs exceptions
|
||||
# localip remoteip encryptdst plaindst
|
||||
do_exception ns3 10.0.3.1 10.0.3.10 10.0.2.253 10.0.2.240/28
|
||||
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
|
||||
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
|
||||
|
||||
# ping to .2 should use ipsec.
|
||||
check_xfrm 1 2
|
||||
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
|
||||
|
||||
exit $ret
|
Loading…
Reference in New Issue
Block a user