From 6b914d5596d947ebea4e8697004e210df1abe61e Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Tue, 12 Aug 2025 14:43:19 +0200 Subject: net: lwip: add Kconfig option to show ICMP unreachable errors 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! => Submitted upstream as https://github.com/lwip-tcpip/lwip/pull/73. Signed-off-by: Jerome Forissier --- net/lwip/Kconfig | 13 +++++++++++++ net/lwip/Makefile | 1 + net/lwip/icmp_unreach.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 net/lwip/icmp_unreach.c (limited to 'net') 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 +#include +#include +#include + +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)); +} -- cgit v1.2.3 From 4800a6a0b3fa9d00f1ec40233a0e16464987c24f Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Thu, 14 Aug 2025 14:03:52 +0200 Subject: net: add missing SPDX-License-Identifier for files originating from LiMon The header of LiMon imported files reference a License file which does not exist in U-Boot. Some files were forgotten when adding the SPDX-License-Identifier. The LiMon files were originally licensed under GPLv2 as can be seen in commit [2ea91039]. Based on this commit, add the correct SPDX license identifier. While at it drop the reference to the non-existing License file from all LiMon files and update the SPDX-License-Identifier to SPDX version 3. Signed-off-by: Max Merchel --- net/arp.c | 3 +-- net/arp.h | 3 +-- net/bootp.c | 2 +- net/bootp.h | 2 +- net/cdp.c | 3 +-- net/cdp.h | 3 +-- net/net.c | 3 +-- net/net_rand.h | 2 +- net/ping.c | 3 +-- net/ping.h | 3 +-- 10 files changed, 10 insertions(+), 17 deletions(-) (limited to 'net') diff --git a/net/arp.c b/net/arp.c index bc1e25f941f..4801dca6213 100644 --- a/net/arp.c +++ b/net/arp.c @@ -1,9 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copied from Linux Monitor (LiMon) - Networking. * * Copyright 1994 - 2000 Neil Russell. - * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000-2002 Wolfgang Denk, wd@denx.de diff --git a/net/arp.h b/net/arp.h index c50885fb9a5..882f3ec31fc 100644 --- a/net/arp.h +++ b/net/arp.h @@ -1,9 +1,8 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copied from Linux Monitor (LiMon) - Networking. * * Copyright 1994 - 2000 Neil Russell. - * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000-2002 Wolfgang Denk, wd@denx.de diff --git a/net/bootp.c b/net/bootp.c index 95d906e3b2d..19e7453daed 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -1,8 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Based on LiMon - BOOTP. * * Copyright 1994, 1995, 2000 Neil Russell. - * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000-2004 Wolfgang Denk, wd@denx.de diff --git a/net/bootp.h b/net/bootp.h index 68320bf66cf..47c743479e7 100644 --- a/net/bootp.h +++ b/net/bootp.h @@ -1,8 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copied from LiMon - BOOTP. * * Copyright 1994, 1995, 2000 Neil Russell. - * (See License) * Copyright 2000 Paolo Scaffardi */ diff --git a/net/cdp.c b/net/cdp.c index d4cfc587ee3..6e404981d4a 100644 --- a/net/cdp.c +++ b/net/cdp.c @@ -1,9 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copied from Linux Monitor (LiMon) - Networking. * * Copyright 1994 - 2000 Neil Russell. - * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000-2002 Wolfgang Denk, wd@denx.de diff --git a/net/cdp.h b/net/cdp.h index 16ccbf4b59e..606fabba957 100644 --- a/net/cdp.h +++ b/net/cdp.h @@ -1,9 +1,8 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copied from Linux Monitor (LiMon) - Networking. * * Copyright 1994 - 2000 Neil Russell. - * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000-2002 Wolfgang Denk, wd@denx.de diff --git a/net/net.c b/net/net.c index 5219367e391..ac9b65c0ca4 100644 --- a/net/net.c +++ b/net/net.c @@ -1,9 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copied from Linux Monitor (LiMon) - Networking. * * Copyright 1994 - 2000 Neil Russell. - * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000-2002 Wolfgang Denk, wd@denx.de diff --git a/net/net_rand.h b/net/net_rand.h index 686e85f2b53..e21dff8569b 100644 --- a/net/net_rand.h +++ b/net/net_rand.h @@ -1,8 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copied from LiMon - BOOTP. * * Copyright 1994, 1995, 2000 Neil Russell. - * (See License) * Copyright 2000 Paolo Scaffardi */ diff --git a/net/ping.c b/net/ping.c index 075df3663fe..fb981f62084 100644 --- a/net/ping.c +++ b/net/ping.c @@ -1,9 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copied from Linux Monitor (LiMon) - Networking. * * Copyright 1994 - 2000 Neil Russell. - * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000-2002 Wolfgang Denk, wd@denx.de diff --git a/net/ping.h b/net/ping.h index 76ac225fc07..739f128408e 100644 --- a/net/ping.h +++ b/net/ping.h @@ -1,9 +1,8 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copied from Linux Monitor (LiMon) - Networking. * * Copyright 1994 - 2000 Neil Russell. - * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi * Copyright 2000-2002 Wolfgang Denk, wd@denx.de -- cgit v1.2.3 From 512be8979666a9c62e5ffb8f331d6cd3052623a4 Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Fri, 18 Jul 2025 12:48:48 +0200 Subject: net: introduce CONFIG_DNS Introduce the DNS Kconfig symbol so that various network commands may use host names without the dns command (CMD_DNS) being selected. Signed-off-by: Jerome Forissier CC: E Shattow --- net/Kconfig | 8 +++- net/Makefile | 2 +- net/lwip/Makefile | 1 + net/lwip/dns.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++ net/lwip/net-lwip.c | 6 +-- net/net.c | 10 ++--- net/wget.c | 2 +- 7 files changed, 131 insertions(+), 11 deletions(-) create mode 100644 net/lwip/dns.c (limited to 'net') diff --git a/net/Kconfig b/net/Kconfig index 24508026200..40ec6bbce76 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -244,11 +244,17 @@ config NET_RANDOM_ETHADDR generated. It will be saved to the appropriate environment variable, too. +config DNS + bool "Enable DNS resolutions" + select PROT_DNS_LWIP if NET_LWIP + help + Selecting this will allow the network stack to use server names + in addition to IP addresses. + config WGET bool "Enable wget" select PROT_TCP if NET select PROT_TCP_LWIP if NET_LWIP - select PROT_DNS_LWIP if NET_LWIP help Selecting this will enable wget, an interface to send HTTP requests via the network stack. diff --git a/net/Makefile b/net/Makefile index d63f62b7c8a..468820186cf 100644 --- a/net/Makefile +++ b/net/Makefile @@ -10,7 +10,7 @@ ifeq ($(CONFIG_NET),y) obj-$(CONFIG_NET) += arp.o obj-$(CONFIG_CMD_BOOTP) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o -obj-$(CONFIG_CMD_DNS) += dns.o +obj-$(CONFIG_DNS) += dns.o obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o obj-$(CONFIG_IPV6) += ndisc.o obj-$(CONFIG_$(PHASE_)DM_ETH) += net.o diff --git a/net/lwip/Makefile b/net/lwip/Makefile index 09c3b3511a4..1b48ae4d508 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_DNS) += dns.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/dns.c b/net/lwip/dns.c new file mode 100644 index 00000000000..9964003195f --- /dev/null +++ b/net/lwip/dns.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2024 Linaro Ltd. */ + +#include +#include +#include +#include +#include +#include +#include + +#define DNS_RESEND_MS 1000 +#define DNS_TIMEOUT_MS 10000 + +struct dns_cb_arg { + ip_addr_t host_ipaddr; + const char *var; + bool done; +}; + +static void do_dns_tmr(void *arg) +{ + dns_tmr(); +} + +static void dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg) +{ + struct dns_cb_arg *dns_cb_arg = arg; + char *ipstr = ip4addr_ntoa(ipaddr); + + dns_cb_arg->done = true; + + if (!ipaddr) { + printf("DNS: host not found\n"); + dns_cb_arg->host_ipaddr.addr = 0; + return; + } + + dns_cb_arg->host_ipaddr.addr = ipaddr->addr; + + if (dns_cb_arg->var) + env_set(dns_cb_arg->var, ipstr); +} + +static int dns_loop(struct udevice *udev, const char *name, const char *var) +{ + struct dns_cb_arg dns_cb_arg = { }; + struct netif *netif; + ip_addr_t ipaddr; + ulong start; + int ret; + + dns_cb_arg.var = var; + + netif = net_lwip_new_netif(udev); + if (!netif) + return CMD_RET_FAILURE; + + if (net_lwip_dns_init()) { + net_lwip_remove_netif(netif); + return CMD_RET_FAILURE; + } + + dns_cb_arg.done = false; + + ret = dns_gethostbyname(name, &ipaddr, dns_cb, &dns_cb_arg); + + if (ret == ERR_OK) { + dns_cb(name, &ipaddr, &dns_cb_arg); + } else if (ret == ERR_INPROGRESS) { + start = get_timer(0); + sys_timeout(DNS_RESEND_MS, do_dns_tmr, NULL); + do { + net_lwip_rx(udev, netif); + if (dns_cb_arg.done) + break; + if (ctrlc()) { + printf("\nAbort\n"); + break; + } + } while (get_timer(start) < DNS_TIMEOUT_MS); + sys_untimeout(do_dns_tmr, NULL); + } + + net_lwip_remove_netif(netif); + + if (dns_cb_arg.done && dns_cb_arg.host_ipaddr.addr != 0) { + if (!var) + printf("%s\n", ipaddr_ntoa(&ipaddr)); + return CMD_RET_SUCCESS; + } + + return CMD_RET_FAILURE; +} + +int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + char *name; + char *var = NULL; + + if (argc == 1 || argc > 3) + return CMD_RET_USAGE; + + name = argv[1]; + + if (argc == 3) + var = argv[2]; + + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; + + return dns_loop(eth_get_dev(), name, var); +} diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index 660ceb10cbe..74cbc7e4bf5 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -147,7 +147,7 @@ static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip, */ int net_lwip_dns_init(void) { -#if CONFIG_IS_ENABLED(CMD_DNS) +#if CONFIG_IS_ENABLED(DNS) bool has_server = false; ip_addr_t ns; char *nsenv; @@ -364,7 +364,7 @@ int net_lwip_rx(struct udevice *udev, struct netif *netif) */ int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip) { -#if defined(CONFIG_CMD_DNS) +#if defined(CONFIG_DNS) char *var = "_dnsres"; char *argv[] = { "dns", name_or_ip, var, NULL }; int argc = ARRAY_SIZE(argv) - 1; @@ -373,7 +373,7 @@ int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip) if (ipaddr_aton(name_or_ip, ip)) return 0; -#if defined(CONFIG_CMD_DNS) +#if defined(CONFIG_DNS) if (do_dns(NULL, 0, argc, argv) != CMD_RET_SUCCESS) return -1; diff --git a/net/net.c b/net/net.c index ac9b65c0ca4..f579f6ac5bc 100644 --- a/net/net.c +++ b/net/net.c @@ -114,7 +114,7 @@ #include "bootp.h" #include "cdp.h" #include "dhcpv6.h" -#if defined(CONFIG_CMD_DNS) +#if defined(CONFIG_DNS) #include "dns.h" #endif #include "link_local.h" @@ -287,7 +287,7 @@ static int on_vlan(const char *name, const char *value, enum env_op op, } U_BOOT_ENV_CALLBACK(vlan, on_vlan); -#if defined(CONFIG_CMD_DNS) +#if defined(CONFIG_DNS) static int on_dnsip(const char *name, const char *value, enum env_op op, int flags) { @@ -581,7 +581,7 @@ restart: nc_start(); break; #endif -#if defined(CONFIG_CMD_DNS) +#if defined(CONFIG_DNS) case DNS: dns_start(); break; @@ -1506,7 +1506,7 @@ static int net_check_prereq(enum proto_t protocol) } goto common; #endif -#if defined(CONFIG_CMD_DNS) +#if defined(CONFIG_DNS) case DNS: if (net_dns_server.s_addr == 0) { puts("*** ERROR: DNS server address not given\n"); @@ -1539,7 +1539,7 @@ static int net_check_prereq(enum proto_t protocol) return 1; } #if defined(CONFIG_CMD_PING) || \ - defined(CONFIG_CMD_DNS) || defined(CONFIG_PROT_UDP) + defined(CONFIG_DNS) || defined(CONFIG_PROT_UDP) common: #endif /* Fall through */ diff --git a/net/wget.c b/net/wget.c index 428ee072330..d3642958bf0 100644 --- a/net/wget.c +++ b/net/wget.c @@ -393,7 +393,7 @@ int wget_do_request(ulong dst_addr, char *uri) if (string_to_ip(host_name).s_addr) { s = host_name; } else { -#if IS_ENABLED(CONFIG_CMD_DNS) +#if IS_ENABLED(CONFIG_DNS) net_dns_resolve = host_name; net_dns_env_var = "httpserverip"; if (net_loop(DNS) < 0) { -- cgit v1.2.3 From 90c05f68fcab57d669233033d34e52b8d55d57dd Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Mon, 4 Aug 2025 14:51:01 +0200 Subject: net: lwip: ping: set net_try_count to 1 The legacy network stack sets net_try_count to 1 at the beginning of the net_loop() function. This is required for net_start_again() to work properly. Therefore, set the variable accordingly in the do_ping() function when NET_LWIP=y. This fixes an issue where a ping to an unreachable destination would run twice on the same network device. For example with qemu_arm64_lwip_defconfig: => dhcp DHCP client bound to address 10.0.2.15 (3 ms) => ping 10.0.0.1 Using virtio-net#32 device ping failed; host 10.0.0.1 is not alive Using virtio-net#32 device ping failed; host 10.0.0.1 is not alive => QEMU: Terminated Signed-off-by: Jerome Forissier --- net/lwip/net-lwip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index 74cbc7e4bf5..1a70cedfb58 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -27,7 +27,7 @@ #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER) void (*push_packet)(void *, int len) = 0; #endif -static int net_try_count; +int net_try_count; static int net_restarted; int net_restart_wrap; static uchar net_pkt_buf[(PKTBUFSRX) * PKTSIZE_ALIGN + PKTALIGN]; -- cgit v1.2.3