[PATCH v1 2/2] net: lwip: add Kconfig option to show ICMP unreachable errors

Jerome Forissier jerome.forissier at linaro.org
Wed Aug 6 10:58:14 CEST 2025


Add Kconfig symbol LWIP_ICMP_SHOW_UNREACH which, when enabled, prints a
message to the console upon reception of ICMP unreachable messages. For
example:

 $ make qemu_arm64_lwip_defconfig
 $ qemu-system-aarch64 -M virt -cpu max -nographic -bios u-boot.bin
 [...]
 => dhcp
 DHCP client bound to address 10.0.2.15 (0 ms)
 => tftp 192.168.0.100:69:Image
 Using virtio-net#32 device
 TFTP from server 192.168.0.100; our IP address is 10.0.2.15
 Filename 'Image'.
 Load address: 0x40200000
 Loading: ICMP destination unreachable (host unreachable) from 192.168.0.16
 Timeout!
 => tftp 192.168.0.16:69:Image
 Using virtio-net#32 device
 TFTP from server 192.168.0.16; our IP address is 10.0.2.15
 Filename 'Image'.
 Load address: 0x40200000
 Loading: ICMP destination unreachable (port unreachable) from 192.168.0.16
 Timeout!
 =>

Signed-off-by: Jerome Forissier <jerome.forissier at linaro.org>
---

 lib/lwip/u-boot/arch/cc.h  |  7 +++++++
 lib/lwip/u-boot/lwipopts.h |  4 ++++
 net/lwip/Kconfig           | 13 +++++++++++++
 net/lwip/Makefile          |  1 +
 net/lwip/icmp_unreach.c    | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 63 insertions(+)
 create mode 100644 net/lwip/icmp_unreach.c

diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h
index 04ab94d6b70..849c79c5a8d 100644
--- a/lib/lwip/u-boot/arch/cc.h
+++ b/lib/lwip/u-boot/arch/cc.h
@@ -56,4 +56,11 @@ static inline const char *sntp_format_time(time_t t)
 }
 
 #define sntp_format_time sntp_format_time
+
+#ifdef CONFIG_LWIP_ICMP_SHOW_UNREACH
+struct pbuf;
+void net_lwip_icmp_dest_unreach(int code, struct pbuf *p);
+
+#define ICMP_DEST_UNREACH_CB(_c, _p) net_lwip_icmp_dest_unreach(_c, _p)
+#endif
 #endif /* LWIP_ARCH_CC_H */
diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h
index 46af91f9410..80b93ea172d 100644
--- a/lib/lwip/u-boot/lwipopts.h
+++ b/lib/lwip/u-boot/lwipopts.h
@@ -80,7 +80,11 @@
 
 #define IP_DEFAULT_TTL                  255
 
+#if defined(CONFIG_PROT_ICMP_LWIP)
+#define LWIP_ICMP                       1
+#else
 #define LWIP_ICMP                       0
+#endif
 
 #if defined(CONFIG_PROT_RAW_LWIP)
 #define LWIP_RAW                        1
diff --git a/net/lwip/Kconfig b/net/lwip/Kconfig
index d28a8a7df94..5789766fe62 100644
--- a/net/lwip/Kconfig
+++ b/net/lwip/Kconfig
@@ -4,6 +4,16 @@
 
 if NET_LWIP
 
+config LWIP_ICMP_SHOW_UNREACH
+	bool "Print ICMP Destination Unreachable messages"
+	default y
+	depends on CMD_TFTPBOOT || CMD_SNTP
+	select PROT_ICMP_LWIP
+	help
+	  Prints a message whenever an ICMP Destination Unreachable message is
+	  received while running a network command that sends requests via UDP.
+	  Enabling this can make troubleshooting easier.
+
 config LWIP_DEBUG
 	bool "Enable debug traces in the lwIP library"
 	help
@@ -31,6 +41,9 @@ config PROT_DNS_LWIP
 	bool
 	select PROT_UDP_LWIP
 
+config PROT_ICMP_LWIP
+	bool
+
 config PROT_RAW_LWIP
 	bool
 
diff --git a/net/lwip/Makefile b/net/lwip/Makefile
index 97299d9b542..09c3b3511a4 100644
--- a/net/lwip/Makefile
+++ b/net/lwip/Makefile
@@ -2,6 +2,7 @@ ccflags-y += -I$(srctree)/lib/lwip/lwip/src/include -I$(srctree)/lib/lwip/u-boot
 
 obj-$(CONFIG_$(PHASE_)DM_ETH) += net-lwip.o
 obj-$(CONFIG_CMD_DHCP) += dhcp.o
+obj-$(CONFIG_LWIP_ICMP_SHOW_UNREACH) += icmp_unreach.o
 obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
 obj-$(CONFIG_WGET) += wget.o
 
diff --git a/net/lwip/icmp_unreach.c b/net/lwip/icmp_unreach.c
new file mode 100644
index 00000000000..9e8a05f5717
--- /dev/null
+++ b/net/lwip/icmp_unreach.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2025 Linaro Ltd. */
+
+#include <lwip/icmp.h>
+#include <lwip/ip4_addr.h>
+#include <lwip/pbuf.h>
+#include <lwip/prot/ip4.h>
+
+static const char *code_to_str(int code)
+{
+	switch (code) {
+	case ICMP_DUR_NET:
+		return "network unreachable";
+	case ICMP_DUR_HOST:
+		return "host unreachable";
+	case ICMP_DUR_PROTO:
+		return "protocol unreachable";
+	case ICMP_DUR_PORT:
+		return "port unreachable";
+	case ICMP_DUR_FRAG:
+		return "fragmentation needed and DF set";
+	case ICMP_DUR_SR:
+		return "source route failed";
+	default:
+		break;
+	}
+	return "unknown cause";
+}
+
+void net_lwip_icmp_dest_unreach(int code, struct pbuf *p)
+{
+	struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
+	ip4_addr_t src;
+
+	ip4_addr_copy(src, iphdr->src);
+	printf("ICMP destination unreachable (%s) from %s\n",
+	       code_to_str(code), ip4addr_ntoa(&src));
+}
-- 
2.43.0



More information about the U-Boot mailing list