aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/libbpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r--tools/lib/bpf/libbpf.c635
1 files changed, 582 insertions, 53 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index d6e62e90e8d4..169e347c76f6 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -9,7 +9,9 @@
9 * Copyright (C) 2017 Nicira, Inc. 9 * Copyright (C) 2017 Nicira, Inc.
10 */ 10 */
11 11
12#ifndef _GNU_SOURCE
12#define _GNU_SOURCE 13#define _GNU_SOURCE
14#endif
13#include <stdlib.h> 15#include <stdlib.h>
14#include <stdio.h> 16#include <stdio.h>
15#include <stdarg.h> 17#include <stdarg.h>
@@ -24,6 +26,7 @@
24#include <linux/kernel.h> 26#include <linux/kernel.h>
25#include <linux/bpf.h> 27#include <linux/bpf.h>
26#include <linux/btf.h> 28#include <linux/btf.h>
29#include <linux/filter.h>
27#include <linux/list.h> 30#include <linux/list.h>
28#include <linux/limits.h> 31#include <linux/limits.h>
29#include <linux/perf_event.h> 32#include <linux/perf_event.h>
@@ -114,6 +117,11 @@ void libbpf_set_print(libbpf_print_fn_t warn,
114# define LIBBPF_ELF_C_READ_MMAP ELF_C_READ 117# define LIBBPF_ELF_C_READ_MMAP ELF_C_READ
115#endif 118#endif
116 119
120struct bpf_capabilities {
121 /* v4.14: kernel support for program & map names. */
122 __u32 name:1;
123};
124
117/* 125/*
118 * bpf_prog should be a better name but it has been used in 126 * bpf_prog should be a better name but it has been used in
119 * linux/filter.h. 127 * linux/filter.h.
@@ -124,6 +132,10 @@ struct bpf_program {
124 char *name; 132 char *name;
125 int prog_ifindex; 133 int prog_ifindex;
126 char *section_name; 134 char *section_name;
135 /* section_name with / replaced by _; makes recursive pinning
136 * in bpf_object__pin_programs easier
137 */
138 char *pin_name;
127 struct bpf_insn *insns; 139 struct bpf_insn *insns;
128 size_t insns_cnt, main_prog_cnt; 140 size_t insns_cnt, main_prog_cnt;
129 enum bpf_prog_type type; 141 enum bpf_prog_type type;
@@ -152,6 +164,16 @@ struct bpf_program {
152 bpf_program_clear_priv_t clear_priv; 164 bpf_program_clear_priv_t clear_priv;
153 165
154 enum bpf_attach_type expected_attach_type; 166 enum bpf_attach_type expected_attach_type;
167 int btf_fd;
168 void *func_info;
169 __u32 func_info_rec_size;
170 __u32 func_info_cnt;
171
172 struct bpf_capabilities *caps;
173
174 void *line_info;
175 __u32 line_info_rec_size;
176 __u32 line_info_cnt;
155}; 177};
156 178
157struct bpf_map { 179struct bpf_map {
@@ -159,6 +181,7 @@ struct bpf_map {
159 char *name; 181 char *name;
160 size_t offset; 182 size_t offset;
161 int map_ifindex; 183 int map_ifindex;
184 int inner_map_fd;
162 struct bpf_map_def def; 185 struct bpf_map_def def;
163 __u32 btf_key_type_id; 186 __u32 btf_key_type_id;
164 __u32 btf_value_type_id; 187 __u32 btf_value_type_id;
@@ -208,10 +231,13 @@ struct bpf_object {
208 struct list_head list; 231 struct list_head list;
209 232
210 struct btf *btf; 233 struct btf *btf;
234 struct btf_ext *btf_ext;
211 235
212 void *priv; 236 void *priv;
213 bpf_object_clear_priv_t clear_priv; 237 bpf_object_clear_priv_t clear_priv;
214 238
239 struct bpf_capabilities caps;
240
215 char path[]; 241 char path[];
216}; 242};
217#define obj_elf_valid(o) ((o)->efile.elf) 243#define obj_elf_valid(o) ((o)->efile.elf)
@@ -237,6 +263,10 @@ void bpf_program__unload(struct bpf_program *prog)
237 263
238 prog->instances.nr = -1; 264 prog->instances.nr = -1;
239 zfree(&prog->instances.fds); 265 zfree(&prog->instances.fds);
266
267 zclose(prog->btf_fd);
268 zfree(&prog->func_info);
269 zfree(&prog->line_info);
240} 270}
241 271
242static void bpf_program__exit(struct bpf_program *prog) 272static void bpf_program__exit(struct bpf_program *prog)
@@ -253,6 +283,7 @@ static void bpf_program__exit(struct bpf_program *prog)
253 bpf_program__unload(prog); 283 bpf_program__unload(prog);
254 zfree(&prog->name); 284 zfree(&prog->name);
255 zfree(&prog->section_name); 285 zfree(&prog->section_name);
286 zfree(&prog->pin_name);
256 zfree(&prog->insns); 287 zfree(&prog->insns);
257 zfree(&prog->reloc_desc); 288 zfree(&prog->reloc_desc);
258 289
@@ -261,6 +292,17 @@ static void bpf_program__exit(struct bpf_program *prog)
261 prog->idx = -1; 292 prog->idx = -1;
262} 293}
263 294
295static char *__bpf_program__pin_name(struct bpf_program *prog)
296{
297 char *name, *p;
298
299 name = p = strdup(prog->section_name);
300 while ((p = strchr(p, '/')))
301 *p = '_';
302
303 return name;
304}
305
264static int 306static int
265bpf_program__init(void *data, size_t size, char *section_name, int idx, 307bpf_program__init(void *data, size_t size, char *section_name, int idx,
266 struct bpf_program *prog) 308 struct bpf_program *prog)
@@ -279,6 +321,13 @@ bpf_program__init(void *data, size_t size, char *section_name, int idx,
279 goto errout; 321 goto errout;
280 } 322 }
281 323
324 prog->pin_name = __bpf_program__pin_name(prog);
325 if (!prog->pin_name) {
326 pr_warning("failed to alloc pin name for prog under section(%d) %s\n",
327 idx, section_name);
328 goto errout;
329 }
330
282 prog->insns = malloc(size); 331 prog->insns = malloc(size);
283 if (!prog->insns) { 332 if (!prog->insns) {
284 pr_warning("failed to alloc insns for prog under section %s\n", 333 pr_warning("failed to alloc insns for prog under section %s\n",
@@ -291,7 +340,8 @@ bpf_program__init(void *data, size_t size, char *section_name, int idx,
291 prog->idx = idx; 340 prog->idx = idx;
292 prog->instances.fds = NULL; 341 prog->instances.fds = NULL;
293 prog->instances.nr = -1; 342 prog->instances.nr = -1;
294 prog->type = BPF_PROG_TYPE_KPROBE; 343 prog->type = BPF_PROG_TYPE_UNSPEC;
344 prog->btf_fd = -1;
295 345
296 return 0; 346 return 0;
297errout: 347errout:
@@ -310,6 +360,7 @@ bpf_object__add_program(struct bpf_object *obj, void *data, size_t size,
310 if (err) 360 if (err)
311 return err; 361 return err;
312 362
363 prog.caps = &obj->caps;
313 progs = obj->programs; 364 progs = obj->programs;
314 nr_progs = obj->nr_programs; 365 nr_progs = obj->nr_programs;
315 366
@@ -562,6 +613,14 @@ static int compare_bpf_map(const void *_a, const void *_b)
562 return a->offset - b->offset; 613 return a->offset - b->offset;
563} 614}
564 615
616static bool bpf_map_type__is_map_in_map(enum bpf_map_type type)
617{
618 if (type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
619 type == BPF_MAP_TYPE_HASH_OF_MAPS)
620 return true;
621 return false;
622}
623
565static int 624static int
566bpf_object__init_maps(struct bpf_object *obj, int flags) 625bpf_object__init_maps(struct bpf_object *obj, int flags)
567{ 626{
@@ -625,13 +684,15 @@ bpf_object__init_maps(struct bpf_object *obj, int flags)
625 } 684 }
626 obj->nr_maps = nr_maps; 685 obj->nr_maps = nr_maps;
627 686
628 /* 687 for (i = 0; i < nr_maps; i++) {
629 * fill all fd with -1 so won't close incorrect 688 /*
630 * fd (fd=0 is stdin) when failure (zclose won't close 689 * fill all fd with -1 so won't close incorrect
631 * negative fd)). 690 * fd (fd=0 is stdin) when failure (zclose won't close
632 */ 691 * negative fd)).
633 for (i = 0; i < nr_maps; i++) 692 */
634 obj->maps[i].fd = -1; 693 obj->maps[i].fd = -1;
694 obj->maps[i].inner_map_fd = -1;
695 }
635 696
636 /* 697 /*
637 * Fill obj->maps using data in "maps" section. 698 * Fill obj->maps using data in "maps" section.
@@ -723,6 +784,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
723{ 784{
724 Elf *elf = obj->efile.elf; 785 Elf *elf = obj->efile.elf;
725 GElf_Ehdr *ep = &obj->efile.ehdr; 786 GElf_Ehdr *ep = &obj->efile.ehdr;
787 Elf_Data *btf_ext_data = NULL;
726 Elf_Scn *scn = NULL; 788 Elf_Scn *scn = NULL;
727 int idx = 0, err = 0; 789 int idx = 0, err = 0;
728 790
@@ -784,6 +846,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
784 BTF_ELF_SEC, PTR_ERR(obj->btf)); 846 BTF_ELF_SEC, PTR_ERR(obj->btf));
785 obj->btf = NULL; 847 obj->btf = NULL;
786 } 848 }
849 } else if (strcmp(name, BTF_EXT_ELF_SEC) == 0) {
850 btf_ext_data = data;
787 } else if (sh.sh_type == SHT_SYMTAB) { 851 } else if (sh.sh_type == SHT_SYMTAB) {
788 if (obj->efile.symbols) { 852 if (obj->efile.symbols) {
789 pr_warning("bpf: multiple SYMTAB in %s\n", 853 pr_warning("bpf: multiple SYMTAB in %s\n",
@@ -845,6 +909,22 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
845 pr_warning("Corrupted ELF file: index of strtab invalid\n"); 909 pr_warning("Corrupted ELF file: index of strtab invalid\n");
846 return LIBBPF_ERRNO__FORMAT; 910 return LIBBPF_ERRNO__FORMAT;
847 } 911 }
912 if (btf_ext_data) {
913 if (!obj->btf) {
914 pr_debug("Ignore ELF section %s because its depending ELF section %s is not found.\n",
915 BTF_EXT_ELF_SEC, BTF_ELF_SEC);
916 } else {
917 obj->btf_ext = btf_ext__new(btf_ext_data->d_buf,
918 btf_ext_data->d_size,
919 __pr_debug);
920 if (IS_ERR(obj->btf_ext)) {
921 pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
922 BTF_EXT_ELF_SEC,
923 PTR_ERR(obj->btf_ext));
924 obj->btf_ext = NULL;
925 }
926 }
927 }
848 if (obj->efile.maps_shndx >= 0) { 928 if (obj->efile.maps_shndx >= 0) {
849 err = bpf_object__init_maps(obj, flags); 929 err = bpf_object__init_maps(obj, flags);
850 if (err) 930 if (err)
@@ -1095,6 +1175,52 @@ err_free_new_name:
1095} 1175}
1096 1176
1097static int 1177static int
1178bpf_object__probe_name(struct bpf_object *obj)
1179{
1180 struct bpf_load_program_attr attr;
1181 char *cp, errmsg[STRERR_BUFSIZE];
1182 struct bpf_insn insns[] = {
1183 BPF_MOV64_IMM(BPF_REG_0, 0),
1184 BPF_EXIT_INSN(),
1185 };
1186 int ret;
1187
1188 /* make sure basic loading works */
1189
1190 memset(&attr, 0, sizeof(attr));
1191 attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
1192 attr.insns = insns;
1193 attr.insns_cnt = ARRAY_SIZE(insns);
1194 attr.license = "GPL";
1195
1196 ret = bpf_load_program_xattr(&attr, NULL, 0);
1197 if (ret < 0) {
1198 cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));
1199 pr_warning("Error in %s():%s(%d). Couldn't load basic 'r0 = 0' BPF program.\n",
1200 __func__, cp, errno);
1201 return -errno;
1202 }
1203 close(ret);
1204
1205 /* now try the same program, but with the name */
1206
1207 attr.name = "test";
1208 ret = bpf_load_program_xattr(&attr, NULL, 0);
1209 if (ret >= 0) {
1210 obj->caps.name = 1;
1211 close(ret);
1212 }
1213
1214 return 0;
1215}
1216
1217static int
1218bpf_object__probe_caps(struct bpf_object *obj)
1219{
1220 return bpf_object__probe_name(obj);
1221}
1222
1223static int
1098bpf_object__create_maps(struct bpf_object *obj) 1224bpf_object__create_maps(struct bpf_object *obj)
1099{ 1225{
1100 struct bpf_create_map_attr create_attr = {}; 1226 struct bpf_create_map_attr create_attr = {};
@@ -1113,7 +1239,8 @@ bpf_object__create_maps(struct bpf_object *obj)
1113 continue; 1239 continue;
1114 } 1240 }
1115 1241
1116 create_attr.name = map->name; 1242 if (obj->caps.name)
1243 create_attr.name = map->name;
1117 create_attr.map_ifindex = map->map_ifindex; 1244 create_attr.map_ifindex = map->map_ifindex;
1118 create_attr.map_type = def->type; 1245 create_attr.map_type = def->type;
1119 create_attr.map_flags = def->map_flags; 1246 create_attr.map_flags = def->map_flags;
@@ -1123,6 +1250,9 @@ bpf_object__create_maps(struct bpf_object *obj)
1123 create_attr.btf_fd = 0; 1250 create_attr.btf_fd = 0;
1124 create_attr.btf_key_type_id = 0; 1251 create_attr.btf_key_type_id = 0;
1125 create_attr.btf_value_type_id = 0; 1252 create_attr.btf_value_type_id = 0;
1253 if (bpf_map_type__is_map_in_map(def->type) &&
1254 map->inner_map_fd >= 0)
1255 create_attr.inner_map_fd = map->inner_map_fd;
1126 1256
1127 if (obj->btf && !bpf_map_find_btf_info(map, obj->btf)) { 1257 if (obj->btf && !bpf_map_find_btf_info(map, obj->btf)) {
1128 create_attr.btf_fd = btf__fd(obj->btf); 1258 create_attr.btf_fd = btf__fd(obj->btf);
@@ -1161,12 +1291,89 @@ bpf_object__create_maps(struct bpf_object *obj)
1161} 1291}
1162 1292
1163static int 1293static int
1294check_btf_ext_reloc_err(struct bpf_program *prog, int err,
1295 void *btf_prog_info, const char *info_name)
1296{
1297 if (err != -ENOENT) {
1298 pr_warning("Error in loading %s for sec %s.\n",
1299 info_name, prog->section_name);
1300 return err;
1301 }
1302
1303 /* err == -ENOENT (i.e. prog->section_name not found in btf_ext) */
1304
1305 if (btf_prog_info) {
1306 /*
1307 * Some info has already been found but has problem
1308 * in the last btf_ext reloc. Must have to error
1309 * out.
1310 */
1311 pr_warning("Error in relocating %s for sec %s.\n",
1312 info_name, prog->section_name);
1313 return err;
1314 }
1315
1316 /*
1317 * Have problem loading the very first info. Ignore
1318 * the rest.
1319 */
1320 pr_warning("Cannot find %s for main program sec %s. Ignore all %s.\n",
1321 info_name, prog->section_name, info_name);
1322 return 0;
1323}
1324
1325static int
1326bpf_program_reloc_btf_ext(struct bpf_program *prog, struct bpf_object *obj,
1327 const char *section_name, __u32 insn_offset)
1328{
1329 int err;
1330
1331 if (!insn_offset || prog->func_info) {
1332 /*
1333 * !insn_offset => main program
1334 *
1335 * For sub prog, the main program's func_info has to
1336 * be loaded first (i.e. prog->func_info != NULL)
1337 */
1338 err = btf_ext__reloc_func_info(obj->btf, obj->btf_ext,
1339 section_name, insn_offset,
1340 &prog->func_info,
1341 &prog->func_info_cnt);
1342 if (err)
1343 return check_btf_ext_reloc_err(prog, err,
1344 prog->func_info,
1345 "bpf_func_info");
1346
1347 prog->func_info_rec_size = btf_ext__func_info_rec_size(obj->btf_ext);
1348 }
1349
1350 if (!insn_offset || prog->line_info) {
1351 err = btf_ext__reloc_line_info(obj->btf, obj->btf_ext,
1352 section_name, insn_offset,
1353 &prog->line_info,
1354 &prog->line_info_cnt);
1355 if (err)
1356 return check_btf_ext_reloc_err(prog, err,
1357 prog->line_info,
1358 "bpf_line_info");
1359
1360 prog->line_info_rec_size = btf_ext__line_info_rec_size(obj->btf_ext);
1361 }
1362
1363 if (!insn_offset)
1364 prog->btf_fd = btf__fd(obj->btf);
1365
1366 return 0;
1367}
1368
1369static int
1164bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj, 1370bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
1165 struct reloc_desc *relo) 1371 struct reloc_desc *relo)
1166{ 1372{
1167 struct bpf_insn *insn, *new_insn; 1373 struct bpf_insn *insn, *new_insn;
1168 struct bpf_program *text; 1374 struct bpf_program *text;
1169 size_t new_cnt; 1375 size_t new_cnt;
1376 int err;
1170 1377
1171 if (relo->type != RELO_CALL) 1378 if (relo->type != RELO_CALL)
1172 return -LIBBPF_ERRNO__RELOC; 1379 return -LIBBPF_ERRNO__RELOC;
@@ -1189,6 +1396,15 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
1189 pr_warning("oom in prog realloc\n"); 1396 pr_warning("oom in prog realloc\n");
1190 return -ENOMEM; 1397 return -ENOMEM;
1191 } 1398 }
1399
1400 if (obj->btf_ext) {
1401 err = bpf_program_reloc_btf_ext(prog, obj,
1402 text->section_name,
1403 prog->insns_cnt);
1404 if (err)
1405 return err;
1406 }
1407
1192 memcpy(new_insn + prog->insns_cnt, text->insns, 1408 memcpy(new_insn + prog->insns_cnt, text->insns,
1193 text->insns_cnt * sizeof(*insn)); 1409 text->insns_cnt * sizeof(*insn));
1194 prog->insns = new_insn; 1410 prog->insns = new_insn;
@@ -1208,7 +1424,17 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
1208{ 1424{
1209 int i, err; 1425 int i, err;
1210 1426
1211 if (!prog || !prog->reloc_desc) 1427 if (!prog)
1428 return 0;
1429
1430 if (obj->btf_ext) {
1431 err = bpf_program_reloc_btf_ext(prog, obj,
1432 prog->section_name, 0);
1433 if (err)
1434 return err;
1435 }
1436
1437 if (!prog->reloc_desc)
1212 return 0; 1438 return 0;
1213 1439
1214 for (i = 0; i < prog->nr_reloc; i++) { 1440 for (i = 0; i < prog->nr_reloc; i++) {
@@ -1296,9 +1522,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
1296} 1522}
1297 1523
1298static int 1524static int
1299load_program(enum bpf_prog_type type, enum bpf_attach_type expected_attach_type, 1525load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
1300 const char *name, struct bpf_insn *insns, int insns_cnt, 1526 char *license, __u32 kern_version, int *pfd)
1301 char *license, __u32 kern_version, int *pfd, int prog_ifindex)
1302{ 1527{
1303 struct bpf_load_program_attr load_attr; 1528 struct bpf_load_program_attr load_attr;
1304 char *cp, errmsg[STRERR_BUFSIZE]; 1529 char *cp, errmsg[STRERR_BUFSIZE];
@@ -1306,15 +1531,22 @@ load_program(enum bpf_prog_type type, enum bpf_attach_type expected_attach_type,
1306 int ret; 1531 int ret;
1307 1532
1308 memset(&load_attr, 0, sizeof(struct bpf_load_program_attr)); 1533 memset(&load_attr, 0, sizeof(struct bpf_load_program_attr));
1309 load_attr.prog_type = type; 1534 load_attr.prog_type = prog->type;
1310 load_attr.expected_attach_type = expected_attach_type; 1535 load_attr.expected_attach_type = prog->expected_attach_type;
1311 load_attr.name = name; 1536 if (prog->caps->name)
1537 load_attr.name = prog->name;
1312 load_attr.insns = insns; 1538 load_attr.insns = insns;
1313 load_attr.insns_cnt = insns_cnt; 1539 load_attr.insns_cnt = insns_cnt;
1314 load_attr.license = license; 1540 load_attr.license = license;
1315 load_attr.kern_version = kern_version; 1541 load_attr.kern_version = kern_version;
1316 load_attr.prog_ifindex = prog_ifindex; 1542 load_attr.prog_ifindex = prog->prog_ifindex;
1317 1543 load_attr.prog_btf_fd = prog->btf_fd >= 0 ? prog->btf_fd : 0;
1544 load_attr.func_info = prog->func_info;
1545 load_attr.func_info_rec_size = prog->func_info_rec_size;
1546 load_attr.func_info_cnt = prog->func_info_cnt;
1547 load_attr.line_info = prog->line_info;
1548 load_attr.line_info_rec_size = prog->line_info_rec_size;
1549 load_attr.line_info_cnt = prog->line_info_cnt;
1318 if (!load_attr.insns || !load_attr.insns_cnt) 1550 if (!load_attr.insns || !load_attr.insns_cnt)
1319 return -EINVAL; 1551 return -EINVAL;
1320 1552
@@ -1394,10 +1626,8 @@ bpf_program__load(struct bpf_program *prog,
1394 pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n", 1626 pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
1395 prog->section_name, prog->instances.nr); 1627 prog->section_name, prog->instances.nr);
1396 } 1628 }
1397 err = load_program(prog->type, prog->expected_attach_type, 1629 err = load_program(prog, prog->insns, prog->insns_cnt,
1398 prog->name, prog->insns, prog->insns_cnt, 1630 license, kern_version, &fd);
1399 license, kern_version, &fd,
1400 prog->prog_ifindex);
1401 if (!err) 1631 if (!err)
1402 prog->instances.fds[0] = fd; 1632 prog->instances.fds[0] = fd;
1403 goto out; 1633 goto out;
@@ -1425,11 +1655,9 @@ bpf_program__load(struct bpf_program *prog,
1425 continue; 1655 continue;
1426 } 1656 }
1427 1657
1428 err = load_program(prog->type, prog->expected_attach_type, 1658 err = load_program(prog, result.new_insn_ptr,
1429 prog->name, result.new_insn_ptr,
1430 result.new_insn_cnt, 1659 result.new_insn_cnt,
1431 license, kern_version, &fd, 1660 license, kern_version, &fd);
1432 prog->prog_ifindex);
1433 1661
1434 if (err) { 1662 if (err) {
1435 pr_warning("Loading the %dth instance of program '%s' failed\n", 1663 pr_warning("Loading the %dth instance of program '%s' failed\n",
@@ -1495,12 +1723,12 @@ static bool bpf_prog_type__needs_kver(enum bpf_prog_type type)
1495 case BPF_PROG_TYPE_LIRC_MODE2: 1723 case BPF_PROG_TYPE_LIRC_MODE2:
1496 case BPF_PROG_TYPE_SK_REUSEPORT: 1724 case BPF_PROG_TYPE_SK_REUSEPORT:
1497 case BPF_PROG_TYPE_FLOW_DISSECTOR: 1725 case BPF_PROG_TYPE_FLOW_DISSECTOR:
1498 return false;
1499 case BPF_PROG_TYPE_UNSPEC: 1726 case BPF_PROG_TYPE_UNSPEC:
1500 case BPF_PROG_TYPE_KPROBE:
1501 case BPF_PROG_TYPE_TRACEPOINT: 1727 case BPF_PROG_TYPE_TRACEPOINT:
1502 case BPF_PROG_TYPE_PERF_EVENT:
1503 case BPF_PROG_TYPE_RAW_TRACEPOINT: 1728 case BPF_PROG_TYPE_RAW_TRACEPOINT:
1729 case BPF_PROG_TYPE_PERF_EVENT:
1730 return false;
1731 case BPF_PROG_TYPE_KPROBE:
1504 default: 1732 default:
1505 return true; 1733 return true;
1506 } 1734 }
@@ -1627,6 +1855,7 @@ int bpf_object__load(struct bpf_object *obj)
1627 1855
1628 obj->loaded = true; 1856 obj->loaded = true;
1629 1857
1858 CHECK_ERR(bpf_object__probe_caps(obj), err, out);
1630 CHECK_ERR(bpf_object__create_maps(obj), err, out); 1859 CHECK_ERR(bpf_object__create_maps(obj), err, out);
1631 CHECK_ERR(bpf_object__relocate(obj), err, out); 1860 CHECK_ERR(bpf_object__relocate(obj), err, out);
1632 CHECK_ERR(bpf_object__load_progs(obj), err, out); 1861 CHECK_ERR(bpf_object__load_progs(obj), err, out);
@@ -1699,6 +1928,34 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
1699 return 0; 1928 return 0;
1700} 1929}
1701 1930
1931int bpf_program__unpin_instance(struct bpf_program *prog, const char *path,
1932 int instance)
1933{
1934 int err;
1935
1936 err = check_path(path);
1937 if (err)
1938 return err;
1939
1940 if (prog == NULL) {
1941 pr_warning("invalid program pointer\n");
1942 return -EINVAL;
1943 }
1944
1945 if (instance < 0 || instance >= prog->instances.nr) {
1946 pr_warning("invalid prog instance %d of prog %s (max %d)\n",
1947 instance, prog->section_name, prog->instances.nr);
1948 return -EINVAL;
1949 }
1950
1951 err = unlink(path);
1952 if (err != 0)
1953 return -errno;
1954 pr_debug("unpinned program '%s'\n", path);
1955
1956 return 0;
1957}
1958
1702static int make_dir(const char *path) 1959static int make_dir(const char *path)
1703{ 1960{
1704 char *cp, errmsg[STRERR_BUFSIZE]; 1961 char *cp, errmsg[STRERR_BUFSIZE];
@@ -1733,6 +1990,11 @@ int bpf_program__pin(struct bpf_program *prog, const char *path)
1733 return -EINVAL; 1990 return -EINVAL;
1734 } 1991 }
1735 1992
1993 if (prog->instances.nr == 1) {
1994 /* don't create subdirs when pinning single instance */
1995 return bpf_program__pin_instance(prog, path, 0);
1996 }
1997
1736 err = make_dir(path); 1998 err = make_dir(path);
1737 if (err) 1999 if (err)
1738 return err; 2000 return err;
@@ -1742,16 +2004,83 @@ int bpf_program__pin(struct bpf_program *prog, const char *path)
1742 int len; 2004 int len;
1743 2005
1744 len = snprintf(buf, PATH_MAX, "%s/%d", path, i); 2006 len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
2007 if (len < 0) {
2008 err = -EINVAL;
2009 goto err_unpin;
2010 } else if (len >= PATH_MAX) {
2011 err = -ENAMETOOLONG;
2012 goto err_unpin;
2013 }
2014
2015 err = bpf_program__pin_instance(prog, buf, i);
2016 if (err)
2017 goto err_unpin;
2018 }
2019
2020 return 0;
2021
2022err_unpin:
2023 for (i = i - 1; i >= 0; i--) {
2024 char buf[PATH_MAX];
2025 int len;
2026
2027 len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
2028 if (len < 0)
2029 continue;
2030 else if (len >= PATH_MAX)
2031 continue;
2032
2033 bpf_program__unpin_instance(prog, buf, i);
2034 }
2035
2036 rmdir(path);
2037
2038 return err;
2039}
2040
2041int bpf_program__unpin(struct bpf_program *prog, const char *path)
2042{
2043 int i, err;
2044
2045 err = check_path(path);
2046 if (err)
2047 return err;
2048
2049 if (prog == NULL) {
2050 pr_warning("invalid program pointer\n");
2051 return -EINVAL;
2052 }
2053
2054 if (prog->instances.nr <= 0) {
2055 pr_warning("no instances of prog %s to pin\n",
2056 prog->section_name);
2057 return -EINVAL;
2058 }
2059
2060 if (prog->instances.nr == 1) {
2061 /* don't create subdirs when pinning single instance */
2062 return bpf_program__unpin_instance(prog, path, 0);
2063 }
2064
2065 for (i = 0; i < prog->instances.nr; i++) {
2066 char buf[PATH_MAX];
2067 int len;
2068
2069 len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
1745 if (len < 0) 2070 if (len < 0)
1746 return -EINVAL; 2071 return -EINVAL;
1747 else if (len >= PATH_MAX) 2072 else if (len >= PATH_MAX)
1748 return -ENAMETOOLONG; 2073 return -ENAMETOOLONG;
1749 2074
1750 err = bpf_program__pin_instance(prog, buf, i); 2075 err = bpf_program__unpin_instance(prog, buf, i);
1751 if (err) 2076 if (err)
1752 return err; 2077 return err;
1753 } 2078 }
1754 2079
2080 err = rmdir(path);
2081 if (err)
2082 return -errno;
2083
1755 return 0; 2084 return 0;
1756} 2085}
1757 2086
@@ -1776,12 +2105,33 @@ int bpf_map__pin(struct bpf_map *map, const char *path)
1776 } 2105 }
1777 2106
1778 pr_debug("pinned map '%s'\n", path); 2107 pr_debug("pinned map '%s'\n", path);
2108
1779 return 0; 2109 return 0;
1780} 2110}
1781 2111
1782int bpf_object__pin(struct bpf_object *obj, const char *path) 2112int bpf_map__unpin(struct bpf_map *map, const char *path)
2113{
2114 int err;
2115
2116 err = check_path(path);
2117 if (err)
2118 return err;
2119
2120 if (map == NULL) {
2121 pr_warning("invalid map pointer\n");
2122 return -EINVAL;
2123 }
2124
2125 err = unlink(path);
2126 if (err != 0)
2127 return -errno;
2128 pr_debug("unpinned map '%s'\n", path);
2129
2130 return 0;
2131}
2132
2133int bpf_object__pin_maps(struct bpf_object *obj, const char *path)
1783{ 2134{
1784 struct bpf_program *prog;
1785 struct bpf_map *map; 2135 struct bpf_map *map;
1786 int err; 2136 int err;
1787 2137
@@ -1803,28 +2153,142 @@ int bpf_object__pin(struct bpf_object *obj, const char *path)
1803 2153
1804 len = snprintf(buf, PATH_MAX, "%s/%s", path, 2154 len = snprintf(buf, PATH_MAX, "%s/%s", path,
1805 bpf_map__name(map)); 2155 bpf_map__name(map));
2156 if (len < 0) {
2157 err = -EINVAL;
2158 goto err_unpin_maps;
2159 } else if (len >= PATH_MAX) {
2160 err = -ENAMETOOLONG;
2161 goto err_unpin_maps;
2162 }
2163
2164 err = bpf_map__pin(map, buf);
2165 if (err)
2166 goto err_unpin_maps;
2167 }
2168
2169 return 0;
2170
2171err_unpin_maps:
2172 while ((map = bpf_map__prev(map, obj))) {
2173 char buf[PATH_MAX];
2174 int len;
2175
2176 len = snprintf(buf, PATH_MAX, "%s/%s", path,
2177 bpf_map__name(map));
2178 if (len < 0)
2179 continue;
2180 else if (len >= PATH_MAX)
2181 continue;
2182
2183 bpf_map__unpin(map, buf);
2184 }
2185
2186 return err;
2187}
2188
2189int bpf_object__unpin_maps(struct bpf_object *obj, const char *path)
2190{
2191 struct bpf_map *map;
2192 int err;
2193
2194 if (!obj)
2195 return -ENOENT;
2196
2197 bpf_map__for_each(map, obj) {
2198 char buf[PATH_MAX];
2199 int len;
2200
2201 len = snprintf(buf, PATH_MAX, "%s/%s", path,
2202 bpf_map__name(map));
1806 if (len < 0) 2203 if (len < 0)
1807 return -EINVAL; 2204 return -EINVAL;
1808 else if (len >= PATH_MAX) 2205 else if (len >= PATH_MAX)
1809 return -ENAMETOOLONG; 2206 return -ENAMETOOLONG;
1810 2207
1811 err = bpf_map__pin(map, buf); 2208 err = bpf_map__unpin(map, buf);
1812 if (err) 2209 if (err)
1813 return err; 2210 return err;
1814 } 2211 }
1815 2212
2213 return 0;
2214}
2215
2216int bpf_object__pin_programs(struct bpf_object *obj, const char *path)
2217{
2218 struct bpf_program *prog;
2219 int err;
2220
2221 if (!obj)
2222 return -ENOENT;
2223
2224 if (!obj->loaded) {
2225 pr_warning("object not yet loaded; load it first\n");
2226 return -ENOENT;
2227 }
2228
2229 err = make_dir(path);
2230 if (err)
2231 return err;
2232
1816 bpf_object__for_each_program(prog, obj) { 2233 bpf_object__for_each_program(prog, obj) {
1817 char buf[PATH_MAX]; 2234 char buf[PATH_MAX];
1818 int len; 2235 int len;
1819 2236
1820 len = snprintf(buf, PATH_MAX, "%s/%s", path, 2237 len = snprintf(buf, PATH_MAX, "%s/%s", path,
1821 prog->section_name); 2238 prog->pin_name);
2239 if (len < 0) {
2240 err = -EINVAL;
2241 goto err_unpin_programs;
2242 } else if (len >= PATH_MAX) {
2243 err = -ENAMETOOLONG;
2244 goto err_unpin_programs;
2245 }
2246
2247 err = bpf_program__pin(prog, buf);
2248 if (err)
2249 goto err_unpin_programs;
2250 }
2251
2252 return 0;
2253
2254err_unpin_programs:
2255 while ((prog = bpf_program__prev(prog, obj))) {
2256 char buf[PATH_MAX];
2257 int len;
2258
2259 len = snprintf(buf, PATH_MAX, "%s/%s", path,
2260 prog->pin_name);
2261 if (len < 0)
2262 continue;
2263 else if (len >= PATH_MAX)
2264 continue;
2265
2266 bpf_program__unpin(prog, buf);
2267 }
2268
2269 return err;
2270}
2271
2272int bpf_object__unpin_programs(struct bpf_object *obj, const char *path)
2273{
2274 struct bpf_program *prog;
2275 int err;
2276
2277 if (!obj)
2278 return -ENOENT;
2279
2280 bpf_object__for_each_program(prog, obj) {
2281 char buf[PATH_MAX];
2282 int len;
2283
2284 len = snprintf(buf, PATH_MAX, "%s/%s", path,
2285 prog->pin_name);
1822 if (len < 0) 2286 if (len < 0)
1823 return -EINVAL; 2287 return -EINVAL;
1824 else if (len >= PATH_MAX) 2288 else if (len >= PATH_MAX)
1825 return -ENAMETOOLONG; 2289 return -ENAMETOOLONG;
1826 2290
1827 err = bpf_program__pin(prog, buf); 2291 err = bpf_program__unpin(prog, buf);
1828 if (err) 2292 if (err)
1829 return err; 2293 return err;
1830 } 2294 }
@@ -1832,6 +2296,23 @@ int bpf_object__pin(struct bpf_object *obj, const char *path)
1832 return 0; 2296 return 0;
1833} 2297}
1834 2298
2299int bpf_object__pin(struct bpf_object *obj, const char *path)
2300{
2301 int err;
2302
2303 err = bpf_object__pin_maps(obj, path);
2304 if (err)
2305 return err;
2306
2307 err = bpf_object__pin_programs(obj, path);
2308 if (err) {
2309 bpf_object__unpin_maps(obj, path);
2310 return err;
2311 }
2312
2313 return 0;
2314}
2315
1835void bpf_object__close(struct bpf_object *obj) 2316void bpf_object__close(struct bpf_object *obj)
1836{ 2317{
1837 size_t i; 2318 size_t i;
@@ -1845,6 +2326,7 @@ void bpf_object__close(struct bpf_object *obj)
1845 bpf_object__elf_finish(obj); 2326 bpf_object__elf_finish(obj);
1846 bpf_object__unload(obj); 2327 bpf_object__unload(obj);
1847 btf__free(obj->btf); 2328 btf__free(obj->btf);
2329 btf_ext__free(obj->btf_ext);
1848 2330
1849 for (i = 0; i < obj->nr_maps; i++) { 2331 for (i = 0; i < obj->nr_maps; i++) {
1850 zfree(&obj->maps[i].name); 2332 zfree(&obj->maps[i].name);
@@ -1918,23 +2400,26 @@ void *bpf_object__priv(struct bpf_object *obj)
1918} 2400}
1919 2401
1920static struct bpf_program * 2402static struct bpf_program *
1921__bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) 2403__bpf_program__iter(struct bpf_program *p, struct bpf_object *obj, bool forward)
1922{ 2404{
1923 size_t idx; 2405 size_t nr_programs = obj->nr_programs;
2406 ssize_t idx;
1924 2407
1925 if (!obj->programs) 2408 if (!nr_programs)
1926 return NULL; 2409 return NULL;
1927 /* First handler */
1928 if (prev == NULL)
1929 return &obj->programs[0];
1930 2410
1931 if (prev->obj != obj) { 2411 if (!p)
2412 /* Iter from the beginning */
2413 return forward ? &obj->programs[0] :
2414 &obj->programs[nr_programs - 1];
2415
2416 if (p->obj != obj) {
1932 pr_warning("error: program handler doesn't match object\n"); 2417 pr_warning("error: program handler doesn't match object\n");
1933 return NULL; 2418 return NULL;
1934 } 2419 }
1935 2420
1936 idx = (prev - obj->programs) + 1; 2421 idx = (p - obj->programs) + (forward ? 1 : -1);
1937 if (idx >= obj->nr_programs) 2422 if (idx >= obj->nr_programs || idx < 0)
1938 return NULL; 2423 return NULL;
1939 return &obj->programs[idx]; 2424 return &obj->programs[idx];
1940} 2425}
@@ -1945,7 +2430,19 @@ bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
1945 struct bpf_program *prog = prev; 2430 struct bpf_program *prog = prev;
1946 2431
1947 do { 2432 do {
1948 prog = __bpf_program__next(prog, obj); 2433 prog = __bpf_program__iter(prog, obj, true);
2434 } while (prog && bpf_program__is_function_storage(prog, obj));
2435
2436 return prog;
2437}
2438
2439struct bpf_program *
2440bpf_program__prev(struct bpf_program *next, struct bpf_object *obj)
2441{
2442 struct bpf_program *prog = next;
2443
2444 do {
2445 prog = __bpf_program__iter(prog, obj, false);
1949 } while (prog && bpf_program__is_function_storage(prog, obj)); 2446 } while (prog && bpf_program__is_function_storage(prog, obj));
1950 2447
1951 return prog; 2448 return prog;
@@ -2272,10 +2769,24 @@ void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex)
2272 map->map_ifindex = ifindex; 2769 map->map_ifindex = ifindex;
2273} 2770}
2274 2771
2275struct bpf_map * 2772int bpf_map__set_inner_map_fd(struct bpf_map *map, int fd)
2276bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
2277{ 2773{
2278 size_t idx; 2774 if (!bpf_map_type__is_map_in_map(map->def.type)) {
2775 pr_warning("error: unsupported map type\n");
2776 return -EINVAL;
2777 }
2778 if (map->inner_map_fd != -1) {
2779 pr_warning("error: inner_map_fd already specified\n");
2780 return -EINVAL;
2781 }
2782 map->inner_map_fd = fd;
2783 return 0;
2784}
2785
2786static struct bpf_map *
2787__bpf_map__iter(struct bpf_map *m, struct bpf_object *obj, int i)
2788{
2789 ssize_t idx;
2279 struct bpf_map *s, *e; 2790 struct bpf_map *s, *e;
2280 2791
2281 if (!obj || !obj->maps) 2792 if (!obj || !obj->maps)
@@ -2284,22 +2795,40 @@ bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
2284 s = obj->maps; 2795 s = obj->maps;
2285 e = obj->maps + obj->nr_maps; 2796 e = obj->maps + obj->nr_maps;
2286 2797
2287 if (prev == NULL) 2798 if ((m < s) || (m >= e)) {
2288 return s;
2289
2290 if ((prev < s) || (prev >= e)) {
2291 pr_warning("error in %s: map handler doesn't belong to object\n", 2799 pr_warning("error in %s: map handler doesn't belong to object\n",
2292 __func__); 2800 __func__);
2293 return NULL; 2801 return NULL;
2294 } 2802 }
2295 2803
2296 idx = (prev - obj->maps) + 1; 2804 idx = (m - obj->maps) + i;
2297 if (idx >= obj->nr_maps) 2805 if (idx >= obj->nr_maps || idx < 0)
2298 return NULL; 2806 return NULL;
2299 return &obj->maps[idx]; 2807 return &obj->maps[idx];
2300} 2808}
2301 2809
2302struct bpf_map * 2810struct bpf_map *
2811bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
2812{
2813 if (prev == NULL)
2814 return obj->maps;
2815
2816 return __bpf_map__iter(prev, obj, 1);
2817}
2818
2819struct bpf_map *
2820bpf_map__prev(struct bpf_map *next, struct bpf_object *obj)
2821{
2822 if (next == NULL) {
2823 if (!obj->nr_maps)
2824 return NULL;
2825 return obj->maps + obj->nr_maps - 1;
2826 }
2827
2828 return __bpf_map__iter(next, obj, -1);
2829}
2830
2831struct bpf_map *
2303bpf_object__find_map_by_name(struct bpf_object *obj, const char *name) 2832bpf_object__find_map_by_name(struct bpf_object *obj, const char *name)
2304{ 2833{
2305 struct bpf_map *pos; 2834 struct bpf_map *pos;