From: Daniel Borkmann <daniel@iogearbox.net>
To: Mahe Tardy <mahe.tardy@gmail.com>, bpf@vger.kernel.org
Cc: andrew+netdev@lunn.ch, andrii@kernel.org, ast@kernel.org,
davem@davemloft.net, eddyz87@gmail.com, edumazet@google.com,
john.fastabend@gmail.com, kuba@kernel.org, martin.lau@linux.dev,
pabeni@redhat.com, song@kernel.org, liamwisehart@meta.com
Subject: Re: [PATCH v1 1/4] bpf: Add netpoll kfuncs for sending UDP packets
Date: Mon, 11 May 2026 14:05:26 +0200 [thread overview]
Message-ID: <4b64ecd8-eade-4676-822e-da73abe2421d@iogearbox.net> (raw)
In-Reply-To: <20260511085344.3302-2-mahe.tardy@gmail.com>
On 5/11/26 10:53 AM, Mahe Tardy wrote:
> From: Song Liu <song@kernel.org>
>
> Add BPF kfuncs that allow BPF programs to send UDP packets via the
> netpoll infrastructure. This provides a mechanism for BPF programs
> (e.g., LSM hooks) to emit telemetry over UDP without depending on
> the regular networking stack.
>
> The API consists of four kfuncs:
>
> bpf_netpoll_create() - Allocate and set up a netpoll context
> (sleepable, SYSCALL prog type only)
> bpf_netpoll_acquire() - Acquire a reference to a netpoll context
> bpf_netpoll_release() - Release a reference (cleanup via
> queue_rcu_work since netpoll_cleanup sleeps)
> bpf_netpoll_send_udp() - Send a UDP packet (any context, LSM prog
> type only for now)
>
> The implementation follows the established kfunc lifecycle pattern
> (create/acquire/release with refcounting, kptr map storage, dtor
> registration). The netpoll context is wrapped in a refcounted
> bpf_netpoll struct. Cleanup is deferred via queue_rcu_work() because
> netpoll_cleanup() takes rtnl_lock.
>
> AI was used to generate the code and each line was manually reviewed.
>
> Reviewed-by: Mahe Tardy <mahe.tardy@gmail.com>
> Signed-off-by: Song Liu <song@kernel.org>
> ---
> drivers/net/Kconfig | 11 ++
> include/linux/bpf_netpoll.h | 38 +++++++
> kernel/bpf/verifier.c | 3 +
> net/core/Makefile | 1 +
> net/core/bpf_netpoll.c | 209 ++++++++++++++++++++++++++++++++++++
> 5 files changed, 262 insertions(+)
> create mode 100644 include/linux/bpf_netpoll.h
> create mode 100644 net/core/bpf_netpoll.c
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index edaab759dc50..8d94c9d58f32 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -364,6 +364,17 @@ config NETCONSOLE_PREPEND_RELEASE
> message. See <file:Documentation/networking/netconsole.rst> for
> details.
>
> +config BPF_NETPOLL
> + bool "BPF netpoll UDP support"
> + depends on BPF_SYSCALL && NET
> + select NETPOLL
> + help
> + Enable BPF kfuncs for sending UDP packets via netpoll.
> + This allows BPF programs to send UDP packets from any
> + context using the netpoll infrastructure.
> +
> + If unsure, say N.
Do we need the extra Kconfig knob? For most other BPF functionality we don't
have such convention. BPF_NETPOLL could be a hidden config enabled when both
BPF_SYSCALL && NETPOLL is enabled?
> config NETPOLL
> def_bool NETCONSOLE
>
> diff --git a/include/linux/bpf_netpoll.h b/include/linux/bpf_netpoll.h
> new file mode 100644
> index 000000000000..b738032548c7
> --- /dev/null
> +++ b/include/linux/bpf_netpoll.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
> +
> +#ifndef _BPF_NETPOLL_H
> +#define _BPF_NETPOLL_H
> +
> +#include <linux/types.h>
> +
> +#define BPF_NETPOLL_DEV_NAME_LEN 16 /* IFNAMSIZ */
Do we need this, can't we just reuse IFNAMSIZ?
> +/**
> + * struct bpf_netpoll_opts - BPF netpoll initialization parameters
> + * @dev_name: Network device name (e.g. "eth0"), null-terminated.
> + * @local_ip: Local IPv4 address in network byte order. 0 = auto-detect.
> + * @remote_ip: Remote IPv4 address in network byte order.
> + * @local_port: Local UDP port in host byte order.
> + * @remote_port: Remote UDP port in host byte order.
> + * @remote_mac: Remote MAC address (6 bytes).
> + * @ipv6: Set to 1 for IPv6, 0 for IPv4.
> + * @reserved: Must be zero. Reserved for future use.
> + * @local_ip6: Local IPv6 address (16 bytes). Used when ipv6=1.
> + * Zero = auto-detect.
> + * @remote_ip6: Remote IPv6 address (16 bytes). Used when ipv6=1.
> + */
> +struct bpf_netpoll_opts {
> + char dev_name[BPF_NETPOLL_DEV_NAME_LEN];
> + __be32 local_ip;
> + __be32 remote_ip;
> + __u16 local_port;
> + __u16 remote_port;
> + __u8 remote_mac[6];
> + __u8 ipv6;
> + __u8 reserved;
> + __u8 local_ip6[16];
> + __u8 remote_ip6[16];
> +};
Could we detangle this a bit and structure the design similar to what was
done for the bpf fib lookup helpers? __u8 family and then union.
Is the remote_mac strictly needed? Feels a bit like a burden, maybe for the
selftest, we should first do a bpf_fib_lookup before the bpf_netpoll_create
so that the use case where the user only cares about giving remote_ip/remote_port
and maybe local_port (e.g. to as indicator for different event types and/or
RSS hashing) works, but everything else is derived via kernel fib lookup.
Thanks,
Daniel
next prev parent reply other threads:[~2026-05-11 12:05 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 8:53 [PATCH v1 0/4] bpf: Introduce bpf_netpoll Mahe Tardy
2026-05-11 8:53 ` [PATCH v1 1/4] bpf: Add netpoll kfuncs for sending UDP packets Mahe Tardy
2026-05-11 9:40 ` bot+bpf-ci
2026-05-11 9:51 ` Mahe Tardy
2026-05-11 12:05 ` Daniel Borkmann [this message]
2026-05-12 8:51 ` Mahe Tardy
2026-05-12 1:20 ` Jakub Kicinski
2026-05-12 1:59 ` Alexei Starovoitov
2026-05-12 2:36 ` Jakub Kicinski
2026-05-12 2:59 ` Alexei Starovoitov
2026-05-12 13:53 ` Jakub Kicinski
2026-05-12 20:25 ` Alexei Starovoitov
2026-05-12 23:32 ` Jakub Kicinski
2026-05-13 1:16 ` Alexei Starovoitov
2026-05-13 1:31 ` Song Liu
2026-05-11 8:53 ` [PATCH v1 2/4] selftests/bpf: Add netpoll kfunc sanity test Mahe Tardy
2026-05-11 8:53 ` [PATCH v1 3/4] selftests/bpf: Add netpoll kfunc IPv6 variant test Mahe Tardy
2026-05-11 8:53 ` [PATCH v1 4/4] selftests/bpf: Add netpoll setup basic tests Mahe Tardy
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=4b64ecd8-eade-4676-822e-da73abe2421d@iogearbox.net \
--to=daniel@iogearbox.net \
--cc=andrew+netdev@lunn.ch \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=davem@davemloft.net \
--cc=eddyz87@gmail.com \
--cc=edumazet@google.com \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=liamwisehart@meta.com \
--cc=mahe.tardy@gmail.com \
--cc=martin.lau@linux.dev \
--cc=pabeni@redhat.com \
--cc=song@kernel.org \
/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