@@ -1617,8 +1617,8 @@ int cpu_map_generic_redirect(struct bpf_cpu_map_entry *rcpu,
/* Return map's numa specified by userspace */
static inline int bpf_map_attr_numa_node(const union bpf_attr *attr)
{
- return (attr->map_flags & BPF_F_NUMA_NODE) ?
- attr->numa_node : NUMA_NO_NODE;
+ return (attr->map_create.map_flags & BPF_F_NUMA_NODE) ?
+ attr->map_create.numa_node : NUMA_NO_NODE;
}
struct bpf_prog *bpf_prog_get_type_path(const char *name, enum bpf_prog_type type);
@@ -1271,29 +1271,31 @@ enum {
BPF_OBJ_NAME_LEN = 16U,
};
+struct bpf_map_create_attr {
+ __u32 map_type; /* one of enum bpf_map_type */
+ __u32 key_size; /* size of key in bytes */
+ __u32 value_size; /* size of value in bytes */
+ __u32 max_entries; /* max number of entries in a map */
+ __u32 map_flags; /* BPF_MAP_CREATE related
+ * flags defined above.
+ */
+ __u32 inner_map_fd; /* fd pointing to the inner map */
+ __u32 numa_node; /* numa node (effective only if
+ * BPF_F_NUMA_NODE is set).
+ */
+ char map_name[BPF_OBJ_NAME_LEN];
+ __u32 map_ifindex; /* ifindex of netdev to create on */
+ __u32 btf_fd; /* fd pointing to a BTF type data */
+ __u32 btf_key_type_id; /* BTF type_id of the key */
+ __u32 btf_value_type_id; /* BTF type_id of the value */
+ __u32 btf_vmlinux_value_type_id; /* BTF type_id of a kernel-
+ * struct stored as the
+ * map value
+ */
+};
+
union bpf_attr {
- struct { /* anonymous struct used by BPF_MAP_CREATE command */
- __u32 map_type; /* one of enum bpf_map_type */
- __u32 key_size; /* size of key in bytes */
- __u32 value_size; /* size of value in bytes */
- __u32 max_entries; /* max number of entries in a map */
- __u32 map_flags; /* BPF_MAP_CREATE related
- * flags defined above.
- */
- __u32 inner_map_fd; /* fd pointing to the inner map */
- __u32 numa_node; /* numa node (effective only if
- * BPF_F_NUMA_NODE is set).
- */
- char map_name[BPF_OBJ_NAME_LEN];
- __u32 map_ifindex; /* ifindex of netdev to create on */
- __u32 btf_fd; /* fd pointing to a BTF type data */
- __u32 btf_key_type_id; /* BTF type_id of the key */
- __u32 btf_value_type_id; /* BTF type_id of the value */
- __u32 btf_vmlinux_value_type_id;/* BTF type_id of a kernel-
- * struct stored as the
- * map value
- */
- };
+ struct bpf_map_create_attr map_create;
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
__u32 map_fd;
@@ -1506,6 +1508,22 @@ union bpf_attr {
__u32 flags; /* extra flags */
} prog_bind_map;
+ /* DEPRECATED: these are kept for compatibility purposes. */
+ struct { /* anonymous struct used by BPF_MAP_CREATE command */
+ __u32 map_type;
+ __u32 key_size;
+ __u32 value_size;
+ __u32 max_entries;
+ __u32 map_flags;
+ __u32 inner_map_fd;
+ __u32 numa_node;
+ char map_name[BPF_OBJ_NAME_LEN];
+ __u32 map_ifindex;
+ __u32 btf_fd;
+ __u32 btf_key_type_id;
+ __u32 btf_value_type_id;
+ __u32 btf_vmlinux_value_type_id;
+ };
} __attribute__((aligned(8)));
/* The description below is an attempt at providing documentation to eBPF
@@ -103,7 +103,7 @@ const struct bpf_map_ops bpf_map_offload_ops = {
.map_check_btf = map_check_no_btf,
};
-static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
+static struct bpf_map *find_and_alloc_map(struct bpf_map_create_attr *attr)
{
const struct bpf_map_ops *ops;
u32 type = attr->map_type;
@@ -118,13 +118,13 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
return ERR_PTR(-EINVAL);
if (ops->map_alloc_check) {
- err = ops->map_alloc_check(attr);
+ err = ops->map_alloc_check((union bpf_attr *)attr); /* XXX: Dodgy cast */
if (err)
return ERR_PTR(err);
}
if (attr->map_ifindex)
ops = &bpf_map_offload_ops;
- map = ops->map_alloc(attr);
+ map = ops->map_alloc((union bpf_attr *)attr); /* XXX: Dodgy cast */
if (IS_ERR(map))
return map;
map->ops = ops;
@@ -814,18 +814,14 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf,
return ret;
}
-#define BPF_MAP_CREATE_LAST_FIELD btf_vmlinux_value_type_id
/* called via syscall */
-static int map_create(union bpf_attr *attr)
+static int map_create(struct bpf_map_create_attr *attr)
{
int numa_node = bpf_map_attr_numa_node(attr);
struct bpf_map *map;
int f_flags;
int err;
- err = CHECK_ATTR(BPF_MAP_CREATE);
- if (err)
- return -EINVAL;
if (attr->btf_vmlinux_value_type_id) {
if (attr->map_type != BPF_MAP_TYPE_STRUCT_OPS ||
@@ -4570,7 +4566,8 @@ static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
switch (cmd) {
case BPF_MAP_CREATE:
- err = map_create(&attr);
+ err = CHECK_ATTR_TAIL(&attr, map_create);
+ err = err ?: map_create(&attr.map_create);
break;
case BPF_MAP_LOOKUP_ELEM:
err = map_lookup_elem(&attr);