netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Toke Høiland-Jørgensen" <toke@redhat.com>
To: Stephen Hemminger <stephen@networkplumber.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Alexei Starovoitov <ast@kernel.org>
Cc: "Martin KaFai Lau" <kafai@fb.com>,
	"Song Liu" <songliubraving@fb.com>, "Yonghong Song" <yhs@fb.com>,
	"David Miller" <davem@davemloft.net>,
	"Jesper Dangaard Brouer" <brouer@redhat.com>,
	netdev@vger.kernel.org, bpf@vger.kernel.org,
	"Toke Høiland-Jørgensen" <toke@redhat.com>
Subject: [RFC bpf-next 5/5] iproute2: Support loading XDP programs with libbpf
Date: Tue, 20 Aug 2019 13:47:06 +0200	[thread overview]
Message-ID: <20190820114706.18546-6-toke@redhat.com> (raw)
In-Reply-To: <20190820114706.18546-1-toke@redhat.com>

This switches over loading of XDP programs to the using libbpf, if it is
available. It uses the automatic pinning features added to libbpf to
construct the same pinning paths as the libelf-based loader.

Since map-in-map support has not yet been added to libbpf, this means that
map-in-map definitions will not work with this patch.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 lib/bpf.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 102 insertions(+), 13 deletions(-)

diff --git a/lib/bpf.c b/lib/bpf.c
index c6e3bd0d..de1a655a 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -938,9 +938,17 @@ static int bpf_do_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl)
 	return ret;
 }
 
