bpf: keep parsed program mode in struct bpf_cfg_in

bpf_parse() will parse command line arguments to find out the
program mode.  This mode will later be needed at loading time.
Instead of keeping it locally add it to struct bpf_cfg_in,
this will allow splitting parsing and loading stages.

enum bpf_mode has to be moved to the header file, because C
doesn't allow forward declaration of enums.

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:
Jakub Kicinski 2017-11-23 18:11:59 -08:00 committed by Stephen Hemminger
parent 658cfebc27
commit f20ff2f195
2 changed files with 25 additions and 26 deletions

View File

@ -56,11 +56,20 @@ struct bpf_cfg_ops {
void (*ebpf_cb)(void *nl, int fd, const char *annotation); void (*ebpf_cb)(void *nl, int fd, const char *annotation);
}; };
enum bpf_mode {
CBPF_BYTECODE,
CBPF_FILE,
EBPF_OBJECT,
EBPF_PINNED,
BPF_MODE_MAX,
};
struct bpf_cfg_in { struct bpf_cfg_in {
const char *object; const char *object;
const char *section; const char *section;
const char *uds; const char *uds;
enum bpf_prog_type type; enum bpf_prog_type type;
enum bpf_mode mode;
int argc; int argc;
char **argv; char **argv;
struct sock_filter *ops; struct sock_filter *ops;

View File

@ -805,16 +805,7 @@ static int bpf_obj_pinned(const char *pathname, enum bpf_prog_type type)
return prog_fd; return prog_fd;
} }
enum bpf_mode { static int bpf_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl)
CBPF_BYTECODE,
CBPF_FILE,
EBPF_OBJECT,
EBPF_PINNED,
BPF_MODE_MAX,
};
static int bpf_parse(enum bpf_mode *mode, 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;
@ -827,20 +818,20 @@ static int bpf_parse(enum bpf_mode *mode, struct bpf_cfg_in *cfg,
if (opt_tbl[CBPF_BYTECODE] && if (opt_tbl[CBPF_BYTECODE] &&
(matches(*argv, "bytecode") == 0 || (matches(*argv, "bytecode") == 0 ||
strcmp(*argv, "bc") == 0)) { strcmp(*argv, "bc") == 0)) {
*mode = CBPF_BYTECODE; cfg->mode = CBPF_BYTECODE;
} else if (opt_tbl[CBPF_FILE] && } else if (opt_tbl[CBPF_FILE] &&
(matches(*argv, "bytecode-file") == 0 || (matches(*argv, "bytecode-file") == 0 ||
strcmp(*argv, "bcf") == 0)) { strcmp(*argv, "bcf") == 0)) {
*mode = CBPF_FILE; cfg->mode = CBPF_FILE;
} else if (opt_tbl[EBPF_OBJECT] && } else if (opt_tbl[EBPF_OBJECT] &&
(matches(*argv, "object-file") == 0 || (matches(*argv, "object-file") == 0 ||
strcmp(*argv, "obj") == 0)) { strcmp(*argv, "obj") == 0)) {
*mode = EBPF_OBJECT; cfg->mode = EBPF_OBJECT;
} else if (opt_tbl[EBPF_PINNED] && } else if (opt_tbl[EBPF_PINNED] &&
(matches(*argv, "object-pinned") == 0 || (matches(*argv, "object-pinned") == 0 ||
matches(*argv, "pinned") == 0 || matches(*argv, "pinned") == 0 ||
matches(*argv, "fd") == 0)) { matches(*argv, "fd") == 0)) {
*mode = EBPF_PINNED; cfg->mode = EBPF_PINNED;
} else { } else {
fprintf(stderr, "What mode is \"%s\"?\n", *argv); fprintf(stderr, "What mode is \"%s\"?\n", *argv);
return -1; return -1;
@ -848,7 +839,7 @@ static int bpf_parse(enum bpf_mode *mode, struct bpf_cfg_in *cfg,
NEXT_ARG(); NEXT_ARG();
file = section = uds_name = NULL; file = section = uds_name = NULL;
if (*mode == EBPF_OBJECT || *mode == EBPF_PINNED) { if (cfg->mode == EBPF_OBJECT || cfg->mode == EBPF_PINNED) {
file = *argv; file = *argv;
NEXT_ARG_FWD(); NEXT_ARG_FWD();
@ -902,11 +893,12 @@ static int bpf_parse(enum bpf_mode *mode, struct bpf_cfg_in *cfg,
PREV_ARG(); PREV_ARG();
} }
if (*mode == CBPF_BYTECODE || *mode == CBPF_FILE) if (cfg->mode == CBPF_BYTECODE || cfg->mode == CBPF_FILE)
ret = bpf_ops_parse(argc, argv, cfg->ops, *mode == CBPF_FILE); ret = bpf_ops_parse(argc, argv, cfg->ops,
else if (*mode == EBPF_OBJECT) cfg->mode == CBPF_FILE);
else if (cfg->mode == EBPF_OBJECT)
ret = bpf_obj_open(file, cfg->type, section, verbose); ret = bpf_obj_open(file, cfg->type, section, verbose);
else if (*mode == EBPF_PINNED) else if (cfg->mode == EBPF_PINNED)
ret = bpf_obj_pinned(file, cfg->type); ret = bpf_obj_pinned(file, cfg->type);
else else
return -1; return -1;
@ -926,20 +918,19 @@ static int bpf_parse_opt_tbl(struct bpf_cfg_in *cfg,
{ {
struct sock_filter opcodes[BPF_MAXINSNS]; struct sock_filter opcodes[BPF_MAXINSNS];
char annotation[256]; char annotation[256];
enum bpf_mode mode;
int ret; int ret;
cfg->ops = opcodes; cfg->ops = opcodes;
ret = bpf_parse(&mode, cfg, opt_tbl); ret = bpf_parse(cfg, opt_tbl);
cfg->ops = NULL; cfg->ops = NULL;
if (ret < 0) if (ret < 0)
return ret; return ret;
if (mode == CBPF_BYTECODE || mode == CBPF_FILE) if (cfg->mode == CBPF_BYTECODE || cfg->mode == CBPF_FILE)
ops->cbpf_cb(nl, opcodes, ret); ops->cbpf_cb(nl, opcodes, ret);
if (mode == EBPF_OBJECT || 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), 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, ret, annotation);
} }
@ -983,10 +974,9 @@ int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv)
}; };
struct bpf_map_ext ext = {}; struct bpf_map_ext ext = {};
int ret, prog_fd, map_fd; int ret, prog_fd, map_fd;
enum bpf_mode mode;
uint32_t map_key; uint32_t map_key;
prog_fd = bpf_parse(&mode, &cfg, opt_tbl); prog_fd = bpf_parse(&cfg, opt_tbl);
if (prog_fd < 0) if (prog_fd < 0)
return prog_fd; return prog_fd;
if (key) { if (key) {