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

Reply via email to