+#ifdef HAVE_LIBBPF
+static int bpf_do_load_libbpf(struct bpf_cfg_in *cfg);
+#endif
+
 static int bpf_do_load(struct bpf_cfg_in *cfg)
 {
 	if (cfg->mode == EBPF_OBJECT) {
+#ifdef HAVE_LIBBPF
+		if(cfg->type == BPF_PROG_TYPE_XDP)
+			return bpf_do_load_libbpf(cfg);
+#endif
 		cfg->prog_fd = bpf_obj_open(cfg->object, cfg->type,
 					    cfg->section, cfg->ifindex,
 					    cfg->verbose);
@@ -1407,25 +1415,22 @@ static bool bpf_no_pinning(const struct bpf_elf_ctx *ctx,
 	}
 }
 
-static void bpf_make_pathname(char *pathname, size_t len, const char *name,
+static int bpf_make_pathname(char *pathname, size_t len, const char *name,
 			      const struct bpf_elf_ctx *ctx, uint32_t pinning)
 {
 	switch (pinning) {
 	case PIN_OBJECT_NS:
-		snprintf(pathname, len, "%s/%s/%s",
-			 bpf_get_work_dir(ctx->type),
-			 ctx->obj_uid, name);
-		break;
+		return snprintf(pathname, len, "%s/%s/%s",
+				bpf_get_work_dir(ctx->type),
+				ctx->obj_uid, name);
 	case PIN_GLOBAL_NS:
-		snprintf(pathname, len, "%s/%s/%s",
-			 bpf_get_work_dir(ctx->type),
-			 BPF_DIR_GLOBALS, name);
-		break;
+		return snprintf(pathname, len, "%s/%s/%s",
+				bpf_get_work_dir(ctx->type),
+				BPF_DIR_GLOBALS, name);
 	default:
-		snprintf(pathname, len, "%s/../%s/%s",
-			 bpf_get_work_dir(ctx->type),
-			 bpf_custom_pinning(ctx, pinning), name);
-		break;
+		return snprintf(pathname, len, "%s/../%s/%s",
+				bpf_get_work_dir(ctx->type),
+				bpf_custom_pinning(ctx, pinning), name);
 	}
 }
 
@@ -3160,3 +3165,87 @@ int bpf_recv_map_fds(const char *path, int *fds, struct bpf_map_aux *aux,
 	return ret;
 }
 #endif /* HAVE_ELF */
+
+#ifdef HAVE_LIBBPF
+static int bpf_gen_pin_name(void *priv, char *buf, int buf_len,
+			    const char *name, unsigned int pinning)
+{
+	struct bpf_elf_ctx *ctx = priv;
+	const char *tmp;
+	int ret = 0;
+
+	if (bpf_no_pinning(ctx, pinning) || !bpf_get_work_dir(ctx->type))
+		return 0;
+
+	if (pinning == PIN_OBJECT_NS)
+		ret = bpf_make_obj_path(ctx);
+	else if ((tmp = bpf_custom_pinning(ctx, pinning)))
+		ret = bpf_make_custom_path(ctx, tmp);
+	if (ret < 0)
+		return ret;
+
+	return bpf_make_pathname(buf, buf_len, name, ctx, pinning);
+}
+
+static int bpf_elf_ctx_init_stub(struct bpf_elf_ctx *ctx, const char *pathname,
+				 enum bpf_prog_type type, int verbose)
+{
+	uint8_t tmp[20];
+	int ret;
+
+	memset(ctx, 0, sizeof(*ctx));
+	ret = bpf_obj_hash(pathname, tmp, sizeof(tmp));
+	if (ret)
+		ctx->noafalg = true;
+	else
+		hexstring_n2a(tmp, sizeof(tmp), ctx->obj_uid,
+			      sizeof(ctx->obj_uid));
+
+	ctx->verbose = verbose;
+	ctx->type    = type;
+	bpf_hash_init(ctx, CONFDIR "/bpf_pinning");
+
+	return 0;
+}
+
+static int verbose_print(enum libbpf_print_level level, const char *format,
+			 va_list args)
+{
+	return vfprintf(stderr, format, args);
+}
+
+static int bpf_do_load_libbpf(struct bpf_cfg_in *cfg)
+{
+	struct bpf_elf_ctx *ctx = &__ctx;
+	struct bpf_program *prog;
+	struct bpf_object *obj;
+	int err, prog_fd = -1;
+
+	struct bpf_prog_load_attr attr = {
+		.file = cfg->object,
+		.prog_type = cfg->type,
+		.ifindex = cfg->ifindex,
+		.log_level = cfg->verbose,
+		.auto_pin_cb = bpf_gen_pin_name,
+		.auto_pin_ctx = ctx,
+	};
+
+	if (cfg->verbose)
+		libbpf_set_print(verbose_print);
+
+	bpf_elf_ctx_init_stub(ctx, cfg->object, cfg->type, cfg->verbose);
+
+	err = bpf_prog_load_xattr(&attr, &obj, &prog_fd);
+	if (err)
+		return err;
+
+	if (cfg->section) {
+		prog = bpf_object__find_program_by_title(obj,
+							 cfg->section);
+		prog_fd = bpf_program__fd(prog);
+	}
+
+	cfg->prog_fd = prog_fd;
+	return cfg->prog_fd;
+}
+#endif
-- 
2.22.1


  parent reply	other threads:[~2019-08-20 11:48 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-20 11:47 [RFC bpf-next 0/5] Convert iproute2 to use libbpf (WIP) Toke Høiland-Jørgensen
2019-08-20 11:47 ` [RFC bpf-next 1/5] libbpf: Add map definition struct fields from iproute2 Toke Høiland-Jørgensen
2019-08-20 11:47 ` [RFC bpf-next 2/5] libbpf: Add support for auto-pinning of maps with reuse on program load Toke Høiland-Jørgensen
2019-08-20 11:47 ` [RFC bpf-next 3/5] libbpf: Add support for specifying map pinning path via callback Toke Høiland-Jørgensen
2019-08-20 11:47 ` [RFC bpf-next 4/5] iproute2: Allow compiling against libbpf Toke Høiland-Jørgensen
2019-08-22  8:58   ` Daniel Borkmann
2019-08-22 10:43     ` Toke Høiland-Jørgensen
2019-08-22 11:45       ` Daniel Borkmann
2019-08-22 12:04         ` Toke Høiland-Jørgensen
2019-08-22 12:33           ` Daniel Borkmann
2019-08-22 13:38             ` Toke Høiland-Jørgensen
2019-08-22 13:45               ` Daniel Borkmann
2019-08-22 15:28                 ` Toke Høiland-Jørgensen
2019-08-20 11:47 ` Toke Høiland-Jørgensen [this message]
2019-08-21 19:26 ` [RFC bpf-next 0/5] Convert iproute2 to use libbpf (WIP) Alexei Starovoitov
2019-08-21 21:00   ` Toke Høiland-Jørgensen
2019-08-22  7:52     ` Andrii Nakryiko
2019-08-22 10:38       ` Toke Høiland-Jørgensen
2019-08-21 20:30 ` Andrii Nakryiko
2019-08-21 21:07   ` Toke Høiland-Jørgensen
2019-08-22  7:49     ` Andrii Nakryiko
2019-08-22  8:33       ` Daniel Borkmann
2019-08-22 11:48         ` Toke Høiland-Jørgensen
2019-08-22 11:49           ` Toke Høiland-Jørgensen
2019-08-23  6:31         ` Andrii Nakryiko
2019-08-23 11:29           ` Toke Høiland-Jørgensen
2019-08-28 20:40             ` Andrii Nakryiko
2020-02-03  7:29               ` Andrii Nakryiko
2020-02-03 19:34                 ` Toke Høiland-Jørgensen
2020-02-04  0:56                   ` Andrii Nakryiko
2020-02-04  1:46                     ` David Ahern
2020-02-04  3:41                       ` Andrii Nakryiko
2020-02-04  4:52                         ` David Ahern
2020-02-04  5:00                           ` Andrii Nakryiko
2020-02-04  8:25                             ` Toke Høiland-Jørgensen
2020-02-04 18:47                               ` Andrii Nakryiko
2020-02-04 19:19                                 ` Toke Høiland-Jørgensen
2020-02-04 19:29                                   ` Andrii Nakryiko
2020-02-04 21:56                                     ` Toke Høiland-Jørgensen
2020-02-04 22:12                                       ` David Ahern
2020-02-04 22:35                                         ` Toke Høiland-Jørgensen
2020-02-04 23:13                                           ` David Ahern
2020-02-05 10:37                                             ` Toke Høiland-Jørgensen
2020-02-04  8:27                     ` Toke Høiland-Jørgensen
2019-08-23 10:27   ` Jesper Dangaard Brouer
2019-08-28 20:23     ` Andrii Nakryiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190820114706.18546-6-toke@redhat.com \
    --to=toke@redhat.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brouer@redhat.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=kafai@fb.com \
    --cc=netdev@vger.kernel.org \
    --cc=songliubraving@fb.com \
    --cc=stephen@networkplumber.org \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).