Skip to content

Commit e7adc82

Browse files
danobiAlexei Starovoitov
authored andcommitted
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 <[email protected]> Signed-off-by: Antony Antony <[email protected]> Signed-off-by: Daniel Xu <[email protected]> Link: https://lore.kernel.org/r/a350db9e08520c64544562d88ec005a039124d9b.1702593901.git.dxu@dxuuu.xyz Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 02b4e12 commit e7adc82

File tree

3 files changed

+151
-95
lines changed

3 files changed

+151
-95
lines changed

tools/testing/selftests/bpf/prog_tests/test_tunnel.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151

5252
#include <arpa/inet.h>
53+
#include <linux/if_link.h>
5354
#include <linux/if_tun.h>
5455
#include <linux/limits.h>
5556
#include <linux/sysctl.h>
@@ -92,6 +93,11 @@
9293
#define IPIP_TUNL_DEV0 "ipip00"
9394
#define IPIP_TUNL_DEV1 "ipip11"
9495

96+
#define XFRM_AUTH "0x1111111111111111111111111111111111111111"
97+
#define XFRM_ENC "0x22222222222222222222222222222222"
98+
#define XFRM_SPI_IN_TO_OUT 0x1
99+
#define XFRM_SPI_OUT_TO_IN 0x2
100+
95101
#define PING_ARGS "-i 0.01 -c 3 -w 10 -q"
96102

97103
static int config_device(void)
@@ -264,6 +270,92 @@ static void delete_ipip_tunnel(void)
264270
SYS_NOFAIL("ip fou del port 5555 2> /dev/null");
265271
}
266272

273+
static int add_xfrm_tunnel(void)
274+
{
275+
/* at_ns0 namespace
276+
* at_ns0 -> root
277+
*/
278+
SYS(fail,
279+
"ip netns exec at_ns0 "
280+
"ip xfrm state add src %s dst %s proto esp "
281+
"spi %d reqid 1 mode tunnel "
282+
"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
283+
IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT, XFRM_AUTH, XFRM_ENC);
284+
SYS(fail,
285+
"ip netns exec at_ns0 "
286+
"ip xfrm policy add src %s/32 dst %s/32 dir out "
287+
"tmpl src %s dst %s proto esp reqid 1 "
288+
"mode tunnel",
289+
IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
290+
291+
/* root -> at_ns0 */
292+
SYS(fail,
293+
"ip netns exec at_ns0 "
294+
"ip xfrm state add src %s dst %s proto esp "
295+
"spi %d reqid 2 mode tunnel "
296+
"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
297+
IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN, XFRM_AUTH, XFRM_ENC);
298+
SYS(fail,
299+
"ip netns exec at_ns0 "
300+
"ip xfrm policy add src %s/32 dst %s/32 dir in "
301+
"tmpl src %s dst %s proto esp reqid 2 "
302+
"mode tunnel",
303+
IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0, IP4_ADDR1_VETH1, IP4_ADDR_VETH0);
304+
305+
/* address & route */
306+
SYS(fail, "ip netns exec at_ns0 ip addr add dev veth0 %s/32",
307+
IP4_ADDR_TUNL_DEV0);
308+
SYS(fail, "ip netns exec at_ns0 ip route add %s dev veth0 via %s src %s",
309+
IP4_ADDR_TUNL_DEV1, IP4_ADDR1_VETH1, IP4_ADDR_TUNL_DEV0);
310+
311+
/* root namespace
312+
* at_ns0 -> root
313+
*/
314+
SYS(fail,
315+
"ip xfrm state add src %s dst %s proto esp "
316+
"spi %d reqid 1 mode tunnel "
317+
"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
318+
IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT, XFRM_AUTH, XFRM_ENC);
319+
SYS(fail,
320+
"ip xfrm policy add src %s/32 dst %s/32 dir in "
321+
"tmpl src %s dst %s proto esp reqid 1 "
322+
"mode tunnel",
323+
IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
324+
325+
/* root -> at_ns0 */
326+
SYS(fail,
327+
"ip xfrm state add src %s dst %s proto esp "
328+
"spi %d reqid 2 mode tunnel "
329+
"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
330+
IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN, XFRM_AUTH, XFRM_ENC);
331+
SYS(fail,
332+
"ip xfrm policy add src %s/32 dst %s/32 dir out "
333+
"tmpl src %s dst %s proto esp reqid 2 "
334+
"mode tunnel",
335+
IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0, IP4_ADDR1_VETH1, IP4_ADDR_VETH0);
336+
337+
/* address & route */
338+
SYS(fail, "ip addr add dev veth1 %s/32", IP4_ADDR_TUNL_DEV1);
339+
SYS(fail, "ip route add %s dev veth1 via %s src %s",
340+
IP4_ADDR_TUNL_DEV0, IP4_ADDR_VETH0, IP4_ADDR_TUNL_DEV1);
341+
342+
return 0;
343+
fail:
344+
return -1;
345+
}
346+
347+
static void delete_xfrm_tunnel(void)
348+
{
349+
SYS_NOFAIL("ip xfrm policy delete dir out src %s/32 dst %s/32 2> /dev/null",
350+
IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0);
351+
SYS_NOFAIL("ip xfrm policy delete dir in src %s/32 dst %s/32 2> /dev/null",
352+
IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1);
353+
SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d 2> /dev/null",
354+
IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT);
355+
SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d 2> /dev/null",
356+
IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN);
357+
}
358+
267359
static int test_ping(int family, const char *addr)
268360
{
269361
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)
532624
test_tunnel_kern__destroy(skel);
533625
}
534626

