diff --git a/include/bpf_util.h b/include/bpf_util.h index 638721f6..8e39a2d4 100644 --- a/include/bpf_util.h +++ b/include/bpf_util.h @@ -70,9 +70,14 @@ struct bpf_cfg_in { const char *uds; enum bpf_prog_type type; enum bpf_mode mode; + bool verbose; int argc; char **argv; struct sock_filter opcodes[BPF_MAXINSNS]; + union { + int n_opcodes; + int prog_fd; + }; }; /* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */ diff --git a/lib/bpf.c b/lib/bpf.c index 7493595a..52f7c790 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -805,7 +805,7 @@ static int bpf_obj_pinned(const char *pathname, enum bpf_prog_type type) return prog_fd; } -static int bpf_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl) +static int bpf_do_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl) { const char *file, *section, *uds_name; bool verbose = false; @@ -893,25 +893,39 @@ static int bpf_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl) PREV_ARG(); } - if (cfg->mode == CBPF_BYTECODE || cfg->mode == CBPF_FILE) + if (cfg->mode == CBPF_BYTECODE || cfg->mode == CBPF_FILE) { ret = bpf_ops_parse(argc, argv, cfg->opcodes, cfg->mode == CBPF_FILE); - else if (cfg->mode == EBPF_OBJECT) - ret = bpf_obj_open(file, cfg->type, section, verbose); - else if (cfg->mode == EBPF_PINNED) + cfg->n_opcodes = ret; + } else if (cfg->mode == EBPF_OBJECT) { + ret = 0; /* program will be loaded by load stage */ + } else if (cfg->mode == EBPF_PINNED) { ret = bpf_obj_pinned(file, cfg->type); - else + cfg->prog_fd = ret; + } else { return -1; + } cfg->object = file; cfg->section = section; cfg->uds = uds_name; cfg->argc = argc; cfg->argv = argv; + cfg->verbose = verbose; return ret; } +static int bpf_do_load(struct bpf_cfg_in *cfg) +{ + if (cfg->mode == EBPF_OBJECT) { + cfg->prog_fd = bpf_obj_open(cfg->object, cfg->type, + cfg->section, cfg->verbose); + return cfg->prog_fd; + } + return 0; +} + static int bpf_parse_opt_tbl(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops, void *nl, const bool *opt_tbl) @@ -919,17 +933,21 @@ static int bpf_parse_opt_tbl(struct bpf_cfg_in *cfg, char annotation[256]; int ret; - ret = bpf_parse(cfg, opt_tbl); + ret = bpf_do_parse(cfg, opt_tbl); + if (ret < 0) + return ret; + + ret = bpf_do_load(cfg); if (ret < 0) return ret; if (cfg->mode == CBPF_BYTECODE || cfg->mode == CBPF_FILE) - ops->cbpf_cb(nl, cfg->opcodes, ret); + ops->cbpf_cb(nl, cfg->opcodes, cfg->n_opcodes); if (cfg->mode == EBPF_OBJECT || cfg->mode == EBPF_PINNED) { snprintf(annotation, sizeof(annotation), "%s:[%s]", basename(cfg->object), cfg->mode == EBPF_PINNED ? "*fsobj" : cfg->section); - ops->ebpf_cb(nl, ret, annotation); + ops->ebpf_cb(nl, cfg->prog_fd, annotation); } return 0; @@ -973,9 +991,16 @@ int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv) int ret, prog_fd, map_fd; uint32_t map_key; - prog_fd = bpf_parse(&cfg, opt_tbl); - if (prog_fd < 0) - return prog_fd; + ret = bpf_do_parse(&cfg, opt_tbl); + if (ret < 0) + return ret; + + ret = bpf_do_load(&cfg); + if (ret < 0) + return ret; + + prog_fd = cfg.prog_fd; + if (key) { map_key = *key; } else {