Skip to content

Commit

Permalink
Merge pull request iovisor#4093 from chantra/fix_bpf_load_program_attr
Browse files Browse the repository at this point in the history
[bcc] stop using deprecated `bpf_load_program_attr`
  • Loading branch information
davemarchevsky committed Jul 6, 2022
2 parents 9c043a2 + 185143b commit e96571e
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 102 deletions.
36 changes: 16 additions & 20 deletions src/cc/bpf_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -982,26 +982,22 @@ int BPFModule::bcc_func_load(int prog_type, const char *name,
const char *license, unsigned kern_version,
int log_level, char *log_buf, unsigned log_buf_size,
const char *dev_name, unsigned flags, int expected_attach_type) {
struct bpf_load_program_attr attr = {};
struct bpf_prog_load_opts opts = {};
unsigned func_info_cnt, line_info_cnt, finfo_rec_size, linfo_rec_size;
void *func_info = NULL, *line_info = NULL;
int ret;

attr.prog_type = (enum bpf_prog_type)prog_type;
if (expected_attach_type != -1) {
attr.expected_attach_type = (enum bpf_attach_type)expected_attach_type;
opts.expected_attach_type = (enum bpf_attach_type)expected_attach_type;
}
attr.name = name;
attr.insns = insns;
attr.license = license;
if (attr.prog_type != BPF_PROG_TYPE_TRACING &&
attr.prog_type != BPF_PROG_TYPE_EXT) {
attr.kern_version = kern_version;
if (prog_type != BPF_PROG_TYPE_TRACING &&
prog_type != BPF_PROG_TYPE_EXT) {
opts.kern_version = kern_version;
}
attr.prog_flags = flags;
attr.log_level = log_level;
opts.prog_flags = flags;
opts.log_level = log_level;
if (dev_name)
attr.prog_ifindex = if_nametoindex(dev_name);
opts.prog_ifindex = if_nametoindex(dev_name);

if (btf_) {
int btf_fd = btf_->get_fd();
Expand All @@ -1012,17 +1008,17 @@ int BPFModule::bcc_func_load(int prog_type, const char *name,
&finfo_rec_size, &line_info,
&line_info_cnt, &linfo_rec_size);
if (!ret) {
attr.prog_btf_fd = btf_fd;
attr.func_info = func_info;
attr.func_info_cnt = func_info_cnt;
attr.func_info_rec_size = finfo_rec_size;
attr.line_info = line_info;
attr.line_info_cnt = line_info_cnt;
attr.line_info_rec_size = linfo_rec_size;
opts.prog_btf_fd = btf_fd;
opts.func_info = func_info;
opts.func_info_cnt = func_info_cnt;
opts.func_info_rec_size = finfo_rec_size;
opts.line_info = line_info;
opts.line_info_cnt = line_info_cnt;
opts.line_info_rec_size = linfo_rec_size;
}
}

ret = bcc_prog_load_xattr(&attr, prog_len, log_buf, log_buf_size, allow_rlimit_);
ret = bcc_prog_load_xattr((enum bpf_prog_type)prog_type, name, license, insns, &opts, prog_len, log_buf, log_buf_size, allow_rlimit_);
if (btf_) {
free(func_info);
free(line_info);
Expand Down
160 changes: 81 additions & 79 deletions src/cc/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,148 +632,153 @@ int bpf_prog_get_tag(int fd, unsigned long long *ptag)
return -2;
}

static int libbpf_bpf_prog_load(const struct bpf_load_program_attr *load_attr,
static int libbpf_bpf_prog_load(enum bpf_prog_type prog_type,
const char *prog_name, const char *license,
const struct bpf_insn *insns, size_t insn_cnt,
struct bpf_prog_load_opts *opts,
char *log_buf, size_t log_buf_sz)
{

LIBBPF_OPTS(bpf_prog_load_opts, p);

if (!load_attr || !log_buf != !log_buf_sz) {
if (!opts || !log_buf != !log_buf_sz) {
errno = EINVAL;
return -EINVAL;
}

p.expected_attach_type = load_attr->expected_attach_type;
switch (load_attr->prog_type) {
p.expected_attach_type = opts->expected_attach_type;
switch (prog_type) {
case BPF_PROG_TYPE_STRUCT_OPS:
case BPF_PROG_TYPE_LSM:
p.attach_btf_id = load_attr->attach_btf_id;
p.attach_btf_id = opts->attach_btf_id;
break;
case BPF_PROG_TYPE_TRACING:
case BPF_PROG_TYPE_EXT:
p.attach_btf_id = load_attr->attach_btf_id;
p.attach_prog_fd = load_attr->attach_prog_fd;
p.attach_btf_id = opts->attach_btf_id;
p.attach_prog_fd = opts->attach_prog_fd;
break;
default:
p.prog_ifindex = load_attr->prog_ifindex;
p.kern_version = load_attr->kern_version;
p.prog_ifindex = opts->prog_ifindex;
p.kern_version = opts->kern_version;
}
p.log_level = load_attr->log_level;
p.log_level = opts->log_level;
p.log_buf = log_buf;
p.log_size = log_buf_sz;
p.prog_btf_fd = load_attr->prog_btf_fd;
p.func_info_rec_size = load_attr->func_info_rec_size;
p.func_info_cnt = load_attr->func_info_cnt;
p.func_info = load_attr->func_info;
p.line_info_rec_size = load_attr->line_info_rec_size;
p.line_info_cnt = load_attr->line_info_cnt;
p.line_info = load_attr->line_info;
p.prog_flags = load_attr->prog_flags;

return bpf_prog_load(load_attr->prog_type, load_attr->name, load_attr->license,
load_attr->insns, load_attr->insns_cnt, &p);
p.prog_btf_fd = opts->prog_btf_fd;
p.func_info_rec_size = opts->func_info_rec_size;
p.func_info_cnt = opts->func_info_cnt;
p.func_info = opts->func_info;
p.line_info_rec_size = opts->line_info_rec_size;
p.line_info_cnt = opts->line_info_cnt;
p.line_info = opts->line_info;
p.prog_flags = opts->prog_flags;

return bpf_prog_load(prog_type, prog_name, license,
insns, insn_cnt, &p);
}

int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
int bcc_prog_load_xattr(enum bpf_prog_type prog_type, const char *prog_name,
const char *license, const struct bpf_insn *insns,
struct bpf_prog_load_opts *opts, int prog_len,
char *log_buf, unsigned log_buf_size, bool allow_rlimit)
{
unsigned name_len = attr->name ? strlen(attr->name) : 0;
char *tmp_log_buf = NULL, *attr_log_buf = NULL;
unsigned tmp_log_buf_size = 0, attr_log_buf_size = 0;
unsigned name_len = prog_name ? strlen(prog_name) : 0;
char *tmp_log_buf = NULL, *opts_log_buf = NULL;
unsigned tmp_log_buf_size = 0, opts_log_buf_size = 0;
int ret = 0, name_offset = 0, expected_attach_type = 0;
char prog_name[BPF_OBJ_NAME_LEN] = {};
char new_prog_name[BPF_OBJ_NAME_LEN] = {};

unsigned insns_cnt = prog_len / sizeof(struct bpf_insn);
attr->insns_cnt = insns_cnt;

if (attr->log_level > 0) {
if (opts->log_level > 0) {
if (log_buf_size > 0) {
// Use user-provided log buffer if available.
log_buf[0] = 0;
attr_log_buf = log_buf;
attr_log_buf_size = log_buf_size;
opts_log_buf = log_buf;
opts_log_buf_size = log_buf_size;
} else {
// Create and use temporary log buffer if user didn't provide one.
tmp_log_buf_size = LOG_BUF_SIZE;
tmp_log_buf = malloc(tmp_log_buf_size);
if (!tmp_log_buf) {
fprintf(stderr, "bpf: Failed to allocate temporary log buffer: %s\n\n",
strerror(errno));
attr->log_level = 0;
opts->log_level = 0;
} else {
tmp_log_buf[0] = 0;
attr_log_buf = tmp_log_buf;
attr_log_buf_size = tmp_log_buf_size;
opts_log_buf = tmp_log_buf;
opts_log_buf_size = tmp_log_buf_size;
}
}
}


if (name_len) {
if (strncmp(attr->name, "kprobe__", 8) == 0)
if (strncmp(prog_name, "kprobe__", 8) == 0)
name_offset = 8;
else if (strncmp(attr->name, "kretprobe__", 11) == 0)
else if (strncmp(prog_name, "kretprobe__", 11) == 0)
name_offset = 11;
else if (strncmp(attr->name, "tracepoint__", 12) == 0)
else if (strncmp(prog_name, "tracepoint__", 12) == 0)
name_offset = 12;
else if (strncmp(attr->name, "raw_tracepoint__", 16) == 0)
else if (strncmp(prog_name, "raw_tracepoint__", 16) == 0)
name_offset = 16;
else if (strncmp(attr->name, "kfunc__", 7) == 0) {
else if (strncmp(prog_name, "kfunc__", 7) == 0) {
name_offset = 7;
expected_attach_type = BPF_TRACE_FENTRY;
} else if (strncmp(attr->name, "kmod_ret__", 10) == 0) {
} else if (strncmp(prog_name, "kmod_ret__", 10) == 0) {
name_offset = 10;
expected_attach_type = BPF_MODIFY_RETURN;
} else if (strncmp(attr->name, "kretfunc__", 10) == 0) {
} else if (strncmp(prog_name, "kretfunc__", 10) == 0) {
name_offset = 10;
expected_attach_type = BPF_TRACE_FEXIT;
} else if (strncmp(attr->name, "lsm__", 5) == 0) {
} else if (strncmp(prog_name, "lsm__", 5) == 0) {
name_offset = 5;
expected_attach_type = BPF_LSM_MAC;
} else if (strncmp(attr->name, "bpf_iter__", 10) == 0) {
} else if (strncmp(prog_name, "bpf_iter__", 10) == 0) {
name_offset = 10;
expected_attach_type = BPF_TRACE_ITER;
}

if (attr->prog_type == BPF_PROG_TYPE_TRACING ||
attr->prog_type == BPF_PROG_TYPE_LSM) {
ret = libbpf_find_vmlinux_btf_id(attr->name + name_offset,
if (prog_type == BPF_PROG_TYPE_TRACING ||
prog_type == BPF_PROG_TYPE_LSM) {
ret = libbpf_find_vmlinux_btf_id(prog_name + name_offset,
expected_attach_type);
if (ret == -EINVAL) {
fprintf(stderr, "bpf: vmlinux BTF is not found\n");
return ret;
} else if (ret < 0) {
fprintf(stderr, "bpf: %s is not found in vmlinux BTF\n",
attr->name + name_offset);
prog_name + name_offset);
return ret;
}

attr->attach_btf_id = ret;
attr->expected_attach_type = expected_attach_type;
opts->attach_btf_id = ret;
opts->expected_attach_type = expected_attach_type;
}

memcpy(prog_name, attr->name + name_offset,
memcpy(new_prog_name, prog_name + name_offset,
min(name_len - name_offset, BPF_OBJ_NAME_LEN - 1));
attr->name = prog_name;
}

ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
ret = libbpf_bpf_prog_load(prog_type, new_prog_name, license, insns, insns_cnt, opts, opts_log_buf, opts_log_buf_size);

// func_info/line_info may not be supported in old kernels.
if (ret < 0 && attr->func_info && errno == EINVAL) {
attr->prog_btf_fd = 0;
attr->func_info = NULL;
attr->func_info_cnt = 0;
attr->func_info_rec_size = 0;
attr->line_info = NULL;
attr->line_info_cnt = 0;
attr->line_info_rec_size = 0;
ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
if (ret < 0 && opts->func_info && errno == EINVAL) {
opts->prog_btf_fd = 0;
opts->func_info = NULL;
opts->func_info_cnt = 0;
opts->func_info_rec_size = 0;
opts->line_info = NULL;
opts->line_info_cnt = 0;
opts->line_info_rec_size = 0;
ret = libbpf_bpf_prog_load(prog_type, new_prog_name, license, insns, insns_cnt, opts, opts_log_buf, opts_log_buf_size);
}

// BPF object name is not supported on older Kernels.
// If we failed due to this, clear the name and try again.
if (ret < 0 && name_len && (errno == E2BIG || errno == EINVAL)) {
prog_name[0] = '\0';
ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
new_prog_name[0] = '\0';
ret = libbpf_bpf_prog_load(prog_type, new_prog_name, license, insns, insns_cnt, opts, opts_log_buf, opts_log_buf_size);
}

if (ret < 0 && errno == EPERM) {
Expand All @@ -792,14 +797,14 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
rl.rlim_max = RLIM_INFINITY;
rl.rlim_cur = rl.rlim_max;
if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0)
ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
ret = libbpf_bpf_prog_load(prog_type, new_prog_name, license, insns, insns_cnt, opts, opts_log_buf, opts_log_buf_size);
}
}

if (ret < 0 && errno == E2BIG) {
fprintf(stderr,
"bpf: %s. Program %s too large (%u insns), at most %d insns\n\n",
strerror(errno), attr->name, insns_cnt, BPF_MAXINSNS);
strerror(errno), new_prog_name, insns_cnt, BPF_MAXINSNS);
return -1;
}

Expand All @@ -808,9 +813,9 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
// User has provided a log buffer.
if (log_buf_size) {
// If logging is not already enabled, enable it and do the syscall again.
if (attr->log_level == 0) {
attr->log_level = 1;
ret = libbpf_bpf_prog_load(attr, log_buf, log_buf_size);
if (opts->log_level == 0) {
opts->log_level = 1;
ret = libbpf_bpf_prog_load(prog_type, new_prog_name, license, insns, insns_cnt, opts, log_buf, log_buf_size);
}
// Print the log message and return.
bpf_print_hints(ret, log_buf);
Expand All @@ -824,8 +829,8 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
if (tmp_log_buf)
free(tmp_log_buf);
tmp_log_buf_size = LOG_BUF_SIZE;
if (attr->log_level == 0)
attr->log_level = 1;
if (opts->log_level == 0)
opts->log_level = 1;
for (;;) {
tmp_log_buf = malloc(tmp_log_buf_size);
if (!tmp_log_buf) {
Expand All @@ -834,7 +839,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
goto return_result;
}
tmp_log_buf[0] = 0;
ret = libbpf_bpf_prog_load(attr, tmp_log_buf, tmp_log_buf_size);
ret = libbpf_bpf_prog_load(prog_type, new_prog_name, license, insns, insns_cnt, opts, tmp_log_buf, tmp_log_buf_size);
if (ret < 0 && errno == ENOSPC) {
// Temporary buffer size is not enough. Double it and try again.
free(tmp_log_buf);
Expand All @@ -848,7 +853,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,

// Check if we should print the log message if log_level is not 0,
// either specified by user or set due to error.
if (attr->log_level > 0) {
if (opts->log_level > 0) {
// Don't print if user enabled logging and provided log buffer,
// but there is no error.
if (log_buf && ret < 0)
Expand All @@ -868,16 +873,13 @@ int bcc_prog_load(enum bpf_prog_type prog_type, const char *name,
const char *license, unsigned kern_version,
int log_level, char *log_buf, unsigned log_buf_size)
{
struct bpf_load_program_attr attr = {};
struct bpf_prog_load_opts opts = {};


attr.prog_type = prog_type;
attr.name = name;
attr.insns = insns;
attr.license = license;
if (prog_type != BPF_PROG_TYPE_TRACING && prog_type != BPF_PROG_TYPE_EXT)
attr.kern_version = kern_version;
attr.log_level = log_level;
return bcc_prog_load_xattr(&attr, prog_len, log_buf, log_buf_size, true);
opts.kern_version = kern_version;
opts.log_level = log_level;
return bcc_prog_load_xattr(prog_type, name, license, insns, &opts, prog_len, log_buf, log_buf_size, true);
}

int bpf_open_raw_sock(const char *name)
Expand Down
8 changes: 5 additions & 3 deletions src/cc/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ struct bcc_create_map_attr {
__u32 btf_vmlinux_value_type_id;
};
};
struct bpf_load_program_attr;

struct bpf_prog_load_opts;

enum bpf_probe_attach_type {
BPF_PROBE_ENTRY,
Expand Down Expand Up @@ -88,10 +89,11 @@ int bcc_prog_load(enum bpf_prog_type prog_type, const char *name,
const struct bpf_insn *insns, int prog_len,
const char *license, unsigned kern_version,
int log_level, char *log_buf, unsigned log_buf_size);
int bcc_prog_load_xattr(struct bpf_load_program_attr *attr,
int bcc_prog_load_xattr(enum bpf_prog_type prog_type, const char *prog_name,
const char *license, const struct bpf_insn *insns,
struct bpf_prog_load_opts *opts,
int prog_len, char *log_buf,
unsigned log_buf_size, bool allow_rlimit);

int bpf_attach_socket(int sockfd, int progfd);

/* create RAW socket. If name is not NULL/a non-empty null-terminated string,
Expand Down

0 comments on commit e96571e

Please sign in to comment.