[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210119155013.154808-7-bjorn.topel@gmail.com>
Date: Tue, 19 Jan 2021 16:50:11 +0100
From: Björn Töpel <bjorn.topel@...il.com>
To: ast@...nel.org, daniel@...earbox.net, netdev@...r.kernel.org,
bpf@...r.kernel.org
Cc: Björn Töpel <bjorn.topel@...el.com>,
magnus.karlsson@...el.com, maciej.fijalkowski@...el.com,
kuba@...nel.org, jonathan.lemon@...il.com, maximmi@...dia.com,
davem@...emloft.net, hawk@...nel.org, john.fastabend@...il.com,
ciara.loftus@...el.com, weqaar.a.janjua@...el.com
Subject: [PATCH bpf-next v2 6/8] libbpf, xsk: select bpf_redirect_xsk(), if supported
From: Björn Töpel <bjorn.topel@...el.com>
Select bpf_redirect_xsk() as the default AF_XDP BPF program, if
supported.
The bpf_redirect_xsk() helper does not require an XSKMAP, so make sure
that no map is created/updated when using it.
Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@...el.com>
Signed-off-by: Björn Töpel <bjorn.topel@...el.com>
---
tools/lib/bpf/xsk.c | 46 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 42 insertions(+), 4 deletions(-)
diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c
index c8642c6cb5d6..27e36d6d92a6 100644
--- a/tools/lib/bpf/xsk.c
+++ b/tools/lib/bpf/xsk.c
@@ -47,9 +47,12 @@
#define PF_XDP AF_XDP
#endif
+#define XSKMAP_NOT_NEEDED -1
+
enum xsk_prog {
XSK_PROG_FALLBACK,
XSK_PROG_REDIRECT_FLAGS,
+ XSK_PROG_REDIRECT_XSK,
};
struct xsk_umem {
@@ -361,7 +364,11 @@ static enum xsk_prog get_xsk_prog(void)
{
__u32 kver = get_kernel_version();
- return kver < KERNEL_VERSION(5, 3, 0) ? XSK_PROG_FALLBACK : XSK_PROG_REDIRECT_FLAGS;
+ if (kver < KERNEL_VERSION(5, 3, 0))
+ return XSK_PROG_FALLBACK;
+ if (kver < KERNEL_VERSION(5, 12, 0))
+ return XSK_PROG_REDIRECT_FLAGS;
+ return XSK_PROG_REDIRECT_XSK;
}
static int xsk_load_xdp_prog(struct xsk_socket *xsk)
@@ -445,10 +452,25 @@ static int xsk_load_xdp_prog(struct xsk_socket *xsk)
BPF_EMIT_CALL(BPF_FUNC_redirect_map),
BPF_EXIT_INSN(),
};
+
+ /* This is the post-5.12 kernel C-program:
+ * SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
+ * {
+ * return bpf_redirect_xsk(ctx, XDP_PASS);
+ * }
+ */
+ struct bpf_insn prog_redirect_xsk[] = {
+ /* r2 = XDP_PASS */
+ BPF_MOV64_IMM(BPF_REG_2, 2),
+ /* call bpf_redirect_xsk */
+ BPF_EMIT_CALL(BPF_FUNC_redirect_xsk),
+ BPF_EXIT_INSN(),
+ };
size_t insns_cnt[] = {sizeof(prog) / sizeof(struct bpf_insn),
sizeof(prog_redirect_flags) / sizeof(struct bpf_insn),
+ sizeof(prog_redirect_xsk) / sizeof(struct bpf_insn),
};
- struct bpf_insn *progs[] = {prog, prog_redirect_flags};
+ struct bpf_insn *progs[] = {prog, prog_redirect_flags, prog_redirect_xsk};
enum xsk_prog option = get_xsk_prog();
prog_fd = bpf_load_program(BPF_PROG_TYPE_XDP, progs[option], insns_cnt[option],
@@ -508,12 +530,22 @@ static int xsk_get_max_queues(struct xsk_socket *xsk)
return ret;
}
+static bool xskmap_required(void)
+{
+ return get_xsk_prog() != XSK_PROG_REDIRECT_XSK;
+}
+
static int xsk_create_bpf_maps(struct xsk_socket *xsk)
{
struct xsk_ctx *ctx = xsk->ctx;
int max_queues;
int fd;
+ if (!xskmap_required()) {
+ ctx->xsks_map_fd = XSKMAP_NOT_NEEDED;
+ return 0;
+ }
+
max_queues = xsk_get_max_queues(xsk);
if (max_queues < 0)
return max_queues;
@@ -532,6 +564,9 @@ static void xsk_delete_bpf_maps(struct xsk_socket *xsk)
{
struct xsk_ctx *ctx = xsk->ctx;
+ if (ctx->xsks_map_fd == XSKMAP_NOT_NEEDED)
+ return;
+
bpf_map_delete_elem(ctx->xsks_map_fd, &ctx->queue_id);
close(ctx->xsks_map_fd);
}
@@ -563,7 +598,7 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
if (err)
goto out_map_ids;
- ctx->xsks_map_fd = -1;
+ ctx->xsks_map_fd = XSKMAP_NOT_NEEDED;
for (i = 0; i < prog_info.nr_map_ids; i++) {
fd = bpf_map_get_fd_by_id(map_ids[i]);
@@ -585,7 +620,7 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
}
err = 0;
- if (ctx->xsks_map_fd == -1)
+ if (ctx->xsks_map_fd == XSKMAP_NOT_NEEDED && xskmap_required())
err = -ENOENT;
out_map_ids:
@@ -597,6 +632,9 @@ static int xsk_set_bpf_maps(struct xsk_socket *xsk)
{
struct xsk_ctx *ctx = xsk->ctx;
+ if (ctx->xsks_map_fd == XSKMAP_NOT_NEEDED)
+ return 0;
+
return bpf_map_update_elem(ctx->xsks_map_fd, &ctx->queue_id,
&xsk->fd, 0);
}
--
2.27.0
Powered by blists - more mailing lists