Program type is needed both for parsing and loading of the program. Parsing may also induce the type based on signatures from __bpf_prog_meta. Instead of passing the type around keep it in struct bpf_cfg_in.
Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com> Reviewed-by: Quentin Monnet <quentin.mon...@netronome.com> Acked-by: Daniel Borkmann <dan...@iogearbox.net> --- include/bpf_util.h | 5 +++-- ip/iplink_xdp.c | 3 ++- ip/iproute_lwtunnel.c | 3 ++- lib/bpf.c | 38 +++++++++++++++++++------------------- tc/f_bpf.c | 3 ++- tc/m_bpf.c | 3 ++- 6 files changed, 30 insertions(+), 25 deletions(-) diff --git a/include/bpf_util.h b/include/bpf_util.h index e818221d70d9..0da4b85c979a 100644 --- a/include/bpf_util.h +++ b/include/bpf_util.h @@ -60,6 +60,7 @@ struct bpf_cfg_in { const char *object; const char *section; const char *uds; + enum bpf_prog_type type; int argc; char **argv; struct sock_filter *ops; @@ -244,8 +245,8 @@ struct bpf_cfg_in { .off = 0, \ .imm = 0 }) -int bpf_parse_common(enum bpf_prog_type type, struct bpf_cfg_in *cfg, - const struct bpf_cfg_ops *ops, void *nl); +int bpf_parse_common(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops, + void *nl); const char *bpf_prog_to_default_section(enum bpf_prog_type type); diff --git a/ip/iplink_xdp.c b/ip/iplink_xdp.c index 2d2953aa47a8..993e44d7878a 100644 --- a/ip/iplink_xdp.c +++ b/ip/iplink_xdp.c @@ -52,6 +52,7 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, bool drv, bool offload) { struct bpf_cfg_in cfg = { + .type = BPF_PROG_TYPE_XDP, .argc = *argc, .argv = *argv, }; @@ -74,7 +75,7 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, return xdp_delete(&xdp); } - if (bpf_parse_common(BPF_PROG_TYPE_XDP, &cfg, &bpf_cb_ops, &xdp)) + if (bpf_parse_common(&cfg, &bpf_cb_ops, &xdp)) return -1; *argc = cfg.argc; diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c index 1c8adbe78ed2..9f0f647e261f 100644 --- a/ip/iproute_lwtunnel.c +++ b/ip/iproute_lwtunnel.c @@ -872,6 +872,7 @@ static int lwt_parse_bpf(struct rtattr *rta, size_t len, int attr, const enum bpf_prog_type bpf_type) { struct bpf_cfg_in cfg = { + .type = bpf_type, .argc = *argcp, .argv = *argvp, }; @@ -883,7 +884,7 @@ static int lwt_parse_bpf(struct rtattr *rta, size_t len, int err; nest = rta_nest(rta, len, attr); - err = bpf_parse_common(bpf_type, &cfg, &bpf_cb_ops, &x); + err = bpf_parse_common(&cfg, &bpf_cb_ops, &x); if (err < 0) { fprintf(stderr, "Failed to parse eBPF program: %s\n", strerror(-err)); diff --git a/lib/bpf.c b/lib/bpf.c index fdc28772fb71..5e65682b5ea4 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -813,8 +813,8 @@ enum bpf_mode { BPF_MODE_MAX, }; -static int bpf_parse(enum bpf_prog_type *type, enum bpf_mode *mode, - struct bpf_cfg_in *cfg, const bool *opt_tbl) +static int bpf_parse(enum bpf_mode *mode, struct bpf_cfg_in *cfg, + const bool *opt_tbl) { const char *file, *section, *uds_name; bool verbose = false; @@ -852,7 +852,7 @@ static int bpf_parse(enum bpf_prog_type *type, enum bpf_mode *mode, file = *argv; NEXT_ARG_FWD(); - if (*type == BPF_PROG_TYPE_UNSPEC) { + if (cfg->type == BPF_PROG_TYPE_UNSPEC) { if (argc > 0 && matches(*argv, "type") == 0) { NEXT_ARG(); for (i = 0; i < ARRAY_SIZE(__bpf_prog_meta); @@ -861,30 +861,30 @@ static int bpf_parse(enum bpf_prog_type *type, enum bpf_mode *mode, continue; if (!matches(*argv, __bpf_prog_meta[i].type)) { - *type = i; + cfg->type = i; break; } } - if (*type == BPF_PROG_TYPE_UNSPEC) { + if (cfg->type == BPF_PROG_TYPE_UNSPEC) { fprintf(stderr, "What type is \"%s\"?\n", *argv); return -1; } NEXT_ARG_FWD(); } else { - *type = BPF_PROG_TYPE_SCHED_CLS; + cfg->type = BPF_PROG_TYPE_SCHED_CLS; } } - section = bpf_prog_to_default_section(*type); + section = bpf_prog_to_default_section(cfg->type); if (argc > 0 && matches(*argv, "section") == 0) { NEXT_ARG(); section = *argv; NEXT_ARG_FWD(); } - if (__bpf_prog_meta[*type].may_uds_export) { + if (__bpf_prog_meta[cfg->type].may_uds_export) { uds_name = getenv(BPF_ENV_UDS); if (argc > 0 && !uds_name && matches(*argv, "export") == 0) { @@ -905,9 +905,9 @@ static int bpf_parse(enum bpf_prog_type *type, enum bpf_mode *mode, if (*mode == CBPF_BYTECODE || *mode == CBPF_FILE) ret = bpf_ops_parse(argc, argv, cfg->ops, *mode == CBPF_FILE); else if (*mode == EBPF_OBJECT) - ret = bpf_obj_open(file, *type, section, verbose); + ret = bpf_obj_open(file, cfg->type, section, verbose); else if (*mode == EBPF_PINNED) - ret = bpf_obj_pinned(file, *type); + ret = bpf_obj_pinned(file, cfg->type); else return -1; @@ -920,7 +920,7 @@ static int bpf_parse(enum bpf_prog_type *type, enum bpf_mode *mode, return ret; } -static int bpf_parse_opt_tbl(enum bpf_prog_type type, struct bpf_cfg_in *cfg, +static int bpf_parse_opt_tbl(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops, void *nl, const bool *opt_tbl) { @@ -930,7 +930,7 @@ static int bpf_parse_opt_tbl(enum bpf_prog_type type, struct bpf_cfg_in *cfg, int ret; cfg->ops = opcodes; - ret = bpf_parse(&type, &mode, cfg, opt_tbl); + ret = bpf_parse(&mode, cfg, opt_tbl); cfg->ops = NULL; if (ret < 0) return ret; @@ -947,8 +947,8 @@ static int bpf_parse_opt_tbl(enum bpf_prog_type type, struct bpf_cfg_in *cfg, return 0; } -int bpf_parse_common(enum bpf_prog_type type, struct bpf_cfg_in *cfg, - const struct bpf_cfg_ops *ops, void *nl) +int bpf_parse_common(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops, + void *nl) { bool opt_tbl[BPF_MODE_MAX] = {}; @@ -962,12 +962,11 @@ int bpf_parse_common(enum bpf_prog_type type, struct bpf_cfg_in *cfg, opt_tbl[EBPF_PINNED] = true; } - return bpf_parse_opt_tbl(type, cfg, ops, nl, opt_tbl); + return bpf_parse_opt_tbl(cfg, ops, nl, opt_tbl); } int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv) { - enum bpf_prog_type type = BPF_PROG_TYPE_UNSPEC; const bool opt_tbl[BPF_MODE_MAX] = { [EBPF_OBJECT] = true, [EBPF_PINNED] = true, @@ -978,6 +977,7 @@ int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv) .size_value = sizeof(int), }; struct bpf_cfg_in cfg = { + .type = BPF_PROG_TYPE_UNSPEC, .argc = argc, .argv = argv, }; @@ -986,7 +986,7 @@ int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv) enum bpf_mode mode; uint32_t map_key; - prog_fd = bpf_parse(&type, &mode, &cfg, opt_tbl); + prog_fd = bpf_parse(&mode, &cfg, opt_tbl); if (prog_fd < 0) return prog_fd; if (key) { @@ -1000,7 +1000,7 @@ int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv) } } - map_fd = bpf_obj_get(map_path, type); + map_fd = bpf_obj_get(map_path, cfg.type); if (map_fd < 0) { fprintf(stderr, "Couldn\'t retrieve pinned map \'%s\': %s\n", map_path, strerror(errno)); @@ -1010,7 +1010,7 @@ int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv) ret = bpf_map_selfcheck_pinned(map_fd, &test, &ext, offsetof(struct bpf_elf_map, max_elem), - type); + cfg.type); if (ret < 0) { fprintf(stderr, "Map \'%s\' self-check failed!\n", map_path); goto out_map; diff --git a/tc/f_bpf.c b/tc/f_bpf.c index 3f619d0dc738..a38ec2ab7786 100644 --- a/tc/f_bpf.c +++ b/tc/f_bpf.c @@ -103,10 +103,11 @@ static int bpf_parse_opt(struct filter_util *qu, char *handle, NEXT_ARG(); opt_bpf: seen_run = true; + cfg.type = bpf_type; cfg.argc = argc; cfg.argv = argv; - if (bpf_parse_common(bpf_type, &cfg, &bpf_cb_ops, n)) + if (bpf_parse_common(&cfg, &bpf_cb_ops, n)) return -1; argc = cfg.argc; diff --git a/tc/m_bpf.c b/tc/m_bpf.c index e3d0a2b11838..f2ce3892e4ed 100644 --- a/tc/m_bpf.c +++ b/tc/m_bpf.c @@ -98,10 +98,11 @@ static int bpf_parse_opt(struct action_util *a, int *ptr_argc, char ***ptr_argv, NEXT_ARG(); opt_bpf: seen_run = true; + cfg.type = bpf_type; cfg.argc = argc; cfg.argv = argv; - if (bpf_parse_common(bpf_type, &cfg, &bpf_cb_ops, n)) + if (bpf_parse_common(&cfg, &bpf_cb_ops, n)) return -1; argc = cfg.argc; -- 2.14.1