forked from mirrors/linux
		
	bpf, libbpf: introduce bpf_object__probe_caps to test BPF capabilities
It currently only checks whether kernel supports map/prog names. This capability check will be used in the next two commits to skip setting prog/map names. Suggested-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Stanislav Fomichev <sdf@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
		
							parent
							
								
									8c4905b995
								
							
						
					
					
						commit
						47eff61777
					
				
					 1 changed files with 58 additions and 0 deletions
				
			
		|  | @ -24,6 +24,7 @@ | |||
| #include <linux/kernel.h> | ||||
| #include <linux/bpf.h> | ||||
| #include <linux/btf.h> | ||||
| #include <linux/filter.h> | ||||
| #include <linux/list.h> | ||||
| #include <linux/limits.h> | ||||
| #include <linux/perf_event.h> | ||||
|  | @ -114,6 +115,11 @@ void libbpf_set_print(libbpf_print_fn_t warn, | |||
| # define LIBBPF_ELF_C_READ_MMAP ELF_C_READ | ||||
| #endif | ||||
| 
 | ||||
| struct bpf_capabilities { | ||||
| 	/* v4.14: kernel support for program & map names. */ | ||||
| 	__u32 name:1; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * bpf_prog should be a better name but it has been used in | ||||
|  * linux/filter.h. | ||||
|  | @ -160,6 +166,8 @@ struct bpf_program { | |||
| 	void *func_info; | ||||
| 	__u32 func_info_rec_size; | ||||
| 	__u32 func_info_len; | ||||
| 
 | ||||
| 	struct bpf_capabilities *caps; | ||||
| }; | ||||
| 
 | ||||
| struct bpf_map { | ||||
|  | @ -221,6 +229,8 @@ struct bpf_object { | |||
| 	void *priv; | ||||
| 	bpf_object_clear_priv_t clear_priv; | ||||
| 
 | ||||
| 	struct bpf_capabilities caps; | ||||
| 
 | ||||
| 	char path[]; | ||||
| }; | ||||
| #define obj_elf_valid(o)	((o)->efile.elf) | ||||
|  | @ -342,6 +352,7 @@ bpf_object__add_program(struct bpf_object *obj, void *data, size_t size, | |||
| 	if (err) | ||||
| 		return err; | ||||
| 
 | ||||
| 	prog.caps = &obj->caps; | ||||
| 	progs = obj->programs; | ||||
| 	nr_progs = obj->nr_programs; | ||||
| 
 | ||||
|  | @ -1135,6 +1146,52 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd) | |||
| 	return -errno; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| bpf_object__probe_name(struct bpf_object *obj) | ||||
| { | ||||
| 	struct bpf_load_program_attr attr; | ||||
| 	char *cp, errmsg[STRERR_BUFSIZE]; | ||||
| 	struct bpf_insn insns[] = { | ||||
| 		BPF_MOV64_IMM(BPF_REG_0, 0), | ||||
| 		BPF_EXIT_INSN(), | ||||
| 	}; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	/* make sure basic loading works */ | ||||
| 
 | ||||
| 	memset(&attr, 0, sizeof(attr)); | ||||
| 	attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER; | ||||
| 	attr.insns = insns; | ||||
| 	attr.insns_cnt = ARRAY_SIZE(insns); | ||||
| 	attr.license = "GPL"; | ||||
| 
 | ||||
| 	ret = bpf_load_program_xattr(&attr, NULL, 0); | ||||
| 	if (ret < 0) { | ||||
| 		cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); | ||||
| 		pr_warning("Error in %s():%s(%d). Couldn't load basic 'r0 = 0' BPF program.\n", | ||||
| 			   __func__, cp, errno); | ||||
| 		return -errno; | ||||
| 	} | ||||
| 	close(ret); | ||||
| 
 | ||||
| 	/* now try the same program, but with the name */ | ||||
| 
 | ||||
| 	attr.name = "test"; | ||||
| 	ret = bpf_load_program_xattr(&attr, NULL, 0); | ||||
| 	if (ret >= 0) { | ||||
| 		obj->caps.name = 1; | ||||
| 		close(ret); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| bpf_object__probe_caps(struct bpf_object *obj) | ||||
| { | ||||
| 	return bpf_object__probe_name(obj); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| bpf_object__create_maps(struct bpf_object *obj) | ||||
| { | ||||
|  | @ -1708,6 +1765,7 @@ int bpf_object__load(struct bpf_object *obj) | |||
| 
 | ||||
| 	obj->loaded = true; | ||||
| 
 | ||||
| 	CHECK_ERR(bpf_object__probe_caps(obj), err, out); | ||||
| 	CHECK_ERR(bpf_object__create_maps(obj), err, out); | ||||
| 	CHECK_ERR(bpf_object__relocate(obj), err, out); | ||||
| 	CHECK_ERR(bpf_object__load_progs(obj), err, out); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Stanislav Fomichev
						Stanislav Fomichev