All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC nf-next 0/3] bpf, netfilter: minimal support for bpf progs
@ 2023-02-08 16:03 Florian Westphal
  2023-02-08 16:03 ` [RFC nf-next 1/3] bpf: add bpf_link support for BPF_NETFILTER programs Florian Westphal
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Florian Westphal @ 2023-02-08 16:03 UTC (permalink / raw)
  To: bpf; +Cc: netfilter-devel, Florian Westphal

Add minimal support to hook bpf programs to netfilter hooks,
e.g. PREROUTING or FORWARD.

Hooking is currently possible for all supprted protocols, i.e.
arp, bridge, ip, ip6 and inet (both ipv4/ipv6) pseudo-family.

For this the most relevant parts for registering a netfilter
hook via the in-kernel api are exposed to userspace via bpf_link.

With this its possible to build a small test program such as:

SEC("netfilter")
int nf_test(struct __sk_buff *skb)
{
	const struct iphdr *iph = (void *)skb->data;

	if (iph + 1 < skb->data_end)
		bpf_printk("%x,%x\n", iph->saddr, iph->daddr);
	else
		return NF_DROP;

        return NF_ACCEPT;
}

(output can be observed via /sys/kernel/tracing/trace_pipe).

The prototype is wrong, future versions will instead expose
'struct bpf_nf_ctx' via btf, so programs will have to use

SEC("netfilter")
int nf_test(struct bpf_nf_ctx *ctx)
{
	struct sk_buff *skb = ctx->skb; ...


I will work on this next but thought it was better to send
a current snapshot.

This series no longer depends on the proposed in-kernel
nf_hook_slow bpf translator.

Feedback welcome.

Florian Westphal (3):
  bpf: add bpf_link support for BPF_NETFILTER programs
  libbpf: sync header file, add nf prog section name
  bpf: minimal support for programs hooked into netfilter framework

 include/linux/bpf_types.h           |   4 +
 include/linux/netfilter.h           |   1 +
 include/net/netfilter/nf_hook_bpf.h |  10 ++
 include/uapi/linux/bpf.h            |  13 ++
 kernel/bpf/btf.c                    |   3 +
 kernel/bpf/syscall.c                |   7 +
 kernel/bpf/verifier.c               |   3 +
 net/netfilter/Kconfig               |   3 +
 net/netfilter/Makefile              |   1 +
 net/netfilter/nf_bpf_link.c         | 242 ++++++++++++++++++++++++++++
 tools/include/uapi/linux/bpf.h      |  13 ++
 tools/lib/bpf/libbpf.c              |   1 +
 12 files changed, 301 insertions(+)
 create mode 100644 include/net/netfilter/nf_hook_bpf.h
 create mode 100644 net/netfilter/nf_bpf_link.c

-- 
2.39.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC nf-next 1/3] bpf: add bpf_link support for BPF_NETFILTER programs
  2023-02-08 16:03 [RFC nf-next 0/3] bpf, netfilter: minimal support for bpf progs Florian Westphal
@ 2023-02-08 16:03 ` Florian Westphal
  2023-02-08 16:03 ` [RFC nf-next 2/3] libbpf: sync header file, add nf prog section name Florian Westphal
  2023-02-08 16:03 ` [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework Florian Westphal
  2 siblings, 0 replies; 6+ messages in thread
From: Florian Westphal @ 2023-02-08 16:03 UTC (permalink / raw)
  To: bpf; +Cc: netfilter-devel, Florian Westphal

Add bpf_link support skeleton.  To keep this reviewable, no bpf program
can be invoked here, if a program would be attached only a c-stub is called.

This defaults to 'y' if both netfilter and bpf syscall are enabled in
kconfig.

Uapi example usage:
	union bpf_attr attr = { };

	attr.link_create.prog_fd = progfd;
	attr.link_create.attach_type = BPF_NETFILTER;
	attr.link_create.netfilter.pf = PF_INET;
	attr.link_create.netfilter.hooknum = NF_INET_LOCAL_IN;
	attr.link_create.netfilter.priority = -128;

	err = bpf(BPF_LINK_CREATE, &attr, sizeof(attr));

... this would attach progfd to ipv4:input hook.

Such hook gets removed automatically if the calling program exits.

BPF_NETFILTER program invocation is added in followup change.

NF_HOOK_OP_BPF enum will eventually be read from nfnetlink_hook, it
allows to tell userspace which program is attached at the given hook
when user runs 'nft hook list' command rather than just the priority
and not-very-helpful 'this hook runs a bpf prog but I can't tell which
one'.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/linux/netfilter.h           |   1 +
 include/net/netfilter/nf_hook_bpf.h |   2 +
 include/uapi/linux/bpf.h            |  13 ++++
 kernel/bpf/syscall.c                |   7 ++
 net/netfilter/Kconfig               |   3 +
 net/netfilter/Makefile              |   1 +
 net/netfilter/nf_bpf_link.c         | 116 ++++++++++++++++++++++++++++
 7 files changed, 143 insertions(+)
 create mode 100644 include/net/netfilter/nf_hook_bpf.h
 create mode 100644 net/netfilter/nf_bpf_link.c

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index d8817d381c14..c5d51c389fd4 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -80,6 +80,7 @@ typedef unsigned int nf_hookfn(void *priv,
 enum nf_hook_ops_type {
 	NF_HOOK_OP_UNDEFINED,
 	NF_HOOK_OP_NF_TABLES,
+	NF_HOOK_OP_BPF,
 };
 
 struct nf_hook_ops {
diff --git a/include/net/netfilter/nf_hook_bpf.h b/include/net/netfilter/nf_hook_bpf.h
new file mode 100644
index 000000000000..9d1b338e89d7
--- /dev/null
+++ b/include/net/netfilter/nf_hook_bpf.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index ba0f0cfb5e42..ff2fccef91af 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -986,6 +986,7 @@ enum bpf_prog_type {
 	BPF_PROG_TYPE_LSM,
 	BPF_PROG_TYPE_SK_LOOKUP,
 	BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */
+	BPF_PROG_TYPE_NETFILTER,
 };
 
 enum bpf_attach_type {
@@ -1033,6 +1034,7 @@ enum bpf_attach_type {
 	BPF_PERF_EVENT,
 	BPF_TRACE_KPROBE_MULTI,
 	BPF_LSM_CGROUP,
+	BPF_NETFILTER,
 	__MAX_BPF_ATTACH_TYPE
 };
 
@@ -1049,6 +1051,7 @@ enum bpf_link_type {
 	BPF_LINK_TYPE_PERF_EVENT = 7,
 	BPF_LINK_TYPE_KPROBE_MULTI = 8,
 	BPF_LINK_TYPE_STRUCT_OPS = 9,
+	BPF_LINK_TYPE_NETFILTER = 10,
 
 	MAX_BPF_LINK_TYPE,
 };
@@ -1543,6 +1546,11 @@ union bpf_attr {
 				 */
 				__u64		cookie;
 			} tracing;
+			struct {
+				__u32		pf;
+				__u32		hooknum;
+				__s32		prio;
+			} netfilter;
 		};
 	} link_create;
 
@@ -6354,6 +6362,11 @@ struct bpf_link_info {
 		struct {
 			__u32 ifindex;
 		} xdp;
+		struct {
+			__u32 pf;
+			__u32 hooknum;
+			__s32 priority;
+		} netfilter;
 	};
 } __attribute__((aligned(8)));
 
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 99417b387547..f3e7aae44c6a 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -35,6 +35,7 @@
 #include <linux/rcupdate_trace.h>
 #include <linux/memcontrol.h>
 #include <linux/trace_events.h>
+#include <net/netfilter/nf_hook_bpf.h>
 
 #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
 			  (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
@@ -2433,6 +2434,7 @@ static bool is_net_admin_prog_type(enum bpf_prog_type prog_type)
 	case BPF_PROG_TYPE_CGROUP_SYSCTL:
 	case BPF_PROG_TYPE_SOCK_OPS:
 	case BPF_PROG_TYPE_EXT: /* extends any prog */
+	case BPF_PROG_TYPE_NETFILTER:
 		return true;
 	case BPF_PROG_TYPE_CGROUP_SKB:
 		/* always unpriv */
@@ -3460,6 +3462,8 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
 		return BPF_PROG_TYPE_XDP;
 	case BPF_LSM_CGROUP:
 		return BPF_PROG_TYPE_LSM;
+	case BPF_NETFILTER:
+		return BPF_PROG_TYPE_NETFILTER;
 	default:
 		return BPF_PROG_TYPE_UNSPEC;
 	}
@@ -4613,6 +4617,9 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
 	case BPF_PROG_TYPE_XDP:
 		ret = bpf_xdp_link_attach(attr, prog);
 		break;
+	case BPF_PROG_TYPE_NETFILTER:
+		ret = bpf_nf_link_attach(attr, prog);
+		break;
 #endif
 	case BPF_PROG_TYPE_PERF_EVENT:
 	case BPF_PROG_TYPE_TRACEPOINT:
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index f71b41c7ce2f..237f3d411164 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -30,6 +30,9 @@ config NETFILTER_FAMILY_BRIDGE
 config NETFILTER_FAMILY_ARP
 	bool
 
+config NETFILTER_BPF_LINK
+	def_bool BPF_SYSCALL
+
 config NETFILTER_NETLINK_HOOK
 	tristate "Netfilter base hook dump support"
 	depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index ba2a6b5e93d9..ca12f559a04d 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -21,6 +21,7 @@ nf_conntrack-$(CONFIG_DEBUG_INFO_BTF) += nf_conntrack_bpf.o
 endif
 
 obj-$(CONFIG_NETFILTER) = netfilter.o
+obj-$(CONFIG_NETFILTER_BPF_LINK) += nf_bpf_link.o
 
 obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
 obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
diff --git a/net/netfilter/nf_bpf_link.c b/net/netfilter/nf_bpf_link.c
new file mode 100644
index 000000000000..fa4fae5cc669
--- /dev/null
+++ b/net/netfilter/nf_bpf_link.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <linux/netfilter.h>
+
+#include <net/netfilter/nf_hook_bpf.h>
+
+static unsigned int nf_hook_run_bpf(void *bpf_prog, struct sk_buff *skb, const struct nf_hook_state *s)
+{
+	return NF_ACCEPT;
+}
+
+struct bpf_nf_link {
+	struct bpf_link link;
+	struct nf_hook_ops hook_ops;
+	struct net *net;
+};
+
+static void bpf_nf_link_release(struct bpf_link *link)
+{
+	struct bpf_nf_link *nf_link = container_of(link, struct bpf_nf_link, link);
+
+	nf_unregister_net_hook(nf_link->net, &nf_link->hook_ops);
+}
+
+static void bpf_nf_link_dealloc(struct bpf_link *link)
+{
+	struct bpf_nf_link *nf_link = container_of(link, struct bpf_nf_link, link);
+
+	kfree(nf_link);
+}
+
+static int bpf_nf_link_detach(struct bpf_link *link)
+{
+	bpf_nf_link_release(link);
+	return 0;
+}
+
+static void bpf_nf_link_show_info(const struct bpf_link *link,
+				  struct seq_file *seq)
+{
+	struct bpf_nf_link *nf_link = container_of(link, struct bpf_nf_link, link);
+
+	seq_printf(seq, "pf:\t%u\thooknum:\t%u\tprio:\t%d\n",
+		  nf_link->hook_ops.pf, nf_link->hook_ops.hooknum,
+		  nf_link->hook_ops.priority);
+}
+
+static int bpf_nf_link_fill_link_info(const struct bpf_link *link,
+				      struct bpf_link_info *info)
+{
+	struct bpf_nf_link *nf_link = container_of(link, struct bpf_nf_link, link);
+
+	info->netfilter.pf = nf_link->hook_ops.pf;
+	info->netfilter.hooknum = nf_link->hook_ops.hooknum;
+	info->netfilter.priority = nf_link->hook_ops.priority;
+
+	return 0;
+}
+
+static int bpf_nf_link_update(struct bpf_link *link, struct bpf_prog *new_prog,
+			      struct bpf_prog *old_prog)
+{
+	return -EOPNOTSUPP;
+}
+
+static const struct bpf_link_ops bpf_nf_link_lops = {
+	.release = bpf_nf_link_release,
+	.dealloc = bpf_nf_link_dealloc,
+	.detach = bpf_nf_link_detach,
+	.show_fdinfo = bpf_nf_link_show_info,
+	.fill_link_info = bpf_nf_link_fill_link_info,
+	.update_prog = bpf_nf_link_update,
+};
+
+int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
+{
+	struct net *net = current->nsproxy->net_ns;
+	struct bpf_link_primer link_primer;
+	struct bpf_nf_link *link;
+	int err;
+
+	if (attr->link_create.flags)
+		return -EINVAL;
+
+	link = kzalloc(sizeof(*link), GFP_USER);
+	if (!link)
+		return -ENOMEM;
+
+	bpf_link_init(&link->link, BPF_LINK_TYPE_NETFILTER, &bpf_nf_link_lops, prog);
+
+	link->hook_ops.hook = nf_hook_run_bpf;
+	link->hook_ops.hook_ops_type = NF_HOOK_OP_BPF;
+	link->hook_ops.priv = prog;
+
+	link->hook_ops.pf = attr->link_create.netfilter.pf;
+	link->hook_ops.priority = attr->link_create.netfilter.prio;
+	link->hook_ops.hooknum = attr->link_create.netfilter.hooknum;
+
+	link->net = net;
+
+	err = bpf_link_prime(&link->link, &link_primer);
+	if (err)
+		goto out_free;
+
+	err = nf_register_net_hook(net, &link->hook_ops);
+	if (err) {
+		bpf_link_cleanup(&link_primer);
+		goto out_free;
+	}
+
+	return bpf_link_settle(&link_primer);
+
+out_free:
+	kfree(link);
+	return err;
+}
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC nf-next 2/3] libbpf: sync header file, add nf prog section name
  2023-02-08 16:03 [RFC nf-next 0/3] bpf, netfilter: minimal support for bpf progs Florian Westphal
  2023-02-08 16:03 ` [RFC nf-next 1/3] bpf: add bpf_link support for BPF_NETFILTER programs Florian Westphal
@ 2023-02-08 16:03 ` Florian Westphal
  2023-02-08 16:03 ` [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework Florian Westphal
  2 siblings, 0 replies; 6+ messages in thread
From: Florian Westphal @ 2023-02-08 16:03 UTC (permalink / raw)
  To: bpf; +Cc: netfilter-devel, Florian Westphal

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 tools/include/uapi/linux/bpf.h | 13 +++++++++++++
 tools/lib/bpf/libbpf.c         |  1 +
 2 files changed, 14 insertions(+)

diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 7f024ac22edd..c4d548b6b86d 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -986,6 +986,7 @@ enum bpf_prog_type {
 	BPF_PROG_TYPE_LSM,
 	BPF_PROG_TYPE_SK_LOOKUP,
 	BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */
+	BPF_PROG_TYPE_NETFILTER,
 };
 
 enum bpf_attach_type {
@@ -1033,6 +1034,7 @@ enum bpf_attach_type {
 	BPF_PERF_EVENT,
 	BPF_TRACE_KPROBE_MULTI,
 	BPF_LSM_CGROUP,
+	BPF_NETFILTER,
 	__MAX_BPF_ATTACH_TYPE
 };
 
@@ -1049,6 +1051,7 @@ enum bpf_link_type {
 	BPF_LINK_TYPE_PERF_EVENT = 7,
 	BPF_LINK_TYPE_KPROBE_MULTI = 8,
 	BPF_LINK_TYPE_STRUCT_OPS = 9,
+	BPF_LINK_TYPE_NETFILTER = 10,
 
 	MAX_BPF_LINK_TYPE,
 };
@@ -1543,6 +1546,11 @@ union bpf_attr {
 				 */
 				__u64		cookie;
 			} tracing;
+			struct {
+				__u32		pf;
+				__u32		hooknum;
+				__s32		prio;
+			} netfilter;
 		};
 	} link_create;
 
@@ -6354,6 +6362,11 @@ struct bpf_link_info {
 		struct {
 			__u32 ifindex;
 		} xdp;
+		struct {
+			__u32 pf;
+			__u32 hooknum;
+			__s32 priority;
+		} netfilter;
 	};
 } __attribute__((aligned(8)));
 
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index eed5cec6f510..525bc2b2c95c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -8607,6 +8607,7 @@ static const struct bpf_sec_def section_defs[] = {
 	SEC_DEF("struct_ops+",		STRUCT_OPS, 0, SEC_NONE),
 	SEC_DEF("struct_ops.s+",	STRUCT_OPS, 0, SEC_SLEEPABLE),
 	SEC_DEF("sk_lookup",		SK_LOOKUP, BPF_SK_LOOKUP, SEC_ATTACHABLE),
+	SEC_DEF("netfilter",		NETFILTER, BPF_NETFILTER, SEC_ATTACHABLE),
 };
 
 static size_t custom_sec_def_cnt;
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework
  2023-02-08 16:03 [RFC nf-next 0/3] bpf, netfilter: minimal support for bpf progs Florian Westphal
  2023-02-08 16:03 ` [RFC nf-next 1/3] bpf: add bpf_link support for BPF_NETFILTER programs Florian Westphal
  2023-02-08 16:03 ` [RFC nf-next 2/3] libbpf: sync header file, add nf prog section name Florian Westphal
@ 2023-02-08 16:03 ` Florian Westphal
  2023-02-08 19:11   ` kernel test robot
  2 siblings, 1 reply; 6+ messages in thread
From: Florian Westphal @ 2023-02-08 16:03 UTC (permalink / raw)
  To: bpf; +Cc: netfilter-devel, Florian Westphal

Not for merging: has problems.

This adds minimal support for BPF_PROG_TYPE_NETFILTER bpf programs
that will be invoked via the NF_HOOK() points in the ip(6) stack.

Invocation incurs an indirect call.  This is not a necessity: Its
possible to add 'DEFINE_BPF_DISPATCHER(nf_progs)' and handle the
program invocation with the same method already done for xdp progs.

This isn't done here to keep the size of this chunk down.

Verifier will reject programs that don't return either DROP or ACCEPT
verdicts.

Programs currently pretend they have prototype

  func(struct __sk_buff *skb)

with rewrite via verifier, but this will be changed to native kernel struct, i.e.:

  func(struct bpf_nf_ctx *ctx)

Instead of direct packet access, plan is to have programs use upcoming
'dynptr' api.

For 'traditional' netfilter (c-functions), skb->data is only guaranteed
to be linear for the ip/ip6 header, for everything else
skb_header_pointer is mandatory.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/linux/bpf_types.h           |   4 +
 include/net/netfilter/nf_hook_bpf.h |   8 ++
 kernel/bpf/btf.c                    |   3 +
 kernel/bpf/verifier.c               |   3 +
 net/netfilter/nf_bpf_link.c         | 128 +++++++++++++++++++++++++++-
 5 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index d4ee3ccd3753..ecc7444b31d4 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -77,6 +77,10 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_LSM, lsm,
 	       void *, void *)
 #endif /* CONFIG_BPF_LSM */
 #endif
+#ifdef CONFIG_NETFILTER
+BPF_PROG_TYPE(BPF_PROG_TYPE_NETFILTER, netfilter,
+	      struct __sk_buff, struct bpf_nf_ctx)
+#endif
 BPF_PROG_TYPE(BPF_PROG_TYPE_SYSCALL, bpf_syscall,
 	      void *, void *)
 
diff --git a/include/net/netfilter/nf_hook_bpf.h b/include/net/netfilter/nf_hook_bpf.h
index 9d1b338e89d7..cf02e8394598 100644
--- a/include/net/netfilter/nf_hook_bpf.h
+++ b/include/net/netfilter/nf_hook_bpf.h
@@ -1,2 +1,10 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+
+struct bpf_nf_ctx {
+	const struct nf_hook_state *state;
+	const struct sk_buff *skb;
+	const void *data;
+	const void *data_end;
+};
+
 int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 47b8cb96f2c2..07339c81d9f1 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -25,6 +25,9 @@
 #include <linux/bsearch.h>
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
+
+#include <net/netfilter/nf_hook_bpf.h>
+
 #include <net/sock.h>
 #include "../tools/lib/bpf/relo_core.h"
 
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 0973660a30ec..e63ecbb69250 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -12547,6 +12547,9 @@ static int check_return_code(struct bpf_verifier_env *env)
 		}
 		break;
 
+	case BPF_PROG_TYPE_NETFILTER:
+		range = tnum_range(NF_DROP, NF_ACCEPT);
+		break;
 	case BPF_PROG_TYPE_EXT:
 		/* freplace program can return anything as its return value
 		 * depends on the to-be-replaced kernel func or bpf program.
diff --git a/net/netfilter/nf_bpf_link.c b/net/netfilter/nf_bpf_link.c
index fa4fae5cc669..98a6f7dc05e2 100644
--- a/net/netfilter/nf_bpf_link.c
+++ b/net/netfilter/nf_bpf_link.c
@@ -1,12 +1,21 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/bpf.h>
+#include <linux/filter.h>
 #include <linux/netfilter.h>
 
 #include <net/netfilter/nf_hook_bpf.h>
 
 static unsigned int nf_hook_run_bpf(void *bpf_prog, struct sk_buff *skb, const struct nf_hook_state *s)
 {
-	return NF_ACCEPT;
+	const struct bpf_prog *prog = bpf_prog;
+	struct bpf_nf_ctx ctx = {
+		.state = s,
+		.skb = skb,
+		.data = skb->data,
+		.data_end = skb->data + skb_headlen(skb),
+	};
+
+	return bpf_prog_run(prog, &ctx);
 }
 
 struct bpf_nf_link {
@@ -114,3 +123,120 @@ int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
 	kfree(link);
 	return err;
 }
+
+static int bpf_prog_test_run_nf(struct bpf_prog *prog,
+				const union bpf_attr *kattr,
+				union bpf_attr __user *uattr)
+{
+	return -EOPNOTSUPP;
+}
+
+const struct bpf_prog_ops netfilter_prog_ops = {
+	.test_run		= bpf_prog_test_run_nf,
+};
+
+static u32 nf_convert_ctx_access(enum bpf_access_type type,
+				  const struct bpf_insn *si,
+				  struct bpf_insn *insn_buf,
+				  struct bpf_prog *prog, u32 *target_size)
+{
+	struct bpf_insn *insn = insn_buf;
+
+	switch (si->off) {
+	case offsetof(struct __sk_buff, data):
+		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_nf_ctx, data),
+				      si->dst_reg, si->src_reg,
+				      offsetof(struct bpf_nf_ctx, data));
+		break;
+	case offsetof(struct __sk_buff, data_end):
+		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_nf_ctx, data_end),
+				      si->dst_reg, si->src_reg,
+				      offsetof(struct bpf_nf_ctx, data_end));
+		break;
+	}
+
+	return insn - insn_buf;
+}
+
+static bool nf_is_valid_access(int off, int size, enum bpf_access_type type,
+			       const struct bpf_prog *prog,
+			       struct bpf_insn_access_aux *info)
+{
+	if (off < 0 || off >= sizeof(struct __sk_buff))
+		return false;
+
+	if (type == BPF_WRITE)
+		return false;
+
+	switch (off) {
+	case bpf_ctx_range(struct __sk_buff, data):
+		if (size != sizeof(u32))
+			return false;
+		info->reg_type = PTR_TO_PACKET;
+		return true;
+	case bpf_ctx_range(struct __sk_buff, data_end):
+		if (size != sizeof(u32))
+			return false;
+		info->reg_type = PTR_TO_PACKET_END;
+		return true;
+	default:
+		return false;
+	}
+
+	return false;
+}
+
+static const struct bpf_func_proto *
+bpf_nf_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
+{
+	return bpf_base_func_proto(func_id);
+}
+
+const struct bpf_verifier_ops netfilter_verifier_ops = {
+	.is_valid_access	= nf_is_valid_access,
+	.convert_ctx_access	= nf_convert_ctx_access,
+	.get_func_proto		= bpf_nf_func_proto,
+};
+
+__diag_push();
+__diag_ignore_all("-Wmissing-prototypes",
+		  "kfuncs which will be used in BPF programs");
+
+/* bpf_nf_hook_state_ctx_get - get nf_hook_state context structure
+ *
+ * Get the real nf_hook_state context structure.
+ *
+ *
+ */
+const struct nf_hook_state *bpf_nf_hook_state_ctx_get(struct __sk_buff *s)
+{
+	return (const struct nf_hook_state *)s;
+}
+
+int bpf_xt_change_status(struct nf_conn *nfct, u32 status)
+{
+	return 1;
+}
+
+__diag_pop()
+
+BTF_SET8_START(nf_hook_kfunc_set)
+BTF_ID_FLAGS(func, bpf_nf_hook_state_ctx_get, 0)
+BTF_ID_FLAGS(func, bpf_xt_change_status, KF_TRUSTED_ARGS)
+BTF_SET8_END(nf_hook_kfunc_set)
+
+static const struct btf_kfunc_id_set nf_basehook_kfunc_set = {
+	.owner = THIS_MODULE,
+	.set   = &nf_hook_kfunc_set,
+};
+
+int register_nf_hook_bpf(void)
+{
+	int ret;
+
+	ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &nf_basehook_kfunc_set);
+	if (ret)
+		return ret;
+
+	return ret;
+}
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework
  2023-02-08 16:03 ` [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework Florian Westphal
@ 2023-02-08 19:11   ` kernel test robot
  2023-02-09  2:46     ` Philip Li
  0 siblings, 1 reply; 6+ messages in thread
From: kernel test robot @ 2023-02-08 19:11 UTC (permalink / raw)
  To: Florian Westphal; +Cc: oe-kbuild-all

Hi Florian,

[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on bpf-next/master]
[also build test WARNING on linus/master v6.2-rc7 next-20230208]
[cannot apply to nf-next/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Florian-Westphal/bpf-add-bpf_link-support-for-BPF_NETFILTER-programs/20230209-000601
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20230208160307.27534-4-fw%40strlen.de
patch subject: [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework
config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20230209/202302090245.nehZXsVh-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/594e7d0d1d1291101bd2250243e0be4e46e26985
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Florian-Westphal/bpf-add-bpf_link-support-for-BPF_NETFILTER-programs/20230209-000601
        git checkout 594e7d0d1d1291101bd2250243e0be4e46e26985
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash net/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/20230208160307.27534-4-fw@strlen.de

All warnings (new ones prefixed by >>):

>> net/netfilter/nf_bpf_link.c:233:5: warning: no previous prototype for 'register_nf_hook_bpf' [-Wmissing-prototypes]
     233 | int register_nf_hook_bpf(void)
         |     ^~~~~~~~~~~~~~~~~~~~


vim +/register_nf_hook_bpf +233 net/netfilter/nf_bpf_link.c

   232	
 > 233	int register_nf_hook_bpf(void)

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework
  2023-02-08 19:11   ` kernel test robot
@ 2023-02-09  2:46     ` Philip Li
  0 siblings, 0 replies; 6+ messages in thread
From: Philip Li @ 2023-02-09  2:46 UTC (permalink / raw)
  To: kernel test robot; +Cc: Florian Westphal, oe-kbuild-all

On Thu, Feb 09, 2023 at 03:11:55AM +0800, kernel test robot wrote:
> Hi Florian,
> 
> [FYI, it's a private test report for your RFC patch.]
> [auto build test WARNING on bpf-next/master]
> [also build test WARNING on linus/master v6.2-rc7 next-20230208]
> [cannot apply to nf-next/master]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Florian-Westphal/bpf-add-bpf_link-support-for-BPF_NETFILTER-programs/20230209-000601
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
> patch link:    https://lore.kernel.org/r/20230208160307.27534-4-fw%40strlen.de
> patch subject: [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework
> config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20230209/202302090245.nehZXsVh-lkp@intel.com/config)
> compiler: sparc64-linux-gcc (GCC) 12.1.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/intel-lab-lkp/linux/commit/594e7d0d1d1291101bd2250243e0be4e46e26985
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review Florian-Westphal/bpf-add-bpf_link-support-for-BPF_NETFILTER-programs/20230209-000601
>         git checkout 594e7d0d1d1291101bd2250243e0be4e46e26985
>         # save the config file
>         mkdir build_dir && cp config build_dir/.config
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc olddefconfig
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash net/
> 
> If you fix the issue, kindly add following tag where applicable
> | Reported-by: kernel test robot <lkp@intel.com>
> | Link: https://lore.kernel.org/oe-kbuild-all/20230208160307.27534-4-fw@strlen.de

Sorry that the link is wrong, it should be
	Link: https://lore.kernel.org/oe-kbuild-all/202302090245.nehZXsVh-lkp@intel.com/

> 
> All warnings (new ones prefixed by >>):
> 
> >> net/netfilter/nf_bpf_link.c:233:5: warning: no previous prototype for 'register_nf_hook_bpf' [-Wmissing-prototypes]
>      233 | int register_nf_hook_bpf(void)
>          |     ^~~~~~~~~~~~~~~~~~~~
> 
> 
> vim +/register_nf_hook_bpf +233 net/netfilter/nf_bpf_link.c
> 
>    232	
>  > 233	int register_nf_hook_bpf(void)
> 
> -- 
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-02-09  2:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-08 16:03 [RFC nf-next 0/3] bpf, netfilter: minimal support for bpf progs Florian Westphal
2023-02-08 16:03 ` [RFC nf-next 1/3] bpf: add bpf_link support for BPF_NETFILTER programs Florian Westphal
2023-02-08 16:03 ` [RFC nf-next 2/3] libbpf: sync header file, add nf prog section name Florian Westphal
2023-02-08 16:03 ` [RFC nf-next 3/3] bpf: minimal support for programs hooked into netfilter framework Florian Westphal
2023-02-08 19:11   ` kernel test robot
2023-02-09  2:46     ` Philip Li

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.