From: Paul Chaignon <paul.chaignon@gmail.com>
To: Jordan Rife <jordan@jrife.io>
Cc: bpf@vger.kernel.org, netdev@vger.kernel.org,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <martin.lau@linux.dev>,
Stanislav Fomichev <sdf@fomichev.me>
Subject: Re: [PATCH v1 bpf-next 0/2] bpf: bpf_redirect_peer egress redirection
Date: Mon, 15 Jun 2026 17:15:35 +0200 [thread overview]
Message-ID: <ajAXF8Nvg91xU4f2@mail.gmail.com> (raw)
In-Reply-To: <20260613183424.1198073-1-jordan@jrife.io>
On Sat, Jun 13, 2026 at 11:34:04AM -0700, Jordan Rife wrote:
> We have several use cases where a pod injects traffic into the datapath
> of another so that the traffic appears to have originated from that
> pod. One such use case is a synthetic flow generator which injects
> synthetic traffic into a pod's datapath to enable dynamic probing and
> debugging. Another is a transparent proxy where connections originating
> from one pod are redirected towards another which proxies that
> connection. The new connection is bound to the IP of the original pod
> using IP_TRANSPARENT and its traffic is injected into that pod's
> datapath and handled as if it had originated there. This can be used for
> mTLS, etc.
>
> We use bpf_redirect(BPF_F_INGRESS) to direct traffic leaving the proxy,
> flow generator, etc. towards the target pod, ensuring that eBPF programs
> that are meant to intercept traffic leaving that pod are executed.
> However, this doesn't work with netkit.
>
> With netkit, an ingress redirection from proxy to workload skips eBPF
> programs that are meant to intercept traffic leaving the pod, since they
> reside on the netkit peer device. One workaround is to attach the
> same program to both the netkit peer device and the TCX ingress hook for
> the netkit pair's primary interface, but
>
> a) This seems hacky and we need to be careful not to run the same
> program twice for the same skb in cases where we want to pass that
> traffic to the host stack.
> b) We're trying to keep the proxy redirection / traffic injection
> systems as modular and separated from Cilium as possible, the system
> that manages netkit setup and core eBPF programming.
>
> It would be handy if instead we could redirect traffic directly from
> one netkit peer device to another. This patch proposes an extension
> to bpf_redirect_peer to allow us to do just that.
>
> With this patch, the BPF_F_INGRESS flag tells bpf_redirect_peer to emit
> the skb in the egress direction of the target interface's peer device
> While the main use case is netkit, I suppose you could also use this
> mode with veth as well if, e.g., there were some eBPF programs attached
> to that side of the veth pair that needed to intercept traffic.
>
> +---------------------------------------------------------------------+
> | +-------------------------+ 6. bpf_redirect_neigh(eth0) |
> | | pod (10.244.0.10) | ------------------------ |
> | | | | | |
> | | +--------+ | | +---------+ | |
> | | 1. packet -->| | | | | | | |
> | | leaves ^ | netkit |<===========|======| netkit | | |
> | | | | peer |=======(eBPF)=====>| primary | | |
> | | | | | | | | | | |
> | | | +--------+ | | +---------+ | |
> | | | | | 2. bpf_redirect v |
> | +-----------|-------------+ |___________________ +-------|
> | | | | eth0 |
> | | 5. bpf_redirect_peer(BPF_F_INGRESS) | +-------|
> | |________________________ | |
> | +-------------------------+ | | |
> | | proxy (10.244.0.11) | | | |
> | | IP_TRANSPARENT | | | |
> | | +--------+ | | +---------+ | |
> | | 3. packet <--| | | | | |<-- |
> | | enters | netkit |<===========|======| netkit | |
> | | [proxy] | peer |=======(eBPF)=====>| primary | |
> | | 4. packet -->| | | | | |
> | | leaves +--------+ | +---------+ |
> | | sip=10.244.0.10 | |
> | +-------------------------+ |
> +---------------------------------------------------------------------+
>
> Using the proxy use case as an example, in step 5 we would redirect
> traffic leaving the proxy towards the pod's peer device using
> bpf_redirect_peer(BPF_F_INGRESS).
>
> As a bonus, since the skb doesn't have to go through the backlog queue
> it can take full advantage of netkit's performance benefits. I set up a
The motivation makes sense. Cilium could probably use this as well to
avoid some of the hacks we have around proxy reinjection.
> test where outgoing iperf3 traffic is injected into the datapath of
> another pod using either bpf_redirect_peer(BPF_F_INGRESS) or
> bpf_redirect(BPF_F_INGRESS). I used Cilium's eBPF host routing mode
> which skips the host stack and uses BPF redirect helpers to do all the
> routing.
>
> (net.ipv4.tcp_congestion_control=cubic,mtu=1500,100GiB link,Cilium
> eBPF host routing mode)
>
> BASELINE [bpf_redirect(BPF_F_INGRESS)]
> 1. [iperf pod] ==bpf_redirect([pod b], BPF_F_INGRESS)==> [pod b]
> 2. [pod b] ==bpf_redirect_neigh([eth0])==> eth0
> 3. eth0 ==over network==> [host b]
>
> [ ID] Interval Transfer Bitrate Retr
> [ 5] 0.00-60.00 sec 231 GBytes 33.0 Gbits/sec 12060 sender
> [ 5] 0.00-60.00 sec 230 GBytes 33.0 Gbits/sec receiver
>
> TEST [bpf_redirect_peer(BPF_F_INGRESS)]
> 1. [iperf pod] ==bpf_redirect_peer([pod b], BPF_F_INGRESS)==> [pod b]
> 2. [pod b] ==bpf_redirect_neigh([eth0])==> eth0
> 3. eth0 ==over network==> [host b]
>
> [ ID] Interval Transfer Bitrate Retr
> [ 5] 0.00-60.00 sec 272 GBytes 38.9 Gbits/sec 0 sender
> [ 5] 0.00-60.00 sec 272 GBytes 38.9 Gbits/sec receiver
>
> In this test, using bpf_redirect_peer(BPF_F_INGRESS) for the hop from
> [iperf pod] to [pod b] led to ~18% more throughput compared to
> bpf_redirect(BPF_F_INGRESS).
>
> Note: I wasn't sure about the flag name. I can see where BPF_F_INGRESS
> might be confusing, since technically it's an egress redirection
> from the perspective of the peer device's namespace. But, I didn't
> want to add a BPF_F_EGRESS flag just for this and convinced myself
> it makes sense, because from the perspective of the caller the skb
> will be flowing towards the current namespace.
IMO, calling it BPF_F_EGRESS would be less confusing. It's a shame we
can't have the same flag API between bpf_redirect() and
bpf_redirect_peer(), but this is creating inconsistent semantics for
the terms egress/ingress across the two helpers.
>
> Jordan Rife (2):
> bpf: Support BPF_F_INGRESS with bpf_redirect_peer
> selftests/bpf: Add tests for bpf_redirect_peer with BPF_F_INGRESS
>
> include/uapi/linux/bpf.h | 16 +++--
> net/core/filter.c | 14 ++--
> tools/include/uapi/linux/bpf.h | 16 +++--
> .../selftests/bpf/prog_tests/tc_redirect.c | 68 +++++++++++++++++++
> .../selftests/bpf/progs/test_tc_peer.c | 22 ++++++
> 5 files changed, 116 insertions(+), 20 deletions(-)
>
> --
> 2.43.0
>
>
prev parent reply other threads:[~2026-06-15 15:15 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-13 18:34 [PATCH v1 bpf-next 0/2] bpf: bpf_redirect_peer egress redirection Jordan Rife
2026-06-13 18:34 ` [PATCH v1 bpf-next 1/2] bpf: Support BPF_F_INGRESS with bpf_redirect_peer Jordan Rife
2026-06-13 18:48 ` sashiko-bot
2026-06-13 18:34 ` [PATCH v1 bpf-next 2/2] selftests/bpf: Add tests for bpf_redirect_peer with BPF_F_INGRESS Jordan Rife
2026-06-15 15:15 ` Paul Chaignon [this message]
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=ajAXF8Nvg91xU4f2@mail.gmail.com \
--to=paul.chaignon@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=jordan@jrife.io \
--cc=martin.lau@linux.dev \
--cc=netdev@vger.kernel.org \
--cc=sdf@fomichev.me \
/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 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.