bpf: split parse from program loading
Parsing command line is currently done together with potentially loading a new eBPF program. This makes it more difficult to provide additional parameters for loading (which may come after the eBPF program info on the command line). Split the two (only internally for now). Verbose parameter has to be saved in struct bpf_cfg_in to be carried between the stages. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
parent
51be754690
commit
3f0b9e620c
|
|
@ -70,9 +70,14 @@ struct bpf_cfg_in {
|
||||||
const char *uds;
|
const char *uds;
|
||||||
enum bpf_prog_type type;
|
enum bpf_prog_type type;
|
||||||
enum bpf_mode mode;
|
enum bpf_mode mode;
|
||||||
|
bool verbose;
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
struct sock_filter opcodes[BPF_MAXINSNS];
|
struct sock_filter opcodes[BPF_MAXINSNS];
|
||||||
|
union {
|
||||||
|
int n_opcodes;
|
||||||
|
int prog_fd;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
|
/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
|
||||||
|
|
|
||||||
49
lib/bpf.c
49
lib/bpf.c
|
|
@ -805,7 +805,7 @@ static int bpf_obj_pinned(const char *pathname, enum bpf_prog_type type)
|
||||||
return prog_fd;
|
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;
|
const char *file, *section, *uds_name;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
|
@ -893,25 +893,39 @@ static int bpf_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl)
|
||||||
PREV_ARG();
|
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,
|
ret = bpf_ops_parse(argc, argv, cfg->opcodes,
|
||||||
cfg->mode == CBPF_FILE);
|
cfg->mode == CBPF_FILE);
|
||||||
else if (cfg->mode == EBPF_OBJECT)
|
cfg->n_opcodes = ret;
|
||||||
ret = bpf_obj_open(file, cfg->type, section, verbose);
|
} else if (cfg->mode == EBPF_OBJECT) {
|
||||||
else if (cfg->mode == EBPF_PINNED)
|
ret = 0; /* program will be loaded by load stage */
|
||||||
|
} else if (cfg->mode == EBPF_PINNED) {
|
||||||
ret = bpf_obj_pinned(file, cfg->type);
|
ret = bpf_obj_pinned(file, cfg->type);
|
||||||
else
|
cfg->prog_fd = ret;
|
||||||
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
cfg->object = file;
|
cfg->object = file;
|
||||||
cfg->section = section;
|
cfg->section = section;
|
||||||
cfg->uds = uds_name;
|
cfg->uds = uds_name;
|
||||||
cfg->argc = argc;
|
cfg->argc = argc;
|
||||||
cfg->argv = argv;
|
cfg->argv = argv;
|
||||||
|
cfg->verbose = verbose;
|
||||||
|
|
||||||
return ret;
|
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,
|
static int bpf_parse_opt_tbl(struct bpf_cfg_in *cfg,
|
||||||
const struct bpf_cfg_ops *ops, void *nl,
|
const struct bpf_cfg_ops *ops, void *nl,
|
||||||
const bool *opt_tbl)
|
const bool *opt_tbl)
|
||||||
|
|
@ -919,17 +933,21 @@ static int bpf_parse_opt_tbl(struct bpf_cfg_in *cfg,
|
||||||
char annotation[256];
|
char annotation[256];
|
||||||
int ret;
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (cfg->mode == CBPF_BYTECODE || cfg->mode == CBPF_FILE)
|
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) {
|
if (cfg->mode == EBPF_OBJECT || cfg->mode == EBPF_PINNED) {
|
||||||
snprintf(annotation, sizeof(annotation), "%s:[%s]",
|
snprintf(annotation, sizeof(annotation), "%s:[%s]",
|
||||||
basename(cfg->object), cfg->mode == EBPF_PINNED ?
|
basename(cfg->object), cfg->mode == EBPF_PINNED ?
|
||||||
"*fsobj" : cfg->section);
|
"*fsobj" : cfg->section);
|
||||||
ops->ebpf_cb(nl, ret, annotation);
|
ops->ebpf_cb(nl, cfg->prog_fd, annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
int ret, prog_fd, map_fd;
|
||||||
uint32_t map_key;
|
uint32_t map_key;
|
||||||
|
|
||||||
prog_fd = bpf_parse(&cfg, opt_tbl);
|
ret = bpf_do_parse(&cfg, opt_tbl);
|
||||||
if (prog_fd < 0)
|
if (ret < 0)
|
||||||
return prog_fd;
|
return ret;
|
||||||
|
|
||||||
|
ret = bpf_do_load(&cfg);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
prog_fd = cfg.prog_fd;
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
map_key = *key;
|
map_key = *key;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue