[PATCH v2 3/3] net: lwip: introduce net_lwip_eth_stop() function
Jerome Forissier
jerome.forissier at arm.com
Wed May 13 09:57:01 CEST 2026
On 12/05/2026 23:48, David Lechner wrote:
> Add a introduce net_lwip_eth_stop() function and use that to stop the
> network interface after each command that uses the network.
>
> This makes the behavior the same as the legacy net code and avoids
> potential issues with the network interface being left in an active
> state after a command finishes.
>
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---
> cmd/lwip/ping.c | 10 ++++++++--
> cmd/lwip/sntp.c | 10 ++++++++--
> include/net-lwip.h | 1 +
> net/lwip/dhcp.c | 15 +++++++++++----
> net/lwip/dns.c | 7 ++++++-
> net/lwip/net-lwip.c | 5 +++++
> net/lwip/nfs.c | 4 ++++
> net/lwip/tftp.c | 4 ++++
> net/lwip/wget.c | 5 ++++-
> 9 files changed, 51 insertions(+), 10 deletions(-)
>
> diff --git a/cmd/lwip/ping.c b/cmd/lwip/ping.c
> index fc4cf7bde5f..836d1d8287f 100644
> --- a/cmd/lwip/ping.c
> +++ b/cmd/lwip/ping.c
> @@ -163,6 +163,7 @@ static int ping_loop(struct udevice *udev, const ip_addr_t *addr)
> int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> {
> ip_addr_t addr;
> + int ret = CMD_RET_FAILURE;
>
> if (argc < 2)
> return CMD_RET_USAGE;
> @@ -176,8 +177,13 @@ restart:
> if (net_start_again() == 0)
> goto restart;
> else
> - return CMD_RET_FAILURE;
> + goto out;
> }
>
> - return CMD_RET_SUCCESS;
> + ret = CMD_RET_SUCCESS;
> +
> +out:
> + net_lwip_eth_stop();
> +
> + return ret;
> }
> diff --git a/cmd/lwip/sntp.c b/cmd/lwip/sntp.c
> index 608345c873b..5fa400b104a 100644
> --- a/cmd/lwip/sntp.c
> +++ b/cmd/lwip/sntp.c
> @@ -101,6 +101,7 @@ int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> ip_addr_t *srvip;
> char *server;
> ip_addr_t ipaddr;
> + int ret = CMD_RET_FAILURE;
>
> switch (argc) {
> case 1:
> @@ -127,7 +128,12 @@ int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> return CMD_RET_FAILURE;
>
> if (sntp_loop(eth_get_dev(), srvip) < 0)
> - return CMD_RET_FAILURE;
> + goto out;
> +
> + ret = CMD_RET_SUCCESS;
> +
> +out:
> + net_lwip_eth_stop();
>
> - return CMD_RET_SUCCESS;
> + return ret;
> }
> diff --git a/include/net-lwip.h b/include/net-lwip.h
> index 20cb0992cce..5d0627eb271 100644
> --- a/include/net-lwip.h
> +++ b/include/net-lwip.h
> @@ -35,6 +35,7 @@ int eth_init_state_only(void); /* Set active state */
>
> int net_lwip_dns_init(void);
> int net_lwip_eth_start(void);
> +void net_lwip_eth_stop(void);
> struct netif *net_lwip_new_netif(struct udevice *udev);
> struct netif *net_lwip_new_netif_noip(struct udevice *udev);
> void net_lwip_remove_netif(struct netif *netif);
> diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c
> index acdf601d7eb..18dc36ae7ca 100644
> --- a/net/lwip/dhcp.c
> +++ b/net/lwip/dhcp.c
> @@ -138,18 +138,25 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> dev = eth_get_dev();
> if (!dev) {
> log_err("No network device\n");
> - return CMD_RET_FAILURE;
> + ret = CMD_RET_FAILURE;
> + goto out;
> }
>
> ret = dhcp_loop(dev);
> if (ret)
> - return ret;
> + goto out;
>
> if (argc > 1) {
> struct cmd_tbl cmdtp = {};
>
> - return do_tftpb(&cmdtp, 0, argc, argv);
> + ret = do_tftpb(&cmdtp, 0, argc, argv);
> + goto out;
do_tftpb() already takes care of net_lwip_eth_stop() so this should
probably be:
+ return do_tftpb(&cmdtp, 0, argc, argv);
But this also raises the qestion of the double call to
net_lwip_eth_start():
do_dhcp()
net_lwip_eth_start()
do_tftpb()
net_lwip_eth_start()
How about adding a static counter to better deal with the nested case?
static int net_lwip_eth_started;
int net_lwip_eth_start(void)
{
int ret;
if (net_lwip_eth_started++ > 0)
return 0;
ret = eth_init();
if (ret) {
net_lwip_eth_started--;
return ret;
}
return 0;
}
void net_lwip_eth_stop(void)
{
if (!net_lwip_eth_started)
return;
if (--net_lwip_eth_started)
return;
eth_halt();
}
Thanks,
--
Jerome
> }
>
> - return CMD_RET_SUCCESS;
> + ret = CMD_RET_SUCCESS;
> +
> +out:
> + net_lwip_eth_stop();
> +
> + return ret;
> }
> diff --git a/net/lwip/dns.c b/net/lwip/dns.c
> index 8b7b3b7f970..b620b0611d6 100644
> --- a/net/lwip/dns.c
> +++ b/net/lwip/dns.c
> @@ -91,6 +91,7 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> {
> char *name;
> char *var = NULL;
> + int ret;
>
> if (argc == 1 || argc > 3)
> return CMD_RET_USAGE;
> @@ -103,5 +104,9 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> if (net_lwip_eth_start() < 0)
> return CMD_RET_FAILURE;
>
> - return dns_loop(eth_get_dev(), name, var);
> + ret = dns_loop(eth_get_dev(), name, var);
> +
> + net_lwip_eth_stop();
> +
> + return ret;
> }
> diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c
> index 0c83c004cab..be63531c2a2 100644
> --- a/net/lwip/net-lwip.c
> +++ b/net/lwip/net-lwip.c
> @@ -192,6 +192,11 @@ int net_lwip_eth_start(void)
> return 0;
> }
>
> +void net_lwip_eth_stop(void)
> +{
> + eth_halt();
> +}
> +
> static struct netif *new_netif(struct udevice *udev, bool with_ip)
> {
> unsigned char enetaddr[ARP_HLEN];
> diff --git a/net/lwip/nfs.c b/net/lwip/nfs.c
> index 9e6b801e465..4cc36373fdd 100644
> --- a/net/lwip/nfs.c
> +++ b/net/lwip/nfs.c
> @@ -187,6 +187,7 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname,
> int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> {
> int ret = CMD_RET_SUCCESS;
> + bool started = false;
> char *arg = NULL;
> char *words[2] = { };
> char *fname = NULL;
> @@ -281,10 +282,13 @@ int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> ret = CMD_RET_FAILURE;
> goto out;
> }
> + started = true;
>
> if (nfs_loop(eth_get_dev(), laddr, fname, srvip) < 0)
> ret = CMD_RET_FAILURE;
> out:
> + if (started)
> + net_lwip_eth_stop();
> if (arg != net_boot_file_name)
> free(arg);
> return ret;
> diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c
> index 7f3b28b8507..571c38172f9 100644
> --- a/net/lwip/tftp.c
> +++ b/net/lwip/tftp.c
> @@ -261,6 +261,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
> int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> {
> int ret = CMD_RET_SUCCESS;
> + bool started = false;
> char *arg = NULL;
> char *words[3] = { };
> char *fname = NULL;
> @@ -365,12 +366,15 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> ret = CMD_RET_FAILURE;
> goto out;
> }
> + started = true;
>
> if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0)
> ret = CMD_RET_FAILURE;
> else
> image_load_addr = laddr;
> out:
> + if (started)
> + net_lwip_eth_stop();
> if (arg != net_boot_file_name)
> free(arg);
> return ret;
> diff --git a/net/lwip/wget.c b/net/lwip/wget.c
> index 3a0b0dca145..247ece18e2b 100644
> --- a/net/lwip/wget.c
> +++ b/net/lwip/wget.c
> @@ -416,12 +416,15 @@ int wget_do_request(ulong dst_addr, char *uri)
> udev = eth_get_dev();
>
> netif = net_lwip_new_netif(udev);
> - if (!netif)
> + if (!netif) {
> + net_lwip_eth_stop();
> return -ENODEV;
> + }
>
> ret = wget_handle_request(&ctx, is_https, udev, netif);
>
> net_lwip_remove_netif(netif);
> + net_lwip_eth_stop();
>
> return ret;
> }
>
More information about the U-Boot
mailing list