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:   Sat, 24 Dec 2022 00:40:15 +0100
From:   Quentin Deslandes <qde@...cy.de>
To:     <qde@...cy.de>
CC:     <kernel-team@...a.com>, Dmitrii Banshchikov <me@...que.spb.ru>,
        Alexei Starovoitov <ast@...nel.org>,
        Daniel Borkmann <daniel@...earbox.net>,
        Andrii Nakryiko <andrii@...nel.org>,
        Martin KaFai Lau <martin.lau@...ux.dev>,
        Song Liu <song@...nel.org>, Yonghong Song <yhs@...com>,
        John Fastabend <john.fastabend@...il.com>,
        KP Singh <kpsingh@...nel.org>,
        Stanislav Fomichev <sdf@...gle.com>,
        Hao Luo <haoluo@...gle.com>, Jiri Olsa <jolsa@...nel.org>,
        "David S. Miller" <davem@...emloft.net>,
        Eric Dumazet <edumazet@...gle.com>,
        Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni <pabeni@...hat.com>,
        Mykola Lysenko <mykolal@...com>, Shuah Khan <shuah@...nel.org>,
        <linux-kernel@...r.kernel.org>, <bpf@...r.kernel.org>,
        <netdev@...r.kernel.org>, <linux-kselftest@...r.kernel.org>
Subject: [PATCH bpf-next v3 07/16] bpfilter: add support for TC bytecode generation

Add code generation support for TC hooks.

Co-developed-by: Dmitrii Banshchikov <me@...que.spb.ru>
Signed-off-by: Dmitrii Banshchikov <me@...que.spb.ru>
Signed-off-by: Quentin Deslandes <qde@...cy.de>
---
 net/bpfilter/codegen.c | 151 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 151 insertions(+)

diff --git a/net/bpfilter/codegen.c b/net/bpfilter/codegen.c
index 545bc7aeb77c..e7ae7dfa5118 100644
--- a/net/bpfilter/codegen.c
+++ b/net/bpfilter/codegen.c
@@ -8,6 +8,8 @@
 
 #include "../../include/uapi/linux/bpfilter.h"
 
+#include <linux/pkt_cls.h>
+
 #include <unistd.h>
 #include <sys/syscall.h>
 
@@ -15,6 +17,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <bpf/libbpf.h>
+
 #include "logger.h"
 
 enum fixup_insn_type {
@@ -390,6 +394,150 @@ static void unload_maps(struct codegen *codegen)
 	}
 }
 
