diff options
| -rw-r--r-- | tools/lib/bpf/bpf.c | 4 | ||||
| -rw-r--r-- | tools/lib/bpf/bpf.h | 5 | ||||
| -rw-r--r-- | tools/lib/bpf/libbpf.c | 69 | ||||
| -rw-r--r-- | tools/lib/bpf/libbpf.h | 22 | ||||
| -rw-r--r-- | tools/lib/bpf/libbpf.map | 3 | 
5 files changed, 101 insertions, 2 deletions
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index ab40dbf9f020..19ad7bcf0c2f 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -172,7 +172,7 @@ int bpf_map_create(enum bpf_map_type map_type,  		   __u32 max_entries,  		   const struct bpf_map_create_opts *opts)  { -	const size_t attr_sz = offsetofend(union bpf_attr, map_token_fd); +	const size_t attr_sz = offsetofend(union bpf_attr, excl_prog_hash_size);  	union bpf_attr attr;  	int fd; @@ -203,6 +203,8 @@ int bpf_map_create(enum bpf_map_type map_type,  	attr.map_ifindex = OPTS_GET(opts, map_ifindex, 0);  	attr.map_token_fd = OPTS_GET(opts, token_fd, 0); +	attr.excl_prog_hash = ptr_to_u64(OPTS_GET(opts, excl_prog_hash, NULL)); +	attr.excl_prog_hash_size = OPTS_GET(opts, excl_prog_hash_size, 0);  	fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz);  	return libbpf_err_errno(fd); diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 7252150e7ad3..e983a3e40d61 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -54,9 +54,12 @@ struct bpf_map_create_opts {  	__s32 value_type_btf_obj_fd;  	__u32 token_fd; + +	const void *excl_prog_hash; +	__u32 excl_prog_hash_size;  	size_t :0;  }; -#define bpf_map_create_opts__last_field token_fd +#define bpf_map_create_opts__last_field excl_prog_hash_size  LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,  			      const char *map_name, diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index a39640bd5448..5161c2b39875 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -499,6 +499,7 @@ struct bpf_program {  	__u32 line_info_rec_size;  	__u32 line_info_cnt;  	__u32 prog_flags; +	__u8  hash[SHA256_DIGEST_LENGTH];  };  struct bpf_struct_ops { @@ -578,6 +579,7 @@ struct bpf_map {  	bool autocreate;  	bool autoattach;  	__u64 map_extra; +	struct bpf_program *excl_prog;  };  enum extern_type { @@ -4488,6 +4490,44 @@ bpf_object__section_to_libbpf_map_type(const struct bpf_object *obj, int shndx)  	}  } +static int bpf_prog_compute_hash(struct bpf_program *prog) +{ +	struct bpf_insn *purged; +	int i, err; + +	purged = calloc(prog->insns_cnt, BPF_INSN_SZ); +	if (!purged) +		return -ENOMEM; + +	/* If relocations have been done, the map_fd needs to be +	 * discarded for the digest calculation. +	 */ +	for (i = 0; i < prog->insns_cnt; i++) { +		purged[i] = prog->insns[i]; +		if (purged[i].code == (BPF_LD | BPF_IMM | BPF_DW) && +		    (purged[i].src_reg == BPF_PSEUDO_MAP_FD || +		     purged[i].src_reg == BPF_PSEUDO_MAP_VALUE)) { +			purged[i].imm = 0; +			i++; +			if (i >= prog->insns_cnt || +			    prog->insns[i].code != 0 || +			    prog->insns[i].dst_reg != 0 || +			    prog->insns[i].src_reg != 0 || +			    prog->insns[i].off != 0) { +				err = -EINVAL; +				goto out; +			} +			purged[i] = prog->insns[i]; +			purged[i].imm = 0; +		} +	} +	err = libbpf_sha256(purged, prog->insns_cnt * sizeof(struct bpf_insn), +			    prog->hash, SHA256_DIGEST_LENGTH); +out: +	free(purged); +	return err; +} +  static int bpf_program__record_reloc(struct bpf_program *prog,  				     struct reloc_desc *reloc_desc,  				     __u32 insn_idx, const char *sym_name, @@ -5237,6 +5277,14 @@ static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, b  	create_attr.token_fd = obj->token_fd;  	if (obj->token_fd)  		create_attr.map_flags |= BPF_F_TOKEN_FD; +	if (map->excl_prog) { +		err = bpf_prog_compute_hash(map->excl_prog); +		if (err) +			return err; + +		create_attr.excl_prog_hash = map->excl_prog->hash; +		create_attr.excl_prog_hash_size = SHA256_DIGEST_LENGTH; +	}  	if (bpf_map__is_struct_ops(map)) {  		create_attr.btf_vmlinux_value_type_id = map->btf_vmlinux_value_type_id; @@ -10527,6 +10575,27 @@ int bpf_map__set_inner_map_fd(struct bpf_map *map, int fd)  	return 0;  } +int bpf_map__set_exclusive_program(struct bpf_map *map, struct bpf_program *prog) +{ +	if (map_is_created(map)) { +		pr_warn("exclusive programs must be set before map creation\n"); +		return libbpf_err(-EINVAL); +	} + +	if (map->obj != prog->obj) { +		pr_warn("excl_prog and map must be from the same bpf object\n"); +		return libbpf_err(-EINVAL); +	} + +	map->excl_prog = prog; +	return 0; +} + +struct bpf_program *bpf_map__exclusive_program(struct bpf_map *map) +{ +	return map->excl_prog; +} +  static struct bpf_map *  __bpf_map__iter(const struct bpf_map *m, const struct bpf_object *obj, int i)  { diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 2e91148d9b44..e978bc093c39 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -1291,6 +1291,28 @@ LIBBPF_API int bpf_map__lookup_and_delete_elem(const struct bpf_map *map,   */  LIBBPF_API int bpf_map__get_next_key(const struct bpf_map *map,  				     const void *cur_key, void *next_key, size_t key_sz); +/** + * @brief **bpf_map__set_exclusive_program()** sets a map to be exclusive to the + * specified program. This must be called *before* the map is created. + * + * @param map BPF map to make exclusive. + * @param prog BPF program to be the exclusive user of the map. Must belong + * to the same bpf_object as the map. + * @return 0 on success; a negative error code otherwise. + * + * This function must be called after the BPF object is opened but before + * it is loaded. Once the object is loaded, only the specified program + * will be able to access the map's contents. + */ +LIBBPF_API int bpf_map__set_exclusive_program(struct bpf_map *map, struct bpf_program *prog); + +/** + * @brief **bpf_map__exclusive_program()** returns the exclusive program + * that is registered with the map (if any). + * @param map BPF map to which the exclusive program is registered. + * @return the registered exclusive program. + */ +LIBBPF_API struct bpf_program *bpf_map__exclusive_program(struct bpf_map *map);  struct bpf_xdp_set_link_opts {  	size_t sz; diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index d7bd463e7017..8ed8749907d4 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -448,4 +448,7 @@ LIBBPF_1.6.0 {  } LIBBPF_1.5.0;  LIBBPF_1.7.0 { +	global: +		bpf_map__set_exclusive_program; +		bpf_map__exclusive_program;  } LIBBPF_1.6.0;  | 
