Thread (19 messages) 19 messages, 1 author, 20h ago

[RFC net-next v2 01/18] lwtunnel: track callback dispatch separately from return value

flat view
HOTtoday

From: Ralf Lici <ralf@mandelbit.com>
Date: 2026-10-24 09:26:11
Also in: lkml
Subsystem: networking [general], networking [ipv4/ipv6], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds

LWT used -EOPNOTSUPP both as its missing-callback sentinel and as a
valid callback error. Track whether an operation was invoked separately
so callbacks can return meaningful errors without triggering the
no-operation skb cleanup path.

Signed-off-by: Ralf Lici <ralf@mandelbit.com>
---
New patch in RFC v2.

 net/core/lwtunnel.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
index 8223c44f10c8..db21b9ff6f86 100644
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -322,6 +322,7 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	const struct lwtunnel_encap_ops *ops;
 	struct lwtunnel_state *lwtstate;
+	bool called_cb = false;
 	struct dst_entry *dst;
 	int ret;
 
@@ -353,13 +354,14 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 	if (likely(ops && ops->output)) {
 		/* Encap pushes outer headers over the metadata; drop it. */
 		skb_metadata_clear(skb);
+		called_cb = true;
 		dev_xmit_recursion_inc();
 		ret = ops->output(net, sk, skb);
 		dev_xmit_recursion_dec();
 	}
 	rcu_read_unlock();
 
-	if (ret == -EOPNOTSUPP)
+	if (unlikely(!called_cb))
 		goto drop;
 
 	goto out;
@@ -377,6 +379,7 @@ int lwtunnel_xmit(struct sk_buff *skb)
 {
 	const struct lwtunnel_encap_ops *ops;
 	struct lwtunnel_state *lwtstate;
+	bool called_cb = false;
 	struct dst_entry *dst;
 	int ret;
 
@@ -409,13 +412,14 @@ int lwtunnel_xmit(struct sk_buff *skb)
 	if (likely(ops && ops->xmit)) {
 		/* Encap pushes outer headers over the metadata; drop it. */
 		skb_metadata_clear(skb);
+		called_cb = true;
 		dev_xmit_recursion_inc();
 		ret = ops->xmit(skb);
 		dev_xmit_recursion_dec();
 	}
 	rcu_read_unlock();
 
-	if (ret == -EOPNOTSUPP)
+	if (unlikely(!called_cb))
 		goto drop;
 
 	goto out;
@@ -433,6 +437,7 @@ int lwtunnel_input(struct sk_buff *skb)
 {
 	const struct lwtunnel_encap_ops *ops;
 	struct lwtunnel_state *lwtstate;
+	bool called_cb = false;
 	struct dst_entry *dst;
 	int ret;
 
@@ -462,13 +467,14 @@ int lwtunnel_input(struct sk_buff *skb)
 	if (likely(ops && ops->input)) {
 		/* Encap pushes outer headers over the metadata; drop it. */
 		skb_metadata_clear(skb);
+		called_cb = true;
 		dev_xmit_recursion_inc();
 		ret = ops->input(skb);
 		dev_xmit_recursion_dec();
 	}
 	rcu_read_unlock();
 
-	if (ret == -EOPNOTSUPP)
+	if (unlikely(!called_cb))
 		goto drop;
 
 	return ret;
-- 
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help