* [PATCH] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
@ 2026-05-26 10:16 Sayooj K Karun
2026-05-26 15:40 ` Alexander Lobakin
2026-05-27 9:46 ` [PATCH v2 net] " Sayooj K Karun
0 siblings, 2 replies; 7+ messages in thread
From: Sayooj K Karun @ 2026-05-26 10:16 UTC (permalink / raw)
To: netdev
Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms,
linux-kernel, Sayooj K Karun
RFC 4443 section 2.4(e.2) mandates that an ICMPv6 error message MUST NOT
be originated in response to an ICMPv6 Redirect message (type 137).
Add check for NDISC_REDIRECT (137) so that redirect packets become
ineligible and error packets are not generated for Redirect messages.
Signed-off-by: Sayooj K Karun <sayooj@aerlync.com>
---
net/ipv6/icmp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index efb23807a026..3fdb3a97dd8e 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -157,7 +157,8 @@ static bool is_ineligible(const struct sk_buff *skb)
*/
if (!tp && frag_off != 0)
return false;
- else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
+ else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK) ||
+ *tp == NDISC_REDIRECT)
return true;
}
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
2026-05-26 10:16 [PATCH] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets Sayooj K Karun
@ 2026-05-26 15:40 ` Alexander Lobakin
2026-05-27 9:46 ` [PATCH v2 net] " Sayooj K Karun
1 sibling, 0 replies; 7+ messages in thread
From: Alexander Lobakin @ 2026-05-26 15:40 UTC (permalink / raw)
To: Sayooj K Karun
Cc: netdev, dsahern, idosch, davem, edumazet, kuba, pabeni, horms,
linux-kernel
From: Sayooj K Karun <sayooj@aerlync.com>
Date: Tue, 26 May 2026 15:46:22 +0530
> [PATCH] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
Is this a fix or a feature? The subject prefix must contain either
"net-next" (if targeting the feature tree) or "net" (if targeting the
fixes tree)
> RFC 4443 section 2.4(e.2) mandates that an ICMPv6 error message MUST NOT
> be originated in response to an ICMPv6 Redirect message (type 137).
>
> Add check for NDISC_REDIRECT (137) so that redirect packets become
> ineligible and error packets are not generated for Redirect messages.
...for I didn't understand from the commit message which tree this
should be taken to and whether this should be considered for backporting.
I'd also like to hear about real life scenarios where this misbehaves
and what gets affected by this.
IOW very poor description to be reviewable.
>
> Signed-off-by: Sayooj K Karun <sayooj@aerlync.com>
> ---
> net/ipv6/icmp.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
> index efb23807a026..3fdb3a97dd8e 100644
> --- a/net/ipv6/icmp.c
> +++ b/net/ipv6/icmp.c
> @@ -157,7 +157,8 @@ static bool is_ineligible(const struct sk_buff *skb)
> */
> if (!tp && frag_off != 0)
> return false;
> - else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
> + else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK) ||
> + *tp == NDISC_REDIRECT)
> return true;
> }
> return false;
Thanks,
Olek
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 net] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
2026-05-26 10:16 [PATCH] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets Sayooj K Karun
2026-05-26 15:40 ` Alexander Lobakin
@ 2026-05-27 9:46 ` Sayooj K Karun
2026-05-27 12:15 ` Eric Dumazet
1 sibling, 1 reply; 7+ messages in thread
From: Sayooj K Karun @ 2026-05-27 9:46 UTC (permalink / raw)
To: netdev
Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms,
linux-kernel, aleksander.lobakin, Sayooj K Karun
Discovered while reading RFC 4443 and cross-checking the ICMPv6 stack,
which in section 2.4(e.2) mandates that an ICMPv6 error MUST NOT be
originated in response to an ICMPv6 Redirect message (type 137).
is_ineligible() is called by icmpv6_send() to decide whether a received
packet is eligible to trigger an ICMPv6 error. It uses
ICMPV6_INFOMSG_MASK (0x80) to suppress errors for ICMPv6 error types
(bit 7 clear) while passing informational types (bit 7 set). However,
NDISC_REDIRECT has type 137 (0x89), which has bit 7 set, so it passes
the mask check and is_ineligible() returns false and icmpv6_send()
proceeds to generate an error in response to a Redirect, violating the
RFC.
A triggerable scenario: a host with an ip6tables/nftables REJECT rule
applied to incoming ICMPv6 traffic (e.g., dropping Redirects from an
untrusted router). When the Redirect hits the REJECT rule,
nf_send_unreach6() calls icmpv6_send() with the Redirect as the
triggering skb. Without this fix, is_ineligible() returns false and a
Destination Unreachable is erroneously transmitted in response.
Add an explicit check for NDISC_REDIRECT so that Redirect packets are
treated as ineligible, suppressing ICMPv6 error generation in response
to them.
Signed-off-by: Sayooj K Karun <sayooj@aerlync.com>
---
The bug can be triggered via a netfilter REJECT rule targeting ICMPv6
Redirect packets. Consider a host with the following rule:
ip6tables -A INPUT -s <untrusted-router> -p icmpv6 --icmpv6-type redirect \
-j REJECT --reject-with icmp6-adm-prohibited
When a Redirect packet (type 137) arrives from that source, the packet
enters ip6_input(), which invokes NF_HOOK(NF_INET_LOCAL_IN). The
netfilter framework iterates the registered hook entries via
nf_hook_slow(), reaches the ip6tables filter table, and evaluates the
rules. The incoming Redirect matches the rule, causing reject_tg6()
(net/ipv6/netfilter/ip6t_REJECT.c) to be called as the rule's target
action. reject_tg6() calls nf_send_unreach6(), which in turn calls
icmpv6_send() with the Redirect packet as the triggering skb.
Inside icmpv6_send(), is_ineligible() is called to decide whether to
suppress the error. The function detects that the inner protocol is
IPPROTO_ICMPV6 and reads the ICMPv6 type byte. NDISC_REDIRECT is
type 137 (0x89). The check !(*tp & ICMPV6_INFOMSG_MASK) evaluates as
!(0x89 & 0x80) = !(0x80) = false, so is_ineligible() falls through and
returns false and the kernel proceeds to transmit a Destination Unreachable
in response to the Redirect, violating RFC 4443 section 2.4(e.2).
Tested using network namespaces with the above ip6tables rule. Without
the fix, tcpdump confirms a Destination Unreachable is transmitted in
response to the Redirect. With the fix applied and verified under QEMU,
no error is generated.
From the RFC:
(e) An ICMPv6 error message MUST NOT be originated as a result of
receiving the following:
(e.1) An ICMPv6 error message.
(e.2) An ICMPv6 redirect message [IPv6-DISC].
...
net/ipv6/icmp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index efb23807a026..3fdb3a97dd8e 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -157,7 +157,8 @@ static bool is_ineligible(const struct sk_buff *skb)
*/
if (!tp && frag_off != 0)
return false;
- else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
+ else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK) ||
+ *tp == NDISC_REDIRECT)
return true;
}
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2 net] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
2026-05-27 9:46 ` [PATCH v2 net] " Sayooj K Karun
@ 2026-05-27 12:15 ` Eric Dumazet
[not found] ` <CAFdLOz67Sxne4yXi3hB7Nf0eX=SzE9-P1phG4OzYfrgjQvmcGw@mail.gmail.com>
0 siblings, 1 reply; 7+ messages in thread
From: Eric Dumazet @ 2026-05-27 12:15 UTC (permalink / raw)
To: Sayooj K Karun
Cc: netdev, dsahern, idosch, davem, kuba, pabeni, horms, linux-kernel,
aleksander.lobakin
On Wed, May 27, 2026 at 2:46 AM Sayooj K Karun <sayooj@aerlync.com> wrote:
>
> Discovered while reading RFC 4443 and cross-checking the ICMPv6 stack,
> which in section 2.4(e.2) mandates that an ICMPv6 error MUST NOT be
> originated in response to an ICMPv6 Redirect message (type 137).
>
> is_ineligible() is called by icmpv6_send() to decide whether a received
> packet is eligible to trigger an ICMPv6 error. It uses
> ICMPV6_INFOMSG_MASK (0x80) to suppress errors for ICMPv6 error types
> (bit 7 clear) while passing informational types (bit 7 set). However,
> NDISC_REDIRECT has type 137 (0x89), which has bit 7 set, so it passes
> the mask check and is_ineligible() returns false and icmpv6_send()
> proceeds to generate an error in response to a Redirect, violating the
> RFC.
>
> A triggerable scenario: a host with an ip6tables/nftables REJECT rule
> applied to incoming ICMPv6 traffic (e.g., dropping Redirects from an
> untrusted router). When the Redirect hits the REJECT rule,
> nf_send_unreach6() calls icmpv6_send() with the Redirect as the
> triggering skb. Without this fix, is_ineligible() returns false and a
> Destination Unreachable is erroneously transmitted in response.
>
> Add an explicit check for NDISC_REDIRECT so that Redirect packets are
> treated as ineligible, suppressing ICMPv6 error generation in response
> to them.
>
> Signed-off-by: Sayooj K Karun <sayooj@aerlync.com>
> ---
> The bug can be triggered via a netfilter REJECT rule targeting ICMPv6
> Redirect packets. Consider a host with the following rule:
>
> ip6tables -A INPUT -s <untrusted-router> -p icmpv6 --icmpv6-type redirect \
> -j REJECT --reject-with icmp6-adm-prohibited
>
You are saying that after your patch, this ip6ables will no longer
send a packet, and will effectively DROP
the packet.
This might break user choice/expectations/policy.
If the user wanted a DROP, they would have instead specified "-j DROP"
Apart from the netfilter world which is free to implement its own
interpretation of the RFC,
how would the kernel send a reply?
> When a Redirect packet (type 137) arrives from that source, the packet
> enters ip6_input(), which invokes NF_HOOK(NF_INET_LOCAL_IN). The
> netfilter framework iterates the registered hook entries via
> nf_hook_slow(), reaches the ip6tables filter table, and evaluates the
> rules. The incoming Redirect matches the rule, causing reject_tg6()
> (net/ipv6/netfilter/ip6t_REJECT.c) to be called as the rule's target
> action. reject_tg6() calls nf_send_unreach6(), which in turn calls
> icmpv6_send() with the Redirect packet as the triggering skb.
>
> Inside icmpv6_send(), is_ineligible() is called to decide whether to
> suppress the error. The function detects that the inner protocol is
> IPPROTO_ICMPV6 and reads the ICMPv6 type byte. NDISC_REDIRECT is
> type 137 (0x89). The check !(*tp & ICMPV6_INFOMSG_MASK) evaluates as
> !(0x89 & 0x80) = !(0x80) = false, so is_ineligible() falls through and
> returns false and the kernel proceeds to transmit a Destination Unreachable
> in response to the Redirect, violating RFC 4443 section 2.4(e.2).
>
> Tested using network namespaces with the above ip6tables rule. Without
> the fix, tcpdump confirms a Destination Unreachable is transmitted in
> response to the Redirect. With the fix applied and verified under QEMU,
> no error is generated.
>
> From the RFC:
> (e) An ICMPv6 error message MUST NOT be originated as a result of
> receiving the following:
>
> (e.1) An ICMPv6 error message.
>
> (e.2) An ICMPv6 redirect message [IPv6-DISC].
>
> ...
>
> net/ipv6/icmp.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
> index efb23807a026..3fdb3a97dd8e 100644
> --- a/net/ipv6/icmp.c
> +++ b/net/ipv6/icmp.c
> @@ -157,7 +157,8 @@ static bool is_ineligible(const struct sk_buff *skb)
> */
> if (!tp && frag_off != 0)
> return false;
> - else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
> + else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK) ||
> + *tp == NDISC_REDIRECT)
> return true;
> }
> return false;
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 net] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
@ 2026-05-27 9:50 Sayooj K Karun
0 siblings, 0 replies; 7+ messages in thread
From: Sayooj K Karun @ 2026-05-27 9:50 UTC (permalink / raw)
To: netdev
Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms,
linux-kernel, aleksander.lobakin, Sayooj K Karun
Discovered while reading RFC 4443 and cross-checking the ICMPv6 stack,
which in section 2.4(e.2) mandates that an ICMPv6 error MUST NOT be
originated in response to an ICMPv6 Redirect message (type 137).
is_ineligible() is called by icmpv6_send() to decide whether a received
packet is eligible to trigger an ICMPv6 error. It uses
ICMPV6_INFOMSG_MASK (0x80) to suppress errors for ICMPv6 error types
(bit 7 clear) while passing informational types (bit 7 set). However,
NDISC_REDIRECT has type 137 (0x89), which has bit 7 set, so it passes
the mask check and is_ineligible() returns false and icmpv6_send()
proceeds to generate an error in response to a Redirect, violating the
RFC.
A triggerable scenario: a host with an ip6tables/nftables REJECT rule
applied to incoming ICMPv6 traffic (e.g., dropping Redirects from an
untrusted router). When the Redirect hits the REJECT rule,
nf_send_unreach6() calls icmpv6_send() with the Redirect as the
triggering skb. Without this fix, is_ineligible() returns false and a
Destination Unreachable is erroneously transmitted in response.
Add an explicit check for NDISC_REDIRECT so that Redirect packets are
treated as ineligible, suppressing ICMPv6 error generation in response
to them.
Signed-off-by: Sayooj K Karun <sayooj@aerlync.com>
---
The bug can be triggered via a netfilter REJECT rule targeting ICMPv6
Redirect packets. Consider a host with the following rule:
ip6tables -A INPUT -s <untrusted-router> -p icmpv6 --icmpv6-type redirect \
-j REJECT --reject-with icmp6-adm-prohibited
When a Redirect packet (type 137) arrives from that source, the packet
enters ip6_input(), which invokes NF_HOOK(NF_INET_LOCAL_IN). The
netfilter framework iterates the registered hook entries via
nf_hook_slow(), reaches the ip6tables filter table, and evaluates the
rules. The incoming Redirect matches the rule, causing reject_tg6()
(net/ipv6/netfilter/ip6t_REJECT.c) to be called as the rule's target
action. reject_tg6() calls nf_send_unreach6(), which in turn calls
icmpv6_send() with the Redirect packet as the triggering skb.
Inside icmpv6_send(), is_ineligible() is called to decide whether to
suppress the error. The function detects that the inner protocol is
IPPROTO_ICMPV6 and reads the ICMPv6 type byte. NDISC_REDIRECT is
type 137 (0x89). The check !(*tp & ICMPV6_INFOMSG_MASK) evaluates as
!(0x89 & 0x80) = !(0x80) = false, so is_ineligible() falls through and
returns false and the kernel proceeds to transmit a Destination Unreachable
in response to the Redirect, violating RFC 4443 section 2.4(e.2).
Tested using network namespaces with the above ip6tables rule. Without
the fix, tcpdump confirms a Destination Unreachable is transmitted in
response to the Redirect. With the fix applied and verified under QEMU,
no error is generated.
From the RFC:
(e) An ICMPv6 error message MUST NOT be originated as a result of
receiving the following:
(e.1) An ICMPv6 error message.
(e.2) An ICMPv6 redirect message [IPv6-DISC].
...
net/ipv6/icmp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index efb23807a026..3fdb3a97dd8e 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -157,7 +157,8 @@ static bool is_ineligible(const struct sk_buff *skb)
*/
if (!tp && frag_off != 0)
return false;
- else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
+ else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK) ||
+ *tp == NDISC_REDIRECT)
return true;
}
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-01 9:49 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-26 10:16 [PATCH] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets Sayooj K Karun
2026-05-26 15:40 ` Alexander Lobakin
2026-05-27 9:46 ` [PATCH v2 net] " Sayooj K Karun
2026-05-27 12:15 ` Eric Dumazet
[not found] ` <CAFdLOz67Sxne4yXi3hB7Nf0eX=SzE9-P1phG4OzYfrgjQvmcGw@mail.gmail.com>
2026-06-01 7:32 ` Eric Dumazet
2026-06-01 9:49 ` Pablo Neira Ayuso
-- strict thread matches above, loose matches on Subject: below --
2026-05-27 9:50 Sayooj K Karun
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox