[PATCH] net: introduce CONFIG_DNS
Jerome Forissier
jerome.forissier at linaro.org
Mon Jul 21 15:46:04 CEST 2025
Hi E,
On 7/19/25 06:20, E Shattow wrote:
> There is a crash with ping command: I apply the patch and enable
> CONFIG_DNS for a build of starfive_visionfive2_defconfig on Pine64
> Star64 board.
>
> # ping invalid
>
> ethernet at 16030000 Waiting for PHY auto negotiation to complete....... done
> No valid name server (dnsip/dnsip2)
> ping - send ICMP ECHO_REQUEST to network host
>
> Usage:
> ping pingAddressOrHostName
>
> # dhcp
> DHCP client bound to address N.N.N.N (31 ms)
>
> # ping invalid
>
> Unhandled exception: Load access fault
> EPC: 00000000fffa365a RA: 00000000fffafa92 TVAL: 0000000000000000
> EPC: 000000004026e65a RA: 000000004027aa92 reloc adjusted
>
> SP: 00000000ff717b90 GP: 00000000ff724e40 TP: 0000000000000003
> T0: 00000000ff717ce4 T1: fffffffffe02a8c0 T2: 0000000000000007
> S0: 00000000ff717e38 S1: 0000000000000000 A0: 0000000000000000
> A1: 00000000ffffd648 A2: 0000000000000010 A3: 0000000000000000
> A4: 00000000fffafa80 A5: 0000000000000000 A6: 0000000000000001
> A7: 0000000000000001 S2: 0000000000000000 S3: 0000000000000019
> S4: 0000000000010000 S5: 00000000fffb0f48 S6: 00000000000000c0
> S7: 00000000ffffd428 S8: 0000000000000000 S9: 0000000000000000
> S10: 00000000ff737db0 S11: 0000000000000001 T3: 00000000ff737e10
> T4: 0000000000000035 T5: ffffffffffffffff T6: 00000000ff717ce0
>
> Code: 171b 0187 969b 0106 8f55 bfe9 4501 b749 (411c)
Not reproducible here, neither on arm64 QEMU nor ZynqMP KV260.
----------------------------------
$ grep -E -e NET_LWIP -e _DNS .config
# CONFIG_CMD_DNS is not set
CONFIG_NET_LWIP=y
CONFIG_PROT_DNS_LWIP=y
CONFIG_DNS=y
----------------------------------
ZynqMP> ping invalid
No valid name server (dnsip/dnsip2)
ping - send ICMP ECHO_REQUEST to network host
Usage:
ping pingAddressOrHostName
ZynqMP> dhcp
DHCP client bound to address 192.168.0.12 (2047 ms)
ZynqMP> ping invalid
DNS: host not found
ping - send ICMP ECHO_REQUEST to network host
Usage:
ping pingAddressOrHostName
----------------------------------
Could you please debug further on you platform and point me to what's
going wrong?
>
> On 7/18/25 03:48, Jerome Forissier wrote:
>> 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 <jerome.forissier at linaro.org>
>> CC: E Shattow <e at freeshell.de>
>> ---
>>
>> cmd/Kconfig | 2 +-
>> cmd/lwip/dns.c | 108 ---------------------------------------
>> doc/usage/cmd/sntp.rst | 8 +--
>> doc/usage/cmd/wget.rst | 2 +-
>> include/net-legacy.h | 2 +-
>> 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 +-
>> 12 files changed, 138 insertions(+), 126 deletions(-)
>> create mode 100644 net/lwip/dns.c
>>
>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>> index b3b5be1ea79..7a9c4ddb215 100644
>> --- a/cmd/Kconfig
>> +++ b/cmd/Kconfig
>> @@ -2110,7 +2110,7 @@ config CMD_DHCP
>>
>> config CMD_DNS
>> bool "dns"
>> - select PROT_DNS_LWIP if NET_LWIP
>> + select DNS
>> help
>> Lookup the IP of a hostname
>>
>> diff --git a/cmd/lwip/dns.c b/cmd/lwip/dns.c
>> index b5fccc7433e..3eb698b3f82 100644
>> --- a/cmd/lwip/dns.c
>> +++ b/cmd/lwip/dns.c
>> @@ -2,115 +2,7 @@
>> /* Copyright (C) 2024 Linaro Ltd. */
>>
>> #include <command.h>
>> -#include <console.h>
>> -#include <env.h>
>> -#include <lwip/dns.h>
>> -#include <lwip/timeouts.h>
>> #include <net.h>
>> -#include <time.h>
>>
>> U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname",
>> "hostname [envvar]");
>> -
>> -#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/doc/usage/cmd/sntp.rst b/doc/usage/cmd/sntp.rst
>> index d97f83053f7..2046828130d 100644
>> --- a/doc/usage/cmd/sntp.rst
>> +++ b/doc/usage/cmd/sntp.rst
>> @@ -12,7 +12,7 @@ Synopsis
>> ::
>>
>> sntp [serverip]
>> - sntp [servername] # NET_LWIP=y && CMD_DNS=y only
>> + sntp [servername] # NET_LWIP=y && DNS=y only
>>
>>
>> Description
>> @@ -27,8 +27,8 @@ The address of the NTP server does not need to be given if the DHCP server
>> provides one. The legacy network stack (`CONFIG_NET=y`) can only use the
>> first NTP server provided in the `ntp-servers` DHCP option.
>>
>> -When the network stack is lwIP (`CONFIG_NET_LWIP=y`) and the dns command
>> -is enabled (`CONFIG_CMD_DNS=y`), then the sntp command accepts a server
>> +When the network stack is lwIP (`CONFIG_NET_LWIP=y`) and DNS resolution
>> +is enabled (`CONFIG_DNS=y`), then the sntp command accepts a server
>> name as an argument.
>>
>> The network time is sent as UTC. So, if you want to set the RTC to any local
>> @@ -61,7 +61,7 @@ Examples
>> => date
>> Date: 2025-06-16 (Monday) Time: 17:19:57
>>
>> -With `CONFIG_NET_LWIP=y` and `CONFIG_CMD_DNS=y`:
>> +With `CONFIG_NET_LWIP=y` and `CONFIG_DNS=y`:
>>
>> ::
>>
>> diff --git a/doc/usage/cmd/wget.rst b/doc/usage/cmd/wget.rst
>> index 06df2842549..8feda0248b2 100644
>> --- a/doc/usage/cmd/wget.rst
>> +++ b/doc/usage/cmd/wget.rst
>> @@ -38,7 +38,7 @@ address
>> memory address for the data downloaded
>>
>> host
>> - IP address (or host name if `CONFIG_CMD_DNS` is enabled) of the HTTP
>> + IP address (or host name if `CONFIG_DNS` is enabled) of the HTTP
>> server, defaults to the value of environment variable *serverip*.
>>
>> path
>> diff --git a/include/net-legacy.h b/include/net-legacy.h
>> index a7dbcec1506..7ba5148a75a 100644
>> --- a/include/net-legacy.h
>> +++ b/include/net-legacy.h
>> @@ -316,7 +316,7 @@ extern u32 net_boot_file_size;
>> /* Boot file size in blocks as reported by the DHCP server */
>> extern u32 net_boot_file_expected_size_in_blocks;
>>
>> -#if defined(CONFIG_CMD_DNS)
>> +#if defined(CONFIG_DNS)
>> extern char *net_dns_resolve; /* The host to resolve */
>> extern char *net_dns_env_var; /* the env var to put the ip into */
>> #endif
>> 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.
>> +
>
> Perhaps instead of CONFIG_DNS then the CONFIG_NET_DNS_LWIP symbol? or
> CONFIG_NET_DNS if it will coexist with both legacy network stack and
> LwIP.
CONFIG_DNS is indeed targeted at NET_LWIP and legacy NET as well. That is,
regardless of NET vs NET_LWIP, one should be able to disable CMD_DNS and
still have DNS support in the other commands.
I do not think CONFIG_NET_DNS is better than CONFIG_DNS. The shorter the
Kconfig symbols the better (to some extent of course). It is quite obvious
that DNS is a network thing.
> That is unless you foresee a build of U-Boot without any
> networking support but having CONFIG_DNS symbol as a requisite for tools
> that do DNS certificate processing i.e.
No, no, if this kind of need arises we will find a suitable Kconfig symbol
I'm sure.
> If DHCP is likewise separated out you might not need the 'dhcp' command
> as in for EFI but still using the protocol.
Makes sense.
> I'm not sure why you want to
> add a CONFIG_DNS instead of just exposing the protocol symbols,
Because lwIP does have a protocol symbol (CONFIG_PROT_DNS_LWIP) but the
legacy NET does not. CONFIG_PROT_DNS_LWIP is just a clean way to set
a couple of defines for lwIP internal use (LWIP_DNS and DNS_TABLE_SIZE).
> unless,
> there are topical things or situations where portions of supporting code
> are needed without the presence of networking.
>
>> 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 97299d9b542..90d3300bd12 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_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 <command.h>
>> +#include <console.h>
>> +#include <env.h>
>> +#include <lwip/dns.h>
>> +#include <lwip/timeouts.h>
>> +#include <net.h>
>> +#include <time.h>
>> +
>> +#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 3918d57d7e5..7069e56065f 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;
>> @@ -369,7 +369,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;
>> @@ -378,7 +378,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 5219367e391..382a27e0a77 100644
>> --- a/net/net.c
>> +++ b/net/net.c
>> @@ -115,7 +115,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"
>> @@ -288,7 +288,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)
>> {
>> @@ -582,7 +582,7 @@ restart:
>> nc_start();
>> break;
>> #endif
>> -#if defined(CONFIG_CMD_DNS)
>> +#if defined(CONFIG_DNS)
>> case DNS:
>> dns_start();
>> break;
>> @@ -1507,7 +1507,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");
>> @@ -1540,7 +1540,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 3c0fff488eb..e65ce15ccb3 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) {
>
> If hostnames are valid then it does appear to be working for commands
> ping and wget. I do not think there was a crash for wget.
OK. Thanks for testing.
>
> best regards,
>
> -E Shattow
Regards,
--
Jerome
More information about the U-Boot
mailing list