* CONFIG_CGROUP_BPF is turned off, then the call will fail early with EINVAL. If it is turned on the
* parameters are validated however, and that'll fail with EBADF then. */
- attr = (union bpf_attr) {
- .attach_type = BPF_CGROUP_INET_EGRESS,
- .target_fd = -1,
- .attach_bpf_fd = -1,
- };
+ // FIXME: Clang doesn't 0-pad with structured initialization, causing
+ // the kernel to reject the bpf_attr as invalid. See:
+ // https://github.com/torvalds/linux/blob/v5.9/kernel/bpf/syscall.c#L65
+ // Ideally it should behave like GCC, so that we can remove these workarounds.
+ zero(attr);
+ attr.attach_type = BPF_CGROUP_INET_EGRESS;
+ attr.target_fd = -1;
+ attr.attach_bpf_fd = -1;
if (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0) {
if (errno != EBADF) {
* bpf() call and the BPF_F_ALLOW_MULTI flags value. Since the flags are checked early in the system call we'll
* get EINVAL if it's not supported, and EBADF as before if it is available. */
- attr = (union bpf_attr) {
- .attach_type = BPF_CGROUP_INET_EGRESS,
- .target_fd = -1,
- .attach_bpf_fd = -1,
- .attach_flags = BPF_F_ALLOW_MULTI,
- };
+ zero(attr);
+ attr.attach_type = BPF_CGROUP_INET_EGRESS;
+ attr.target_fd = -1;
+ attr.attach_bpf_fd = -1;
+ attr.attach_flags = BPF_F_ALLOW_MULTI;
if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0) {
if (errno == EBADF) {
// https://github.com/torvalds/linux/blob/v5.9/kernel/bpf/syscall.c#L65
// Ideally it should behave like GCC, so that we can remove these workarounds.
zero(attr);
- attr = (union bpf_attr) {
- .prog_type = p->prog_type,
- .insns = PTR_TO_UINT64(p->instructions),
- .insn_cnt = p->n_instructions,
- .license = PTR_TO_UINT64("GPL"),
- .log_buf = PTR_TO_UINT64(log_buf),
- .log_level = !!log_buf,
- .log_size = log_size,
- };
+ attr.prog_type = p->prog_type;
+ attr.insns = PTR_TO_UINT64(p->instructions);
+ attr.insn_cnt = p->n_instructions;
+ attr.license = PTR_TO_UINT64("GPL");
+ attr.log_buf = PTR_TO_UINT64(log_buf);
+ attr.log_level = !!log_buf;
+ attr.log_size = log_size;
p->kernel_fd = bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
if (p->kernel_fd < 0)
return -EBUSY;
zero(attr);
- attr = (union bpf_attr) {
- .pathname = PTR_TO_UINT64(path),
- };
+ attr.pathname = PTR_TO_UINT64(path);
p->kernel_fd = bpf(BPF_OBJ_GET, &attr, sizeof(attr));
if (p->kernel_fd < 0)
return -errno;
zero(attr);
- attr = (union bpf_attr) {
- .attach_type = type,
- .target_fd = fd,
- .attach_bpf_fd = p->kernel_fd,
- .attach_flags = flags,
- };
+ attr.attach_type = type;
+ attr.target_fd = fd;
+ attr.attach_bpf_fd = p->kernel_fd;
+ attr.attach_flags = flags;
if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0)
return -errno;
union bpf_attr attr;
zero(attr);
- attr = (union bpf_attr) {
- .attach_type = p->attached_type,
- .target_fd = fd,
- .attach_bpf_fd = p->kernel_fd,
- };
+ attr.attach_type = p->attached_type;
+ attr.target_fd = fd;
+ attr.attach_bpf_fd = p->kernel_fd;
if (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0)
return -errno;
}
int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags) {
- union bpf_attr attr = {
- .map_type = type,
- .key_size = key_size,
- .value_size = value_size,
- .max_entries = max_entries,
- .map_flags = flags,
- };
+ union bpf_attr attr;
int fd;
+ zero(attr);
+ attr.map_type = type;
+ attr.key_size = key_size;
+ attr.value_size = value_size;
+ attr.max_entries = max_entries;
+ attr.map_flags = flags;
+
fd = bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
if (fd < 0)
return -errno;
}
int bpf_map_update_element(int fd, const void *key, void *value) {
+ union bpf_attr attr;
- union bpf_attr attr = {
- .map_fd = fd,
- .key = PTR_TO_UINT64(key),
- .value = PTR_TO_UINT64(value),
- };
+ zero(attr);
+ attr.map_fd = fd;
+ attr.key = PTR_TO_UINT64(key);
+ attr.value = PTR_TO_UINT64(value);
if (bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)) < 0)
return -errno;
}
int bpf_map_lookup_element(int fd, const void *key, void *value) {
+ union bpf_attr attr;
- union bpf_attr attr = {
- .map_fd = fd,
- .key = PTR_TO_UINT64(key),
- .value = PTR_TO_UINT64(value),
- };
+ zero(attr);
+ attr.map_fd = fd;
+ attr.key = PTR_TO_UINT64(key);
+ attr.value = PTR_TO_UINT64(value);
if (bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)) < 0)
return -errno;