lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 23 Nov 2017 18:12:01 -0800
From:   Jakub Kicinski <jakub.kicinski@...ronome.com>
To:     netdev@...r.kernel.org
Cc:     oss-drivers@...ronome.com, daniel@...earbox.net,
        Jakub Kicinski <jakub.kicinski@...ronome.com>
Subject: [PATCH iproute2/master 04/11] 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@...ronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@...ronome.com>
Acked-by: Daniel Borkmann <daniel@...earbox.net>
---
 include/bpf_util.h |  5 +++++
 lib/bpf.c          | 49 +++++++++++++++++++++++++++++++++++++------------
 2 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/include/bpf_util.h b/include/bpf_util.h
index 638721f6315a..8e39a2d489db 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 7493595ab1d6..52f7c790065f 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 {
-- 
2.14.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