mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
bpf: selftests: Move xfrm tunnel test to test_progs
test_progs is better than a shell script b/c C is a bit easier to maintain than shell. Also it's easier to use new infra like memory mapped global variables from C via bpf skeleton. Co-developed-by: Antony Antony <antony.antony@secunet.com> Signed-off-by: Antony Antony <antony.antony@secunet.com> Signed-off-by: Daniel Xu <dxu@dxuuu.xyz> Link: https://lore.kernel.org/r/a350db9e08520c64544562d88ec005a039124d9b.1702593901.git.dxu@dxuuu.xyz Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
02b4e126e6
commit
e7adc8291a
3 changed files with 151 additions and 95 deletions
|
@ -50,6 +50,7 @@
|
|||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/sysctl.h>
|
||||
|
@ -92,6 +93,11 @@
|
|||
#define IPIP_TUNL_DEV0 "ipip00"
|
||||
#define IPIP_TUNL_DEV1 "ipip11"
|
||||
|
||||
#define XFRM_AUTH "0x1111111111111111111111111111111111111111"
|
||||
#define XFRM_ENC "0x22222222222222222222222222222222"
|
||||
#define XFRM_SPI_IN_TO_OUT 0x1
|
||||
#define XFRM_SPI_OUT_TO_IN 0x2
|
||||
|
||||
#define PING_ARGS "-i 0.01 -c 3 -w 10 -q"
|
||||
|
||||
static int config_device(void)
|
||||
|
@ -264,6 +270,92 @@ static void delete_ipip_tunnel(void)
|
|||
SYS_NOFAIL("ip fou del port 5555 2> /dev/null");
|
||||
}
|
||||
|
||||
static int add_xfrm_tunnel(void)
|
||||
{
|
||||
/* at_ns0 namespace
|
||||
* at_ns0 -> root
|
||||
*/
|
||||
SYS(fail,
|
||||
"ip netns exec at_ns0 "
|
||||
"ip xfrm state add src %s dst %s proto esp "
|
||||
"spi %d reqid 1 mode tunnel "
|
||||
"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
|
||||
IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT, XFRM_AUTH, XFRM_ENC);
|
||||
SYS(fail,
|
||||
"ip netns exec at_ns0 "
|
||||
"ip xfrm policy add src %s/32 dst %s/32 dir out "
|
||||
"tmpl src %s dst %s proto esp reqid 1 "
|
||||
"mode tunnel",
|
||||
IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
|
||||
|
||||
/* root -> at_ns0 */
|
||||
SYS(fail,
|
||||
"ip netns exec at_ns0 "
|
||||
"ip xfrm state add src %s dst %s proto esp "
|
||||
"spi %d reqid 2 mode tunnel "
|
||||
"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
|
||||
IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN, XFRM_AUTH, XFRM_ENC);
|
||||
SYS(fail,
|
||||
"ip netns exec at_ns0 "
|
||||
"ip xfrm policy add src %s/32 dst %s/32 dir in "
|
||||
"tmpl src %s dst %s proto esp reqid 2 "
|
||||
"mode tunnel",
|
||||
IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0, IP4_ADDR1_VETH1, IP4_ADDR_VETH0);
|
||||
|
||||
/* address & route */
|
||||
SYS(fail, "ip netns exec at_ns0 ip addr add dev veth0 %s/32",
|
||||
IP4_ADDR_TUNL_DEV0);
|
||||
SYS(fail, "ip netns exec at_ns0 ip route add %s dev veth0 via %s src %s",
|
||||
IP4_ADDR_TUNL_DEV1, IP4_ADDR1_VETH1, IP4_ADDR_TUNL_DEV0);
|
||||
|
||||
/* root namespace
|
||||
* at_ns0 -> root
|
||||
*/
|
||||
SYS(fail,
|
||||
"ip xfrm state add src %s dst %s proto esp "
|
||||
"spi %d reqid 1 mode tunnel "
|
||||
"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
|
||||
IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT, XFRM_AUTH, XFRM_ENC);
|
||||
SYS(fail,
|
||||
"ip xfrm policy add src %s/32 dst %s/32 dir in "
|
||||
"tmpl src %s dst %s proto esp reqid 1 "
|
||||
"mode tunnel",
|
||||
IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
|
||||
|
||||
/* root -> at_ns0 */
|
||||
SYS(fail,
|
||||
"ip xfrm state add src %s dst %s proto esp "
|
||||
"spi %d reqid 2 mode tunnel "
|
||||
"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
|
||||
IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN, XFRM_AUTH, XFRM_ENC);
|
||||
SYS(fail,
|
||||
"ip xfrm policy add src %s/32 dst %s/32 dir out "
|
||||
"tmpl src %s dst %s proto esp reqid 2 "
|
||||
"mode tunnel",
|
||||
IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0, IP4_ADDR1_VETH1, IP4_ADDR_VETH0);
|
||||
|
||||
/* address & route */
|
||||
SYS(fail, "ip addr add dev veth1 %s/32", IP4_ADDR_TUNL_DEV1);
|
||||
SYS(fail, "ip route add %s dev veth1 via %s src %s",
|
||||
IP4_ADDR_TUNL_DEV0, IP4_ADDR_VETH0, IP4_ADDR_TUNL_DEV1);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void delete_xfrm_tunnel(void)
|
||||
{
|
||||
SYS_NOFAIL("ip xfrm policy delete dir out src %s/32 dst %s/32 2> /dev/null",
|
||||
IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0);
|
||||
SYS_NOFAIL("ip xfrm policy delete dir in src %s/32 dst %s/32 2> /dev/null",
|
||||
IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1);
|
||||
SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d 2> /dev/null",
|
||||
IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT);
|
||||
SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d 2> /dev/null",
|
||||
IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN);
|
||||
}
|
||||
|
||||
static int test_ping(int family, const char *addr)
|
||||
{
|
||||
SYS(fail, "%s %s %s > /dev/null", ping_command(family), PING_ARGS, addr);
|
||||
|
@ -532,6 +624,56 @@ static void test_ipip_tunnel(enum ipip_encap encap)
|
|||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
static void test_xfrm_tunnel(void)
|
||||
{
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
|
||||
.attach_point = BPF_TC_INGRESS);
|
||||
struct test_tunnel_kern *skel = NULL;
|
||||
struct nstoken *nstoken;
|
||||
int tc_prog_fd;
|
||||
int ifindex;
|
||||
int err;
|
||||
|
||||
err = add_xfrm_tunnel();
|
||||
if (!ASSERT_OK(err, "add_xfrm_tunnel"))
|
||||
return;
|
||||
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
goto done;
|
||||
|
||||
ifindex = if_nametoindex("veth1");
|
||||
if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))
|
||||
goto done;
|
||||
|
||||
/* attach tc prog to tunnel dev */
|
||||
tc_hook.ifindex = ifindex;
|
||||
tc_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state);
|
||||
if (!ASSERT_GE(tc_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (attach_tc_prog(&tc_hook, tc_prog_fd, -1))
|
||||
goto done;
|
||||
|
||||
/* ping from at_ns0 namespace test */
|
||||
nstoken = open_netns("at_ns0");
|
||||
err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV1);
|
||||
close_netns(nstoken);
|
||||
if (!ASSERT_OK(err, "test_ping"))
|
||||
goto done;
|
||||
|
||||
if (!ASSERT_EQ(skel->bss->xfrm_reqid, 1, "req_id"))
|
||||
goto done;
|
||||
if (!ASSERT_EQ(skel->bss->xfrm_spi, XFRM_SPI_IN_TO_OUT, "spi"))
|
||||
goto done;
|
||||
if (!ASSERT_EQ(skel->bss->xfrm_remote_ip, 0xac100164, "remote_ip"))
|
||||
goto done;
|
||||
|
||||
done:
|
||||
delete_xfrm_tunnel();
|
||||
if (skel)
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
#define RUN_TEST(name, ...) \
|
||||
({ \
|
||||
if (test__start_subtest(#name)) { \
|
||||
|
@ -548,6 +690,7 @@ static void *test_tunnel_run_tests(void *arg)
|
|||
RUN_TEST(ipip_tunnel, NONE);
|
||||
RUN_TEST(ipip_tunnel, FOU);
|
||||
RUN_TEST(ipip_tunnel, GUE);
|
||||
RUN_TEST(xfrm_tunnel);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -929,6 +929,10 @@ int ip6ip6_get_tunnel(struct __sk_buff *skb)
|
|||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
volatile int xfrm_reqid = 0;
|
||||
volatile int xfrm_spi = 0;
|
||||
volatile int xfrm_remote_ip = 0;
|
||||
|
||||
SEC("tc")
|
||||
int xfrm_get_state(struct __sk_buff *skb)
|
||||
{
|
||||
|
@ -939,9 +943,10 @@ int xfrm_get_state(struct __sk_buff *skb)
|
|||
if (ret < 0)
|
||||
return TC_ACT_OK;
|
||||
|
||||
bpf_printk("reqid %d spi 0x%x remote ip 0x%x\n",
|
||||
x.reqid, bpf_ntohl(x.spi),
|
||||
bpf_ntohl(x.remote_ipv4));
|
||||
xfrm_reqid = x.reqid;
|
||||
xfrm_spi = bpf_ntohl(x.spi);
|
||||
xfrm_remote_ip = bpf_ntohl(x.remote_ipv4);
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -517,90 +517,6 @@ test_ip6ip6()
|
|||
echo -e ${GREEN}"PASS: ip6$TYPE"${NC}
|
||||
}
|
||||
|
||||
setup_xfrm_tunnel()
|
||||
{
|
||||
auth=0x$(printf '1%.0s' {1..40})
|
||||
enc=0x$(printf '2%.0s' {1..32})
|
||||
spi_in_to_out=0x1
|
||||
spi_out_to_in=0x2
|
||||
# at_ns0 namespace
|
||||
# at_ns0 -> root
|
||||
ip netns exec at_ns0 \
|
||||
ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
|
||||
spi $spi_in_to_out reqid 1 mode tunnel \
|
||||
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
|
||||
ip netns exec at_ns0 \
|
||||
ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir out \
|
||||
tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
|
||||
mode tunnel
|
||||
# root -> at_ns0
|
||||
ip netns exec at_ns0 \
|
||||
ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
|
||||
spi $spi_out_to_in reqid 2 mode tunnel \
|
||||
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
|
||||
ip netns exec at_ns0 \
|
||||
ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir in \
|
||||
tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
|
||||
mode tunnel
|
||||
# address & route
|
||||
ip netns exec at_ns0 \
|
||||
ip addr add dev veth0 10.1.1.100/32
|
||||
ip netns exec at_ns0 \
|
||||
ip route add 10.1.1.200 dev veth0 via 172.16.1.200 \
|
||||
src 10.1.1.100
|
||||
|
||||
# root namespace
|
||||
# at_ns0 -> root
|
||||
ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
|
||||
spi $spi_in_to_out reqid 1 mode tunnel \
|
||||
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
|
||||
ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir in \
|
||||
tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
|
||||
mode tunnel
|
||||
# root -> at_ns0
|
||||
ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
|
||||
spi $spi_out_to_in reqid 2 mode tunnel \
|
||||
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
|
||||
ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir out \
|
||||
tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
|
||||
mode tunnel
|
||||
# address & route
|
||||
ip addr add dev veth1 10.1.1.200/32
|
||||
ip route add 10.1.1.100 dev veth1 via 172.16.1.100 src 10.1.1.200
|
||||
}
|
||||
|
||||
test_xfrm_tunnel()
|
||||
{
|
||||
if [[ -e /sys/kernel/tracing/trace ]]; then
|
||||
TRACE=/sys/kernel/tracing/trace
|
||||
else
|
||||
TRACE=/sys/kernel/debug/tracing/trace
|
||||
fi
|
||||
config_device
|
||||
> ${TRACE}
|
||||
setup_xfrm_tunnel
|
||||
mkdir -p ${BPF_PIN_TUNNEL_DIR}
|
||||
bpftool prog loadall ${BPF_FILE} ${BPF_PIN_TUNNEL_DIR}
|
||||
tc qdisc add dev veth1 clsact
|
||||
tc filter add dev veth1 proto ip ingress bpf da object-pinned \
|
||||
${BPF_PIN_TUNNEL_DIR}/xfrm_get_state
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
sleep 1
|
||||
grep "reqid 1" ${TRACE}
|
||||
check_err $?
|
||||
grep "spi 0x1" ${TRACE}
|
||||
check_err $?
|
||||
grep "remote ip 0xac100164" ${TRACE}
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: xfrm tunnel"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: xfrm tunnel"${NC}
|
||||
}
|
||||
|
||||
attach_bpf()
|
||||
{
|
||||
DEV=$1
|
||||
|
@ -630,10 +546,6 @@ cleanup()
|
|||
ip link del ip6geneve11 2> /dev/null
|
||||
ip link del erspan11 2> /dev/null
|
||||
ip link del ip6erspan11 2> /dev/null
|
||||
ip xfrm policy delete dir out src 10.1.1.200/32 dst 10.1.1.100/32 2> /dev/null
|
||||
ip xfrm policy delete dir in src 10.1.1.100/32 dst 10.1.1.200/32 2> /dev/null
|
||||
ip xfrm state delete src 172.16.1.100 dst 172.16.1.200 proto esp spi 0x1 2> /dev/null
|
||||
ip xfrm state delete src 172.16.1.200 dst 172.16.1.100 proto esp spi 0x2 2> /dev/null
|
||||
}
|
||||
|
||||
cleanup_exit()
|
||||
|
@ -716,10 +628,6 @@ bpf_tunnel_test()
|
|||
test_ip6ip6
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing IPSec tunnel..."
|
||||
test_xfrm_tunnel
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
return $errors
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue