/*
* 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
#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"
+#include "xlat/bpf_attach_flags.h"
static int
-bpf_map_create(struct tcb *const tcp, const kernel_ureg_t addr,
+bpf_map_create(struct tcb *const tcp, const kernel_ulong_t addr,
unsigned int size)
{
struct {
}
static void
-bpf_map_update_elem(struct tcb *const tcp, const kernel_ureg_t addr,
+bpf_map_update_elem(struct tcb *const tcp, const kernel_ulong_t addr,
unsigned int size)
{
struct {
}
static void
-bpf_map_delete_elem(struct tcb *const tcp, const kernel_ureg_t addr,
+bpf_map_delete_elem(struct tcb *const tcp, const kernel_ulong_t addr,
unsigned int size)
{
struct {
}
static int
-bpf_map_io(struct tcb *const tcp, const kernel_ureg_t addr, unsigned int size,
+bpf_map_io(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int size,
const char *const text)
{
struct bpf_io_elem_struct {
}
static int
-bpf_prog_load(struct tcb *const tcp, const kernel_ureg_t addr,
+bpf_prog_load(struct tcb *const tcp, const kernel_ulong_t addr,
unsigned int size)
{
struct {
printxval(bpf_prog_types, attr.prog_type, "BPF_PROG_TYPE_???");
tprintf(", insn_cnt=%u, insns=%#" PRIx64 ", license=",
attr.insn_cnt, attr.insns);
- printstr(tcp, attr.license, -1);
+ printstr(tcp, attr.license);
tprintf(", log_level=%u, log_size=%u, log_buf=%#" PRIx64 ", kern_version=%u}",
attr.log_level, attr.log_size, attr.log_buf, attr.kern_version);
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;
+
+ tprints("{pathname=");
+ printpath(tcp, attr.pathname);
+ tprints(", bpf_fd=");
+ printfd(tcp, attr.bpf_fd);
+ tprints("}");
+
+ return RVAL_DECODED | RVAL_FD;
+}
+
+static int
+bpf_prog_attach_detach(struct tcb *const tcp, const kernel_ulong_t addr,
+ unsigned int size, bool print_attach)
+{
+ struct {
+ uint32_t target_fd, attach_bpf_fd, attach_type, attach_flags;
+ } 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;
+
+ tprints("{target_fd=");
+ printfd(tcp, attr.target_fd);
+ if (print_attach) {
+ tprints(", attach_bpf_fd=");
+ printfd(tcp, attr.attach_bpf_fd);
+ }
+ tprints(", attach_type=");
+ printxval(bpf_attach_type, attr.attach_type, "BPF_???");
+ if (print_attach) {
+ tprints(", attach_flags=");
+ printflags(bpf_attach_flags, attr.attach_flags, "BPF_F_???");
+ }
+ tprints("}");
+
+ return RVAL_DECODED;
+}
+
+static int
+bpf_prog_attach(struct tcb *const tcp, const kernel_ulong_t addr,
+ unsigned int size)
+{
+ return bpf_prog_attach_detach(tcp, addr, size, true);
+}
+
+static int
+bpf_prog_detach(struct tcb *const tcp, const kernel_ulong_t addr,
+ unsigned int size)
+{
+ return bpf_prog_attach_detach(tcp, addr, size, false);
+}
+
SYS_FUNC(bpf)
{
const unsigned int cmd = tcp->u_arg[0];
- const kernel_ureg_t addr = tcp->u_arg[1];
+ const kernel_ulong_t addr = tcp->u_arg[1];
const unsigned int size = tcp->u_arg[2];
int rc = RVAL_DECODED;
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;