On 6/3/25 07:51, Heinrich Schuchardt wrote:
> Am 2. Juni 2025 23:23:08 MESZ schrieb Heinrich Schuchardt 
> <xypron.g...@gmx.de>:
>> Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier 
>> <jerome.foriss...@linaro.org>:
>>> Implement the sntp command when NET_LWIP=y.
> 
> https://datatracker.ietf.org/doc/rfc5905/ describes that on Feb 7th, 2036 the 
> 32 bit seconds field wraps around and era 1 starts.
> 
> Does our code consider this?

I don't know. The lwIP code seems to somewhat take care of the year 2036
issue [1] but I need to spend more time understanding what's happening
here to be certain.

[1] 
https://github.com/u-boot/u-boot/blob/d1555de5fa21c06118540dcd4a627a1af29bbb40/lib/lwip/lwip/src/apps/sntp/sntp.c#L141

Thanks,
-- 
Jerome

> 
> Best regards 
> 
> Heinrich
> 
> 
> 
>>>
>>> Signed-off-by: Jerome Forissier <jerome.foriss...@linaro.org>
>>> ---
>>>
>>> cmd/Kconfig                |  13 ++--
>>> cmd/net-lwip.c             |   5 ++
>>> include/net-common.h       |  11 ++++
>>> lib/lwip/Makefile          |   1 +
>>> lib/lwip/u-boot/arch/cc.h  |   4 ++
>>> lib/lwip/u-boot/lwipopts.h |   4 ++
>>> net/lwip/Makefile          |   1 +
>>> net/lwip/sntp.c            | 128 +++++++++++++++++++++++++++++++++++++
>>> 8 files changed, 161 insertions(+), 6 deletions(-)
>>> create mode 100644 net/lwip/sntp.c
>>>
>>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>>> index f21d27cb27f..58f629e1c34 100644
>>> --- a/cmd/Kconfig
>>> +++ b/cmd/Kconfig
>>> @@ -2061,12 +2061,6 @@ config CMD_CDP
>>>       and to retrieve configuration data including the VLAN id using the
>>>       proprietary Cisco Discovery Protocol (CDP).
>>>
>>> -config CMD_SNTP
>>> -   bool "sntp"
>>> -   select PROT_UDP
>>> -   help
>>> -     Synchronize RTC via network
>>> -
>>> config CMD_LINK_LOCAL
>>>     bool "linklocal"
>>>     depends on (LIB_RAND || LIB_HW_RAND)
>>> @@ -2144,6 +2138,13 @@ config CMD_PING
>>>     help
>>>       Send ICMP ECHO_REQUEST to network host
>>>
>>> +config CMD_SNTP
>>
>> The command should depend on RTC support.
>>
>>> +   bool "sntp"
>>> +   select PROT_UDP if NET
>>> +   select PROT_UDP_LWIP if NET_LWIP
>>> +   help
>>> +     Synchronize RTC via network
>>> +
>>> config CMD_TFTPBOOT
>>>     bool "tftp"
>>>     select PROT_UDP_LWIP if NET_LWIP
>>> diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c
>>> index cecf8d02555..2ffee64f97e 100644
>>> --- a/cmd/net-lwip.c
>>> +++ b/cmd/net-lwip.c
>>
>> Please, put every command into a separate file instead of duplicating the 
>> #ifdef chaos of the old network stack.
>>
>>> @@ -21,6 +21,11 @@ U_BOOT_CMD(tftpboot, 3, 0, do_tftpb,
>>>        "[loadAddress] [[hostIPaddr:]bootfilename]");
>>> #endif
>>>
>>> +#if defined(CONFIG_CMD_SNTP)
>>> +U_BOOT_CMD(sntp, 2, 1, do_sntp, "synchronize RTC via network",
>>> +      "[NTP server IP]");
>>> +#endif
>>
>> Why wouldn't we support server names ( e.g.  0.de.pool.ntp.org) here if we 
>> have DNS enabled?
>>
>> Please, add the missing documentation change for the commands.
>>
>> Best regards
>>
>> Heinrich
>>
>>
>>> +
>>> #if defined(CONFIG_CMD_DNS)
>>> U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname",
>>>        "hostname [envvar]");
>>> diff --git a/include/net-common.h b/include/net-common.h
>>> index a021bf503ff..b06cafb497e 100644
>>> --- a/include/net-common.h
>>> +++ b/include/net-common.h
>>> @@ -505,6 +505,17 @@ int dhcp_run(ulong addr, const char *fname, bool 
>>> autoload);
>>>  */
>>> int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>>>
>>> +/**
>>> + * do_sntp - Run the sntp command
>>> + *
>>> + * @cmdtp: Unused
>>> + * @flag: Command flags (CMD_FLAG_...)
>>> + * @argc: Number of arguments
>>> + * @argv: List of arguments
>>> + * Return: result (see enum command_ret_t)
>>> + */
>>> +int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>>> +
>>> /**
>>>  * do_tftpb - Run the tftpboot command
>>>  *
>>> diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile
>>> index e9e8caee93a..c3f0e916f66 100644
>>> --- a/lib/lwip/Makefile
>>> +++ b/lib/lwip/Makefile
>>> @@ -13,6 +13,7 @@ obj-y += \
>>>     lwip/src/api/sockets.o \
>>>     lwip/src/api/tcpip.o \
>>>     lwip/src/apps/http/http_client.o \
>>> +   lwip/src/apps/sntp/sntp.o \
>>>     lwip/src/apps/tftp/tftp.o \
>>>     lwip/src/core/altcp_alloc.o \
>>>     lwip/src/core/altcp.o \
>>> diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h
>>> index 6104c296f6f..f91127ac565 100644
>>> --- a/lib/lwip/u-boot/arch/cc.h
>>> +++ b/lib/lwip/u-boot/arch/cc.h
>>> @@ -43,4 +43,8 @@
>>> #define BYTE_ORDER BIG_ENDIAN
>>> #endif
>>>
>>> +#define SNTP_STARTUP_DELAY 0
>>> +void sntp_set_system_time(uint32_t sec);
>>> +#define SNTP_SET_SYSTEM_TIME(sec) sntp_set_system_time(sec)
>>> +
>>> #endif /* LWIP_ARCH_CC_H */
>>> diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h
>>> index edac74ff7a2..14ba7bd7ae2 100644
>>> --- a/lib/lwip/u-boot/lwipopts.h
>>> +++ b/lib/lwip/u-boot/lwipopts.h
>>> @@ -162,4 +162,8 @@
>>> #define LWIP_ALTCP_TLS_MBEDTLS          1
>>> #endif
>>>
>>> +#if defined(CONFIG_CMD_SNTP)
>>> +#define LWIP_DHCP_GET_NTP_SRV 1
>>> +#endif
>>> +
>>> #endif /* LWIP_UBOOT_LWIPOPTS_H */
>>> diff --git a/net/lwip/Makefile b/net/lwip/Makefile
>>> index 5df222589b8..5bb98dc4d98 100644
>>> --- a/net/lwip/Makefile
>>> +++ b/net/lwip/Makefile
>>> @@ -4,6 +4,7 @@ obj-$(CONFIG_$(PHASE_)DM_ETH) += net-lwip.o
>>> obj-$(CONFIG_CMD_DHCP) += dhcp.o
>>> obj-$(CONFIG_CMD_DNS) += dns.o
>>> obj-$(CONFIG_CMD_PING) += ping.o
>>> +obj-$(CONFIG_CMD_SNTP) += sntp.o
>>> obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
>>> obj-$(CONFIG_WGET) += wget.o
>>>
>>> diff --git a/net/lwip/sntp.c b/net/lwip/sntp.c
>>> new file mode 100644
>>> index 00000000000..3b2bc3c679d
>>> --- /dev/null
>>> +++ b/net/lwip/sntp.c
>>> @@ -0,0 +1,128 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/* Copyright (C) 2025 Linaro Ltd. */
>>> +
>>> +#include <command.h>
>>> +#include <console.h>
>>> +#include <dm/device.h>
>>> +#include <lwip/apps/sntp.h>
>>> +#include <lwip/timeouts.h>
>>> +#include <net.h>
>>> +
>>> +#define SNTP_TIMEOUT 10000
>>> +
>>> +static enum done_state {
>>> +   NOT_DONE = 0,
>>> +   SUCCESS,
>>> +   ABORTED,
>>> +   TIMED_OUT
>>> +} sntp_state;
>>> +
>>> +static void no_response(void *arg)
>>> +{
>>> +   sntp_state = TIMED_OUT;
>>> +}
>>> +
>>> +/* Called by lwIP via the SNTP_SET_SYSTEM_TIME() macro */
>>> +void sntp_set_system_time(uint32_t seconds)
>>> +{
>>> +   char *toff;
>>> +   int net_ntp_time_offset = 0;
>>> +
>>> +   toff = env_get("timeoffset");
>>> +   if (toff)
>>> +           net_ntp_time_offset = simple_strtol(toff, NULL, 10);
>>> +
>>> +   net_sntp_set_rtc(seconds + net_ntp_time_offset);
>>> +   sntp_state = SUCCESS;
>>> +}
>>> +
>>> +static bool ntp_server_known(void)
>>> +{
>>> +   int i;
>>> +
>>> +   for (i = 0; i < SNTP_MAX_SERVERS; i++) {
>>> +           const ip_addr_t *ip = sntp_getserver(i);
>>> +
>>> +           if (ip && ip->addr)
>>> +                   return true;
>>> +   }
>>> +
>>> +   return false;
>>> +}
>>> +
>>> +static int sntp_loop(struct udevice *udev, ip_addr_t *srvip)
>>> +{
>>> +   struct netif *netif;
>>> +
>>> +   netif = net_lwip_new_netif(udev);
>>> +   if (!netif)
>>> +           return -1;
>>> +
>>> +   sntp_state = NOT_DONE;
>>> +
>>> +   sntp_setoperatingmode(SNTP_OPMODE_POLL);
>>> +   sntp_servermode_dhcp(CONFIG_IS_ENABLED(CMD_DHCP));
>>> +   if (srvip) {
>>> +           sntp_setserver(0, srvip);
>>> +   } else {
>>> +           if (!ntp_server_known()) {
>>> +                   log_err("error: ntpserverip not set\n");
>>> +                   return -1;
>>> +           }
>>> +   }
>>> +   sntp_init();
>>> +
>>> +   sys_timeout(SNTP_TIMEOUT, no_response, NULL);
>>> +   while (sntp_state == NOT_DONE) {
>>> +           net_lwip_rx(udev, netif);
>>> +           sys_check_timeouts();
>>> +           if (ctrlc()) {
>>> +                   printf("\nAbort\n");
>>> +                   sntp_state = ABORTED;
>>> +                   break;
>>> +           }
>>> +   }
>>> +   sys_untimeout(no_response, NULL);
>>> +
>>> +   sntp_stop();
>>> +   net_lwip_remove_netif(netif);
>>> +
>>> +   if (sntp_state == SUCCESS)
>>> +           return 0;
>>> +
>>> +   return -1;
>>> +}
>>> +
>>> +int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>>> +{
>>> +   ip_addr_t *srvip = NULL;
>>> +   char *server_ip = NULL;
>>> +   ip_addr_t ipaddr;
>>> +
>>> +   switch (argc) {
>>> +   case 1:
>>> +           server_ip = env_get("ntpserverip");
>>> +           break;
>>> +   case 2:
>>> +           server_ip = argv[1];
>>> +           break;
>>> +   default:
>>> +           return CMD_RET_USAGE;
>>> +   }
>>> +
>>> +   if (server_ip) {
>>> +           if (!ipaddr_aton(server_ip, &ipaddr)) {
>>> +                   log_err("error: ipaddr_aton\n");
>>> +                   return CMD_RET_FAILURE;
>>> +           }
>>> +           srvip = &ipaddr;
>>> +   }
>>> +
>>> +   if (net_lwip_eth_start() < 0)
>>> +           return CMD_RET_FAILURE;
>>> +
>>> +   if (sntp_loop(eth_get_dev(), srvip) < 0)
>>> +           return CMD_RET_FAILURE;
>>> +
>>> +   return CMD_RET_SUCCESS;
>>> +}
>>
> 

Reply via email to