Update bpf syscall decoding
Implement decoding of BPF_OBJ_PIN, BPF_OBJ_GET, BPF_PROG_ATTACH, and BPF_PROG_DETACH commands. * bpf.c: Include "xlat/bpf_attach_type.h". (bpf_obj_manage, bpf_prog_attach, bpf_prog_detach): New functions. (SYS_FUNC(bpf)): Use them. * configure.ac: Check for union bpf_attr.bpf_fd and union bpf_attr.attach_type. * xlat/bpf_attach_type.in: New file. * xlat/bpf_commands.in: Update list of BPF_* command constants. * xlat/bpf_map_types.in: Update list of BPF_MAP_TYPE_* constants. * xlat/bpf_prog_types.in: Update list of BPF_PROG_TYPE_* constants. * tests/bpf.c [HAVE_UNION_BPF_ATTR_BPF_FD] (obj_manage): New function. [HAVE_UNION_BPF_ATTR_ATTACH_TYPE] (prog_cgroup): Likewise. (main): Use them.
This commit is contained in:
parent
fe871501ff
commit
0a8dd6a68c
95
bpf.c
95
bpf.c
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
|
||||
* Copyright (c) 2017 Quentin Monnet <quentin.monnet@6wind.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,6 +36,7 @@
|
||||
#include "xlat/bpf_map_types.h"
|
||||
#include "xlat/bpf_prog_types.h"
|
||||
#include "xlat/bpf_map_update_elem_flags.h"
|
||||
#include "xlat/bpf_attach_type.h"
|
||||
|
||||
static int
|
||||
bpf_map_create(struct tcb *const tcp, const kernel_ulong_t addr,
|
||||
@ -177,6 +179,87 @@ bpf_prog_load(struct tcb *const tcp, const kernel_ulong_t addr,
|
||||
return RVAL_DECODED | RVAL_FD;
|
||||
}
|
||||
|
||||
static int
|
||||
bpf_obj_manage(struct tcb *const tcp, const kernel_ulong_t addr,
|
||||
unsigned int size)
|
||||
{
|
||||
struct {
|
||||
uint64_t ATTRIBUTE_ALIGNED(8) pathname;
|
||||
uint32_t bpf_fd;
|
||||
} attr = {};
|
||||
|
||||
if (!size) {
|
||||
printaddr(addr);
|
||||
return RVAL_DECODED | RVAL_FD;
|
||||
}
|
||||
if (size > sizeof(attr))
|
||||
size = sizeof(attr);
|
||||
if (umoven_or_printaddr(tcp, addr, size, &attr))
|
||||
return RVAL_DECODED | RVAL_FD;
|
||||
|
||||
tprintf("{pathname=");
|
||||
printpath(tcp, attr.pathname);
|
||||
tprints(", bpf_fd=");
|
||||
printfd(tcp, attr.bpf_fd);
|
||||
tprintf("}");
|
||||
|
||||
return RVAL_DECODED | RVAL_FD;
|
||||
}
|
||||
|
||||
static int
|
||||
bpf_prog_attach(struct tcb *const tcp, const kernel_ulong_t addr,
|
||||
unsigned int size)
|
||||
{
|
||||
struct {
|
||||
uint32_t target_fd, attach_bpf_fd, attach_type;
|
||||
} attr = {};
|
||||
|
||||
if (!size) {
|
||||
printaddr(addr);
|
||||
return RVAL_DECODED;
|
||||
}
|
||||
if (size > sizeof(attr))
|
||||
size = sizeof(attr);
|
||||
if (umoven_or_printaddr(tcp, addr, size, &attr))
|
||||
return RVAL_DECODED;
|
||||
|
||||
tprintf("{target_fd=");
|
||||
printfd(tcp, attr.target_fd);
|
||||
tprintf(", attach_bpf_fd=");
|
||||
printfd(tcp, attr.attach_bpf_fd);
|
||||
tprintf(", attach_type=");
|
||||
printxval(bpf_attach_type, attr.attach_type, "BPF_???");
|
||||
tprintf("}");
|
||||
|
||||
return RVAL_DECODED;
|
||||
}
|
||||
|
||||
static int
|
||||
bpf_prog_detach(struct tcb *const tcp, const kernel_ulong_t addr,
|
||||
unsigned int size)
|
||||
{
|
||||
struct {
|
||||
uint32_t target_fd, attach_bpf_fd, attach_type;
|
||||
} attr = {};
|
||||
|
||||
if (!size) {
|
||||
printaddr(addr);
|
||||
return RVAL_DECODED;
|
||||
}
|
||||
if (size > sizeof(attr))
|
||||
size = sizeof(attr);
|
||||
if (umoven_or_printaddr(tcp, addr, size, &attr))
|
||||
return RVAL_DECODED;
|
||||
|
||||
tprintf("{target_fd=");
|
||||
printfd(tcp, attr.target_fd);
|
||||
tprintf(", attach_type=");
|
||||
printxval(bpf_attach_type, attr.attach_type, "BPF_???");
|
||||
tprintf("}");
|
||||
|
||||
return RVAL_DECODED;
|
||||
}
|
||||
|
||||
SYS_FUNC(bpf)
|
||||
{
|
||||
const unsigned int cmd = tcp->u_arg[0];
|
||||
@ -208,6 +291,18 @@ SYS_FUNC(bpf)
|
||||
case BPF_PROG_LOAD:
|
||||
rc = bpf_prog_load(tcp, addr, size);
|
||||
break;
|
||||
case BPF_OBJ_PIN:
|
||||
rc = bpf_obj_manage(tcp, addr, size);
|
||||
break;
|
||||
case BPF_OBJ_GET:
|
||||
rc = bpf_obj_manage(tcp, addr, size);
|
||||
break;
|
||||
case BPF_PROG_ATTACH:
|
||||
rc = bpf_prog_attach(tcp, addr, size);
|
||||
break;
|
||||
case BPF_PROG_DETACH:
|
||||
rc = bpf_prog_detach(tcp, addr, size);
|
||||
break;
|
||||
default:
|
||||
printaddr(addr);
|
||||
break;
|
||||
|
22
configure.ac
22
configure.ac
@ -424,6 +424,28 @@ AC_CHECK_HEADERS([linux/bpf.h], [
|
||||
AC_DEFINE(HAVE_UNION_BPF_ATTR_LOG_BUF, [1],
|
||||
[Define to 1 if union bpf_attr.log_buf initialization works])
|
||||
fi
|
||||
AC_CACHE_CHECK([whether union bpf_attr.bpf_fd initialization works],
|
||||
[st_cv_have_union_bpf_attr_bpf_fd],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <linux/bpf.h>]],
|
||||
[[union bpf_attr a = { .bpf_fd = 0 };]])],
|
||||
[st_cv_have_union_bpf_attr_bpf_fd=yes],
|
||||
[st_cv_have_union_bpf_attr_bpf_fd=no])])
|
||||
if test $st_cv_have_union_bpf_attr_bpf_fd = yes; then
|
||||
AC_DEFINE(HAVE_UNION_BPF_ATTR_BPF_FD, [1],
|
||||
[Define to 1 if union bpf_attr.bpf_fd initialization works])
|
||||
fi
|
||||
AC_CACHE_CHECK([whether union bpf_attr.attach_type initialization works],
|
||||
[st_cv_have_union_bpf_attr_attach_type],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <linux/bpf.h>]],
|
||||
[[union bpf_attr a = { .attach_type = 0 };]])],
|
||||
[st_cv_have_union_bpf_attr_attach_type=yes],
|
||||
[st_cv_have_union_bpf_attr_attach_type=no])])
|
||||
if test $st_cv_have_union_bpf_attr_attach_type = yes; then
|
||||
AC_DEFINE(HAVE_UNION_BPF_ATTR_ATTACH_TYPE, [1],
|
||||
[Define to 1 if union bpf_attr.attach_type initialization works])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_CHECK_TYPES([struct statfs], [
|
||||
|
65
tests/bpf.c
65
tests/bpf.c
@ -76,6 +76,39 @@ prog_load(void)
|
||||
return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
/*
|
||||
* bpf() syscall and its first six commands were introduced in Linux kernel
|
||||
* 3.18. Some additional commands were added afterwards, so we need to take
|
||||
* precautions to make sure the tests compile.
|
||||
*
|
||||
* BPF_OBJ_PIN and BPF_OBJ_GET commands appear in kernel 4.4.
|
||||
*/
|
||||
# ifdef HAVE_UNION_BPF_ATTR_BPF_FD
|
||||
static int
|
||||
obj_manage(int cmd)
|
||||
{
|
||||
union bpf_attr attr = {
|
||||
.pathname = (unsigned long) "/sys/fs/bpf/foo/bar",
|
||||
.bpf_fd = -1
|
||||
};
|
||||
return syscall(__NR_bpf, cmd, &attr, sizeof(attr));
|
||||
}
|
||||
# endif
|
||||
|
||||
/* BPF_PROG_ATTACH and BPF_PROG_DETACH commands appear in kernel 4.10. */
|
||||
# ifdef HAVE_UNION_BPF_ATTR_ATTACH_TYPE
|
||||
static int
|
||||
prog_cgroup(int cmd)
|
||||
{
|
||||
union bpf_attr attr = {
|
||||
.target_fd = -1,
|
||||
.attach_bpf_fd = -1,
|
||||
.attach_type = 0
|
||||
};
|
||||
return syscall(__NR_bpf, cmd, &attr, sizeof(attr));
|
||||
}
|
||||
# endif
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
@ -119,6 +152,38 @@ main(void)
|
||||
"kern_version=0\\}, %u\\) += -1 .*\n",
|
||||
insns, log_buf, (unsigned) sizeof(union bpf_attr));
|
||||
|
||||
# ifdef HAVE_UNION_BPF_ATTR_BPF_FD
|
||||
if (!obj_manage(BPF_OBJ_PIN))
|
||||
perror_msg_and_skip("BPF_OBJ_PIN");
|
||||
printf("bpf\\(BPF_OBJ_PIN, "
|
||||
"\\{pathname=\"/sys/fs/bpf/foo/bar\", "
|
||||
"bpf_fd=-1\\}, %u\\) += -1 .*\n",
|
||||
(unsigned) sizeof(union bpf_attr));
|
||||
|
||||
if (!obj_manage(BPF_OBJ_GET))
|
||||
perror_msg_and_skip("BPF_OBJ_GET");
|
||||
printf("bpf\\(BPF_OBJ_GET, "
|
||||
"\\{pathname=\"/sys/fs/bpf/foo/bar\", "
|
||||
"bpf_fd=-1\\}, %u\\) += -1 .*\n",
|
||||
(unsigned) sizeof(union bpf_attr));
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_UNION_BPF_ATTR_ATTACH_TYPE
|
||||
if (!prog_cgroup(BPF_PROG_ATTACH))
|
||||
perror_msg_and_skip("BPF_PROG_ATTACH");
|
||||
printf("bpf\\(BPF_PROG_ATTACH, "
|
||||
"{target_fd=-1, attach_bpf_fd=-1, "
|
||||
"attach_type=BPF_CGROUP_INET_INGRESS\\}, %u\\) += -1 .*\n",
|
||||
(unsigned) sizeof(union bpf_attr));
|
||||
|
||||
if (!prog_cgroup(BPF_PROG_DETACH))
|
||||
perror_msg_and_skip("BPF_PROG_DETACH");
|
||||
printf("bpf\\(BPF_PROG_DETACH, "
|
||||
"\\{target_fd=-1, attach_type=BPF_CGROUP_INET_INGRESS\\}, "
|
||||
"%u\\) += -1 .*\n",
|
||||
(unsigned) sizeof(union bpf_attr));
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
3
xlat/bpf_attach_type.in
Normal file
3
xlat/bpf_attach_type.in
Normal file
@ -0,0 +1,3 @@
|
||||
BPF_CGROUP_INET_INGRESS 0
|
||||
BPF_CGROUP_INET_EGRESS 1
|
||||
BPF_CGROUP_INET_SOCK_CREATE 2
|
@ -4,3 +4,7 @@ BPF_MAP_UPDATE_ELEM 2
|
||||
BPF_MAP_DELETE_ELEM 3
|
||||
BPF_MAP_GET_NEXT_KEY 4
|
||||
BPF_PROG_LOAD 5
|
||||
BPF_OBJ_PIN 6
|
||||
BPF_OBJ_GET 7
|
||||
BPF_PROG_ATTACH 8
|
||||
BPF_PROG_DETACH 9
|
||||
|
@ -7,3 +7,6 @@ BPF_MAP_TYPE_PERCPU_HASH 5
|
||||
BPF_MAP_TYPE_PERCPU_ARRAY 6
|
||||
BPF_MAP_TYPE_STACK_TRACE 7
|
||||
BPF_MAP_TYPE_CGROUP_ARRAY 8
|
||||
BPF_MAP_TYPE_LRU_HASH 9
|
||||
BPF_MAP_TYPE_LRU_PERCPU_HASH 10
|
||||
BPF_MAP_TYPE_LPM_TRIE 11
|
||||
|
@ -6,3 +6,8 @@ BPF_PROG_TYPE_SCHED_ACT 4
|
||||
BPF_PROG_TYPE_TRACEPOINT 5
|
||||
BPF_PROG_TYPE_XDP 6
|
||||
BPF_PROG_TYPE_PERF_EVENT 7
|
||||
BPF_PROG_TYPE_CGROUP_SKB 8
|
||||
BPF_PROG_TYPE_CGROUP_SOCK 9
|
||||
BPF_PROG_TYPE_LWT_IN 10
|
||||
BPF_PROG_TYPE_LWT_OUT 11
|
||||
BPF_PROG_TYPE_LWT_XMIT 12
|
||||
|
Loading…
x
Reference in New Issue
Block a user