[RFC net-next v2 13/18] net: ipxlat: add translator-generated ICMP errors
flat view
DORMANTno replies
From: Ralf Lici <ralf@mandelbit.com>
Date: 2026-10-24 09:26:23
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
Let validation record an ICMP error without emitting it immediately, and provide an input-side helper which sends the pending error while the original packet headers and ingress device are still available. Signed-off-by: Ralf Lici <ralf@mandelbit.com> --- Changes since RFC v1 https://lore.kernel.org/netdev/20260319151230.655687-10-ralf@mandelbit.com/ (local) - Replace the netdevice drop/action path with pending-error metadata recorded during preparation. - Add an input-side emission helper which runs while the original headers and real ingress device are still available. - Leave local-output failures to the originating stack instead of inventing an ingress device solely to generate an ICMP error. include/net/ipxlat.h | 12 ++++++++++++ net/ipxlat/core.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)
diff --git a/include/net/ipxlat.h b/include/net/ipxlat.h
index ddc98058ff20..592429f4cff5 100644
--- a/include/net/ipxlat.h
+++ b/include/net/ipxlat.h@@ -98,4 +98,16 @@ int ipxlat_prepare(const struct ipxlat_config *cfg, struct sk_buff *skb); int ipxlat_translate(const struct ipxlat_config *cfg, struct net *net, struct sk_buff *skb); +/** + * ipxlat_emit_icmp_error - emit a pending error for a received packet + * @dev: real ingress device, required for IPv4 ICMP routing + * @skb: original-family input packet; IPv6 emission also uses @skb->dev + * + * Callers must retain the original headers and must not use it for locally + * originated errors. A forwarded packet may reach an output LWT callback, but + * it still has an ingress device and a remote sender which needs the error. + * It does nothing when the engine did not record an ICMP error. + */ +void ipxlat_emit_icmp_error(struct net_device *dev, struct sk_buff *skb); + #endif /* _NET_IPXLAT_H_ */
diff --git a/net/ipxlat/core.c b/net/ipxlat/core.c
index 1dc1fc7e6f04..dc03ca3c9f89 100644
--- a/net/ipxlat/core.c
+++ b/net/ipxlat/core.c@@ -11,8 +11,12 @@ * Ralf Lici <ralf@mandelbit.com> */ +#include <linux/icmp.h> +#include <linux/icmpv6.h> #include <linux/module.h> +#include <net/icmp.h> #include <net/ip.h> +#include <net/route.h> #include <net/ipv6.h> #include <net/ipxlat.h>
@@ -105,5 +109,41 @@ int ipxlat_translate(const struct ipxlat_config *cfg, struct net *net, } EXPORT_SYMBOL_GPL(ipxlat_translate); +void ipxlat_emit_icmp_error(struct net_device *dev, struct sk_buff *skb) +{ + const struct ipxlat_cb *cb = ipxlat_skb_cb(skb); + const struct iphdr *iph = ip_hdr(skb); + struct inet6_skb_parm param6 = {}; + struct inet_skb_parm param4 = {}; + + if (!cb->emit_icmp_err) + return; + + switch (ntohs(skb->protocol)) { + case ETH_P_IP: + /* __icmp_send requires an input route on the offending packet. + * Rebuild it if the original route was dropped. + */ + if (!skb_dst(skb)) { + if (ip_route_input_noref(skb, iph->daddr, iph->saddr, + ip4h_dscp(iph), dev)) + return; + } + __icmp_send(skb, cb->pending_icmp_err.type, + cb->pending_icmp_err.code, + htonl(cb->pending_icmp_err.info), ¶m4); + break; + case ETH_P_IPV6: + icmp6_send(skb, cb->pending_icmp_err.type, + cb->pending_icmp_err.code, + cb->pending_icmp_err.info, NULL, ¶m6); + break; + default: + DEBUG_NET_WARN_ON_ONCE(1); + break; + } +} +EXPORT_SYMBOL_GPL(ipxlat_emit_icmp_error); + MODULE_DESCRIPTION("IPv6<>IPv4 stateless translation engine (SIIT)"); MODULE_LICENSE("GPL");
--
2.55.0