From: Weiming Shi <bestswngs@gmail.com>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>,
Emil Tsalapatis <emil@etsalapatis.com>,
Ihor Solodrai <ihor.solodrai@linux.dev>,
John Fastabend <john.fastabend@gmail.com>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>, Shuah Khan <shuah@kernel.org>
Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-kselftest@vger.kernel.org,
Xiang Mei <xmei5@asu.edu>, Weiming Shi <bestswngs@gmail.com>,
stable@vger.kernel.org,
Alexei Starovoitov <alexei.starovoitov@gmail.com>
Subject: [PATCH v4 1/2] bpf: clear stale IPv4 options after LWT encapsulation
Date: Tue, 22 Sep 2026 01:39:09 +0800 [thread overview]
Message-ID: <20260921173910.90847-2-bestswngs@gmail.com> (raw)
In-Reply-To: <20260921173910.90847-1-bestswngs@gmail.com>
bpf_lwt_push_ip_encap() rebases the network header after prepending an IP
header, but leaves IPCB(skb)->opt describing the inner IPv4 header. An
ingress LWT route can consequently make an ICMP error use stale option
offsets when constructing its reply.
Mark completed LWT IP encapsulation in the run's BPF network context and
clear stale metadata after bpf_prog_run_save_cb() restores the protocol
control block. For same-family IPv4 encapsulation, clear only the cached
options, as the IP tunnel transmit paths do. When the family changes,
reset the destination family's control block and initialize its ingress
interface, following seg6_do_srh_encap(). Save and restore the marker
around nested LWT runs.
Cc: stable@vger.kernel.org
Fixes: 52f278774e79 ("bpf: implement BPF_LWT_ENCAP_IP mode in bpf_lwt_push_encap")
Reported-by: Xiang Mei <xmei5@asu.edu>
Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Assisted-by: LLM
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
include/linux/filter.h | 1 +
net/core/lwt_bpf.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 39decde7fc73..195898af9528 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -848,6 +848,7 @@ struct bpf_nh_params {
#define BPF_RI_F_CPU_MAP_INIT BIT(2)
#define BPF_RI_F_DEV_MAP_INIT BIT(3)
#define BPF_RI_F_XSK_MAP_INIT BIT(4)
+#define BPF_RI_F_LWT_IP_ENCAP BIT(5)
struct bpf_redirect_info {
u64 tgt_index;
diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c
index da49364ec63d..88664382ca44 100644
--- a/net/core/lwt_bpf.c
+++ b/net/core/lwt_bpf.c
@@ -36,10 +36,30 @@ static inline struct bpf_lwt *bpf_lwt_lwtunnel(struct lwtunnel_state *lwt)
#define NO_REDIRECT false
#define CAN_REDIRECT true
+static void bpf_lwt_reset_cb(struct sk_buff *skb, __be16 orig_proto)
+{
+ if (skb->protocol == orig_proto) {
+ if (skb->protocol == htons(ETH_P_IP))
+ memset(&IPCB(skb)->opt, 0, sizeof(IPCB(skb)->opt));
+ return;
+ }
+
+ if (skb->protocol == htons(ETH_P_IP)) {
+ memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+ IPCB(skb)->iif = skb->skb_iif;
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+ IP6CB(skb)->iif = skb->skb_iif;
+ }
+}
+
static int run_lwt_bpf(struct sk_buff *skb, struct bpf_lwt_prog *lwt,
struct dst_entry *dst, bool can_redirect)
{
struct bpf_net_context __bpf_net_ctx, *bpf_net_ctx;
+ struct bpf_redirect_info *ri;
+ bool lwt_ip_encap, saved_lwt_ip_encap;
+ __be16 orig_proto = skb->protocol;
int ret;
/* Disabling BH is needed to protect per-CPU bpf_redirect_info between
@@ -47,8 +67,17 @@ static int run_lwt_bpf(struct sk_buff *skb, struct bpf_lwt_prog *lwt,
*/
local_bh_disable();
bpf_net_ctx = bpf_net_ctx_set(&__bpf_net_ctx);
+ ri = bpf_net_ctx_get_ri();
+ saved_lwt_ip_encap = ri->kern_flags & BPF_RI_F_LWT_IP_ENCAP;
+ ri->kern_flags &= ~BPF_RI_F_LWT_IP_ENCAP;
bpf_compute_data_pointers(skb);
ret = bpf_prog_run_save_cb(lwt->prog, skb);
+ lwt_ip_encap = ri->kern_flags & BPF_RI_F_LWT_IP_ENCAP;
+ ri->kern_flags &= ~BPF_RI_F_LWT_IP_ENCAP;
+ if (saved_lwt_ip_encap)
+ ri->kern_flags |= BPF_RI_F_LWT_IP_ENCAP;
+ if (lwt_ip_encap)
+ bpf_lwt_reset_cb(skb, orig_proto);
switch (ret) {
case BPF_OK:
@@ -668,6 +697,7 @@ int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len, bool ingress)
} else {
skb->protocol = htons(ETH_P_IPV6);
}
+ bpf_net_ctx_get_ri()->kern_flags |= BPF_RI_F_LWT_IP_ENCAP;
if (skb_is_gso(skb))
return handle_gso_encap(skb, ipv4, len);
--
2.55.0
next prev parent reply other threads:[~2026-09-21 17:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 17:39 [PATCH v4 0/2] " Weiming Shi
2026-09-21 17:39 ` Weiming Shi [this message]
2026-09-21 17:39 ` [PATCH v4 2/2] selftests/bpf: cover stale CB after LWT IP encapsulation Weiming Shi
2026-09-21 18:38 ` bot+bpf-ci
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=20260921173910.90847-2-bestswngs@gmail.com \
--to=bestswngs@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=eddyz87@gmail.com \
--cc=edumazet@google.com \
--cc=emil@etsalapatis.com \
--cc=horms@kernel.org \
--cc=ihor.solodrai@linux.dev \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=stable@vger.kernel.org \
--cc=xmei5@asu.edu \
--cc=yonghong.song@linux.dev \
/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
all inboxes | Powered by JetHome®