diff mbox series

[net,v2] net: Fix icmp host relookup triggering ip_rt_bug

Message ID 20241126025943.1223254-1-dongchenchen2@huawei.com (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series [net,v2] net: Fix icmp host relookup triggering ip_rt_bug | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 3 this patch: 3
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 1 maintainers not CCed: kuba@kernel.org
netdev/build_clang success Errors and warnings before: 3 this patch: 3
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 6 this patch: 6
netdev/checkpatch warning WARNING: line length of 86 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 1 this patch: 1
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-11-26--15-00 (tests: 789)

Commit Message

Dong Chenchen Nov. 26, 2024, 2:59 a.m. UTC
arp link failure may trigger ip_rt_bug while xfrm enabled, call trace is:

WARNING: CPU: 0 PID: 0 at net/ipv4/route.c:1241 ip_rt_bug+0x14/0x20
Modules linked in:
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.0-rc6-00077-g2e1b3cc9d7f7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:ip_rt_bug+0x14/0x20
Call Trace:
 <IRQ>
 ip_send_skb+0x14/0x40
 __icmp_send+0x42d/0x6a0
 ipv4_link_failure+0xe2/0x1d0
 arp_error_report+0x3c/0x50
 neigh_invalidate+0x8d/0x100
 neigh_timer_handler+0x2e1/0x330
 call_timer_fn+0x21/0x120
 __run_timer_base.part.0+0x1c9/0x270
 run_timer_softirq+0x4c/0x80
 handle_softirqs+0xac/0x280
 irq_exit_rcu+0x62/0x80
 sysvec_apic_timer_interrupt+0x77/0x90

The script below reproduces this scenario:
ip xfrm policy add src 0.0.0.0/0 dst 0.0.0.0/0 \
	dir out priority 0 ptype main flag localok icmp
ip l a veth1 type veth
ip a a 192.168.141.111/24 dev veth0
ip l s veth0 up
ping 192.168.141.155 -c 1

icmp_route_lookup() create input routes for locally generated packets
while xfrm relookup ICMP traffic.Then it will set input route
(dst->out = ip_rt_bug) to skb for DESTUNREACH.

For ICMP err triggered by locally generated packets, dst->dev of output
route is loopback. Generally, xfrm relookup verification is not required
on loopback interfaces (net.ipv4.conf.lo.disable_xfrm = 1).

Skip icmp relookup for locally generated packets to fix it.

Fixes: 8b7817f3a959 ("[IPSEC]: Add ICMP host relookup support")
Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
---
v2: Skip icmp relookup to fix bug
---
 net/ipv4/icmp.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

David Ahern Nov. 26, 2024, 4:23 p.m. UTC | #1
On 11/25/24 7:59 PM, Dong Chenchen wrote:
> diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
> index 4f088fa1c2f2..0d51f8434187 100644
> --- a/net/ipv4/icmp.c
> +++ b/net/ipv4/icmp.c
> @@ -515,7 +515,10 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
>  			  flowi4_to_flowi(fl4), NULL, 0);
>  	rt = dst_rtable(dst);
>  	if (!IS_ERR(dst)) {
> -		if (rt != rt2)
> +		unsigned int addr_type = inet_addr_type_dev_table(net,
> +							route_lookup_dev, fl4->daddr);
> +

	unsigned int addr_type;

	addr_type = inet_addr_type_dev_table(net, route_lookup_dev,
                                             fl4->daddr);

allows the lines to meet column limits and alignment requirements.

> +		if (rt != rt2 || addr_type == RTN_LOCAL)
>  			return rt;
>  	} else if (PTR_ERR(dst) == -EPERM) {
>  		rt = NULL;
diff mbox series

Patch

diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 4f088fa1c2f2..0d51f8434187 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -515,7 +515,10 @@  static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
 			  flowi4_to_flowi(fl4), NULL, 0);
 	rt = dst_rtable(dst);
 	if (!IS_ERR(dst)) {
-		if (rt != rt2)
+		unsigned int addr_type = inet_addr_type_dev_table(net,
+							route_lookup_dev, fl4->daddr);
+
+		if (rt != rt2 || addr_type == RTN_LOCAL)
 			return rt;
 	} else if (PTR_ERR(dst) == -EPERM) {
 		rt = NULL;