[PATCH] net: lwt_bpf: replace name-based BPF program comparison with digest
From: Matan Cohen
Date: Mon Apr 27 2026 - 18:51:50 EST
bpf_lwt_prog_cmp() used strcmp() on program names as a workaround
because delete requests rebuild the LWT state, creating a new
bpf_prog instance for the same program.
Name comparison is unreliable: programs with the same name but
different instructions compare equal, while instruction-identical
programs with different names compare unequal.
Replace it with a two-step approach:
- Pointer equality as a cheap fast path.
- SHA256 digest comparison as the fallback. bpf_prog_calc_tag()
computes the digest (instructions with map fds zeroed) at the
end of bpf_check(), so it is valid for every successfully
loaded BPF program.
Signed-off-by: Matan Cohen <matan@matanco.space>
---
net/core/lwt_bpf.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c
index f71ef82a5f3d3..6999da98b6b97 100644
--- a/net/core/lwt_bpf.c
+++ b/net/core/lwt_bpf.c
@@ -494,17 +494,20 @@ static int bpf_encap_nlsize(struct lwtunnel_state *lwtstate)
static int bpf_lwt_prog_cmp(struct bpf_lwt_prog *a, struct bpf_lwt_prog *b)
{
- /* FIXME:
- * The LWT state is currently rebuilt for delete requests which
- * results in a new bpf_prog instance. Comparing names for now.
+ /* Delete requests rebuild the LWT state, so pointer equality is
+ * not sufficient. Compare by digest (SHA256 of instructions with
+ * map fds zeroed by bpf_prog_calc_tag()) as a reliable fallback.
*/
- if (!a->name && !b->name)
+ if (!a->prog && !b->prog)
return 0;
- if (!a->name || !b->name)
+ if (!a->prog || !b->prog)
return 1;
- return strcmp(a->name, b->name);
+ if (a->prog == b->prog)
+ return 0;
+
+ return memcmp(a->prog->digest, b->prog->digest, SHA256_DIGEST_SIZE);
}
static int bpf_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
--
2.43.0