627+
static void test_xfrm_tunnel(void)
628+
{
629+
DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
630+
.attach_point = BPF_TC_INGRESS);
631+
struct test_tunnel_kern *skel = NULL;
632+
struct nstoken *nstoken;
633+
int tc_prog_fd;
634+
int ifindex;
635+
int err;
636+
637+
err = add_xfrm_tunnel();
638+
if (!ASSERT_OK(err, "add_xfrm_tunnel"))
639+
return;
640+
641+
skel = test_tunnel_kern__open_and_load();
642+
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
643+
goto done;
644+
645+
ifindex = if_nametoindex("veth1");
646+
if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))
647+
goto done;
648+
649+
/* attach tc prog to tunnel dev */
650+
tc_hook.ifindex = ifindex;
651+
tc_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state);
652+
if (!ASSERT_GE(tc_prog_fd, 0, "bpf_program__fd"))
653+
goto done;
654+
if (attach_tc_prog(&tc_hook, tc_prog_fd, -1))
655+
goto done;
656+
657+
/* ping from at_ns0 namespace test */
658+
nstoken = open_netns("at_ns0");
659+
err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV1);
660+
close_netns(nstoken);
661+
if (!ASSERT_OK(err, "test_ping"))
662+
goto done;
663+
664+
if (!ASSERT_EQ(skel->bss->xfrm_reqid, 1, "req_id"))
665+
goto done;
666+
if (!ASSERT_EQ(skel->bss->xfrm_spi, XFRM_SPI_IN_TO_OUT, "spi"))
667+
goto done;
668+
if (!ASSERT_EQ(skel->bss->xfrm_remote_ip, 0xac100164, "remote_ip"))
669+
goto done;
670+
671+
done:
672+
delete_xfrm_tunnel();
673+
if (skel)
674+
test_tunnel_kern__destroy(skel);
675+
}
676+
535677
#define RUN_TEST(name, ...) \
536678
({ \
537679
if (test__start_subtest(#name)) { \
@@ -548,6 +690,7 @@ static void *test_tunnel_run_tests(void *arg)
548690
RUN_TEST(ipip_tunnel, NONE);
549691
RUN_TEST(ipip_tunnel, FOU);
550692
RUN_TEST(ipip_tunnel, GUE);
693+
RUN_TEST(xfrm_tunnel);
551694

552695
return NULL;
553696
}

tools/testing/selftests/bpf/progs/test_tunnel_kern.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,10 @@ int ip6ip6_get_tunnel(struct __sk_buff *skb)
929929
return TC_ACT_OK;
930930
}
931931

932+
volatile int xfrm_reqid = 0;
933+
volatile int xfrm_spi = 0;
934+
volatile int xfrm_remote_ip = 0;
935+
932936
SEC("tc")
933937
int xfrm_get_state(struct __sk_buff *skb)
934938
{
@@ -939,9 +943,10 @@ int xfrm_get_state(struct __sk_buff *skb)
939943
if (ret < 0)
940944
return TC_ACT_OK;
941945

942-
bpf_printk("reqid %d spi 0x%x remote ip 0x%x\n",
943-
x.reqid, bpf_ntohl(x.spi),
944-
bpf_ntohl(x.remote_ipv4));
946+
xfrm_reqid = x.reqid;
947+
xfrm_spi = bpf_ntohl(x.spi);
948+
xfrm_remote_ip = bpf_ntohl(x.remote_ipv4);
949+
945950
return TC_ACT_OK;
946951
}
947952

tools/testing/selftests/bpf/test_tunnel.sh

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -517,90 +517,6 @@ test_ip6ip6()
517517
echo -e ${GREEN}"PASS: ip6$TYPE"${NC}
518518
}
519519

520-
setup_xfrm_tunnel()
521-
{
522-
auth=0x$(printf '1%.0s' {1..40})
523-
enc=0x$(printf '2%.0s' {1..32})
524-
spi_in_to_out=0x1
525-
spi_out_to_in=0x2
526-
# at_ns0 namespace
527-
# at_ns0 -> root
528-
ip netns exec at_ns0 \
529-
ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
530-
spi $spi_in_to_out reqid 1 mode tunnel \
531-
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
532-
ip netns exec at_ns0 \
533-
ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir out \
534-
tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
535-
mode tunnel
536-
# root -> at_ns0
537-
ip netns exec at_ns0 \
538-
ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
539-
spi $spi_out_to_in reqid 2 mode tunnel \
540-
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
541-
ip netns exec at_ns0 \
542-
ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir in \
543-
tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
544-
mode tunnel
545-
# address & route
546-
ip netns exec at_ns0 \
547-
ip addr add dev veth0 10.1.1.100/32
548-
ip netns exec at_ns0 \
549-
ip route add 10.1.1.200 dev veth0 via 172.16.1.200 \
550-
src 10.1.1.100
551-
552-
# root namespace
553-
# at_ns0 -> root
554-
ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
555-
spi $spi_in_to_out reqid 1 mode tunnel \
556-
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
557-
ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir in \
558-
tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
559-
mode tunnel
560-
# root -> at_ns0
561-
ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
562-
spi $spi_out_to_in reqid 2 mode tunnel \
563-
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
564-
ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir out \
565-
tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
566-
mode tunnel
567-
# address & route
568-
ip addr add dev veth1 10.1.1.200/32
569-
ip route add 10.1.1.100 dev veth1 via 172.16.1.100 src 10.1.1.200
570-
}
571-
572-
test_xfrm_tunnel()
573-
{
574-
if [[ -e /sys/kernel/tracing/trace ]]; then
575-
TRACE=/sys/kernel/tracing/trace
576-
else
577-
TRACE=/sys/kernel/debug/tracing/trace
578-
fi
579-
config_device
580-
> ${TRACE}
581-
setup_xfrm_tunnel
582-
mkdir -p ${BPF_PIN_TUNNEL_DIR}
583-
bpftool prog loadall ${BPF_FILE} ${BPF_PIN_TUNNEL_DIR}
584-
tc qdisc add dev veth1 clsact
585-
tc filter add dev veth1 proto ip ingress bpf da object-pinned \
586-
${BPF_PIN_TUNNEL_DIR}/xfrm_get_state
587-
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
588-
sleep 1
589-
grep "reqid 1" ${TRACE}
590-
check_err $?
591-
grep "spi 0x1" ${TRACE}
592-
check_err $?
593-
grep "remote ip 0xac100164" ${TRACE}
594-
check_err $?
595-
cleanup
596-
597-
if [ $ret -ne 0 ]; then
598-
echo -e ${RED}"FAIL: xfrm tunnel"${NC}
599-
return 1
600-
fi
601-
echo -e ${GREEN}"PASS: xfrm tunnel"${NC}
602-
}
603-
604520
attach_bpf()
605521
{
606522
DEV=$1
@@ -630,10 +546,6 @@ cleanup()
630546
ip link del ip6geneve11 2> /dev/null
631547
ip link del erspan11 2> /dev/null
632548
ip link del ip6erspan11 2> /dev/null
633-
ip xfrm policy delete dir out src 10.1.1.200/32 dst 10.1.1.100/32 2> /dev/null
634-
ip xfrm policy delete dir in src 10.1.1.100/32 dst 10.1.1.200/32 2> /dev/null
635-
ip xfrm state delete src 172.16.1.100 dst 172.16.1.200 proto esp spi 0x1 2> /dev/null
636-
ip xfrm state delete src 172.16.1.200 dst 172.16.1.100 proto esp spi 0x2 2> /dev/null
637549
}
638550

639551
cleanup_exit()
@@ -716,10 +628,6 @@ bpf_tunnel_test()
716628
test_ip6ip6
717629
errors=$(( $errors + $? ))
718630

719-
echo "Testing IPSec tunnel..."
720-
test_xfrm_tunnel
721-
errors=$(( $errors + $? ))
722-
723631
return $errors
724632
}
725633

0 commit comments

Comments
 (0)