+static int tc_gen_inline_prologue(struct codegen *codegen)
+{
+	EMIT(codegen, BPF_MOV64_REG(CODEGEN_REG_CTX, BPF_REG_ARG1));
+	EMIT(codegen, BPF_MOV64_REG(CODEGEN_REG_RUNTIME_CTX, BPF_REG_FP));
+	EMIT(codegen, BPF_MOV32_IMM(CODEGEN_REG_RETVAL, TC_ACT_OK));
+
+	return 0;
+}
+
+static int tc_load_packet_data(struct codegen *codegen, int dst_reg)
+{
+	EMIT(codegen, BPF_LDX_MEM(BPF_W, dst_reg, CODEGEN_REG_CTX,
+				  offsetof(struct __sk_buff, data)));
+
+	return 0;
+}
+
+static int tc_load_packet_data_end(struct codegen *codegen, int dst_reg)
+{
+	EMIT(codegen, BPF_LDX_MEM(BPF_W, CODEGEN_REG_DATA_END, CODEGEN_REG_CTX,
+				  offsetof(struct __sk_buff, data_end)));
+
+	return 0;
+}
+
+static int tc_emit_ret_code(struct codegen *codegen, int ret_code)
+{
+	int tc_ret_code;
+
+	if (ret_code == BPFILTER_NF_ACCEPT)
+		tc_ret_code = TC_ACT_UNSPEC;
+	else if (ret_code == BPFILTER_NF_DROP)
+		tc_ret_code = TC_ACT_SHOT;
+	else
+		return -EINVAL;
+
+	EMIT(codegen, BPF_MOV32_IMM(BPF_REG_0, tc_ret_code));
+
+	return 0;
+}
+
+static int tc_gen_inline_epilogue(struct codegen *codegen)
+{
+	EMIT(codegen, BPF_EXIT_INSN());
+
+	return 0;
+}
+
+struct tc_img_ctx {
+	int fd;
+	struct bpf_tc_hook hook;
+	struct bpf_tc_opts opts;
+};
+
+static int tc_load_img(struct codegen *codegen)
+{
+	struct tc_img_ctx *img_ctx;
+	int fd;
+	int r;
+
+	if (codegen->img_ctx) {
+		BFLOG_ERR("TC context missing from codegen");
+		return -EINVAL;
+	}
+
+	img_ctx = calloc(1, sizeof(*img_ctx));
+	if (!img_ctx) {
+		BFLOG_ERR("out of memory");
+		return -ENOMEM;
+	}
+
+	img_ctx->hook.sz = sizeof(img_ctx->hook);
+	img_ctx->hook.ifindex = 2;
+	img_ctx->hook.attach_point = codegen->bpf_tc_hook;
+
+	fd = load_img(codegen);
+	if (fd < 0) {
+		BFLOG_ERR("failed to load TC codegen image: %s", STRERR(fd));
+		r = fd;
+		goto err_free;
+	}
+
+	r = bpf_tc_hook_create(&img_ctx->hook);
+	if (r && r != -EEXIST) {
+		BFLOG_ERR("failed to create TC hook: %s\n", STRERR(r));
+		goto err_free;
+	}
+
+	img_ctx->opts.sz = sizeof(img_ctx->opts);
+	img_ctx->opts.handle = codegen->iptables_hook;
+	img_ctx->opts.priority = 0;
+	img_ctx->opts.prog_fd = fd;
+	r = bpf_tc_attach(&img_ctx->hook, &img_ctx->opts);
+	if (r) {
+		BFLOG_ERR("failed to attach TC program: %s", STRERR(r));
+		goto err_free;
+	}
+
+	img_ctx->fd = fd;
+	codegen->img_ctx = img_ctx;
+
+	return fd;
+
+err_free:
+	if (fd > -1)
+		close(fd);
+	free(img_ctx);
+	return r;
+}
+
+static void tc_unload_img(struct codegen *codegen)
+{
+	struct tc_img_ctx *img_ctx;
+	int r;
+
+	BUG_ON(!codegen->img_ctx);
+
+	img_ctx = (struct tc_img_ctx *)codegen->img_ctx;
+	img_ctx->opts.flags = 0;
+	img_ctx->opts.prog_fd = 0;
+	img_ctx->opts.prog_id = 0;
+	r = bpf_tc_detach(&img_ctx->hook, &img_ctx->opts);
+	if (r)
+		BFLOG_EMERG("failed to detach TC program: %s", STRERR(r));
+
+	BUG_ON(img_ctx->fd < 0);
+	close(img_ctx->fd);
+	free(img_ctx);
+
+	codegen->img_ctx = NULL;
+
+	unload_img(codegen);
+}
+
+static const struct codegen_ops tc_codegen_ops = {
+	.gen_inline_prologue = tc_gen_inline_prologue,
+	.load_packet_data = tc_load_packet_data,
+	.load_packet_data_end = tc_load_packet_data_end,
+	.emit_ret_code = tc_emit_ret_code,
+	.gen_inline_epilogue = tc_gen_inline_epilogue,
+	.load_img = tc_load_img,
+	.unload_img = tc_unload_img,
+};
+
 void create_shared_codegen(struct shared_codegen *shared_codegen)
 {
 	shared_codegen->maps_refcnt = 0;
@@ -413,6 +561,9 @@ int create_codegen(struct codegen *codegen, enum bpf_prog_type type)
 	memset(codegen, 0, sizeof(*codegen));
 
 	switch (type) {
+	case BPF_PROG_TYPE_SCHED_CLS:
+		codegen->codegen_ops = &tc_codegen_ops;
+		break;
 	default:
 		BFLOG_ERR("unsupported BPF program type %d", type);
 		return -EINVAL;
-- 
2.38.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