From: Sean Edmond <seanedmond@linux.microsoft.com>
To: Peter Robinson <pbrobinson@gmail.com>
Cc: Maxim Uvarov <maxim.uvarov@linaro.org>,
u-boot@lists.denx.de, ilias.apalodimas@linaro.org,
joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com,
goldsimon@gmx.de
Subject: Re: [PATCHv10 14/15] net/lwip: replace original net commands with lwip
Date: Tue, 3 Oct 2023 16:44:08 -0700 [thread overview]
Message-ID: <6ed884d1-427c-2c1d-275f-25eb817aef7c@linux.microsoft.com> (raw)
In-Reply-To: <CALeDE9NkvMbmwZP-7E4_mH3WfFAV==ZX_3PMhk7DKYj5OyFqmQ@mail.gmail.com>
On 2023-10-03 2:58 p.m., Peter Robinson wrote:
> On Tue, Oct 3, 2023 at 6:58 PM Sean Edmond
> <seanedmond@linux.microsoft.com> wrote:
>>
>> On 2023-09-26 2:41 a.m., Maxim Uvarov wrote:
>>
>> Replace original commands: ping, tftp, dhcp and wget.
>>
>> Signed-off-by: Maxim Uvarov<maxim.uvarov@linaro.org>
>> ---
>> boot/bootmeth_efi.c | 18 +++++++---
>> boot/bootmeth_pxe.c | 21 ++++++-----
>> cmd/net.c | 86 +++++----------------------------------------
>> cmd/pxe.c | 19 +++++-----
>> include/net.h | 8 +++--
>> include/net/ulwip.h | 64 +++++++++++++++++++++++++++++++++
>> 6 files changed, 113 insertions(+), 103 deletions(-)
>> create mode 100644 include/net/ulwip.h
>>
>> diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
>> index ae936c8daa..52399d627c 100644
>> --- a/boot/bootmeth_efi.c
>> +++ b/boot/bootmeth_efi.c
>> @@ -20,6 +20,8 @@
>> #include <mapmem.h>
>> #include <mmc.h>
>> #include <net.h>
>> +#include <net/lwip.h>
>> +#include <net/ulwip.h>
>> #include <pxe_utils.h>
>> #include <linux/sizes.h>
>>
>> @@ -319,9 +321,7 @@ static int distro_efi_try_bootflow_files(struct udevice *dev,
>>
>> static int distro_efi_read_bootflow_net(struct bootflow *bflow)
>> {
>> - char file_addr[17], fname[256];
>> - char *tftp_argv[] = {"tftp", file_addr, fname, NULL};
>> - struct cmd_tbl cmdtp = {}; /* dummy */
>> + char fname[256];
>> const char *addr_str, *fdt_addr_str;
>> int ret, arch, size;
>> ulong addr, fdt_addr;
>> @@ -368,7 +368,6 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
>> if (!fdt_addr_str)
>> return log_msg_ret("fdt", -EINVAL);
>> fdt_addr = hextoul(fdt_addr_str, NULL);
>> - sprintf(file_addr, "%lx", fdt_addr);
>>
>> /* We only allow the first prefix with PXE */
>> ret = distro_efi_get_fdt_name(fname, sizeof(fname), 0);
>> @@ -379,7 +378,16 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
>> if (!bflow->fdt_fname)
>> return log_msg_ret("fil", -ENOMEM);
>>
>> - if (!do_tftpb(&cmdtp, 0, 3, tftp_argv)) {
>> + ret = ulwip_init();
>> + if (ret)
>> + return log_msg_ret("ulwip_init", ret);
>> +
>> + ret = ulwip_tftp(fdt_addr, fname);
>> + if (ret)
>> + return log_msg_ret("ulwip_tftp", ret);
>> +
>> + ret = ulwip_loop();
>> + if (!ret) {
>> bflow->fdt_size = env_get_hex("filesize", 0);
>> bflow->fdt_addr = fdt_addr;
>> } else {
>> diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c
>> index 8d489a11aa..fc6aabaa18 100644
>> --- a/boot/bootmeth_pxe.c
>> +++ b/boot/bootmeth_pxe.c
>> @@ -21,6 +21,8 @@
>> #include <mapmem.h>
>> #include <mmc.h>
>> #include <net.h>
>> +#include <net/ulwip.h>
>> +#include <net/lwip.h>
>> #include <pxe_utils.h>
>>
>> static int extlinux_pxe_getfile(struct pxe_context *ctx, const char *file_path,
>> @@ -116,18 +118,21 @@ static int extlinux_pxe_read_file(struct udevice *dev, struct bootflow *bflow,
>> const char *file_path, ulong addr,
>> ulong *sizep)
>> {
>> - char *tftp_argv[] = {"tftp", NULL, NULL, NULL};
>> - struct pxe_context *ctx = dev_get_priv(dev);
>> - char file_addr[17];
>> ulong size;
>> int ret;
>>
>> - sprintf(file_addr, "%lx", addr);
>> - tftp_argv[1] = file_addr;
>> - tftp_argv[2] = (void *)file_path;
>> + ret = ulwip_init();
>> + if (ret)
>> + return log_msg_ret("ulwip_init", ret);
>> +
>> + ret = ulwip_tftp(addr, file_path);
>> + if (ret)
>> + return log_msg_ret("ulwip_tftp", ret);
>> +
>> + ret = ulwip_loop();
>> + if (ret)
>> + return log_msg_ret("ulwip_loop", ret);
>>
>> - if (do_tftpb(ctx->cmdtp, 0, 3, tftp_argv))
>> - return -ENOENT;
>> ret = pxe_get_file_size(&size);
>> if (ret)
>> return log_msg_ret("tftp", ret);
>> diff --git a/cmd/net.c b/cmd/net.c
>> index d407d8320a..dc5a114309 100644
>> --- a/cmd/net.c
>> +++ b/cmd/net.c
>> @@ -22,6 +22,7 @@
>> #include <net/udp.h>
>> #include <net/sntp.h>
>> #include <net/ncsi.h>
>> +#include <net/lwip.h>
>>
>> static int netboot_common(enum proto_t, struct cmd_tbl *, int, char * const []);
>>
>> @@ -40,19 +41,9 @@ U_BOOT_CMD(
>> #endif
>>
>> #ifdef CONFIG_CMD_TFTPBOOT
>> -int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>> -{
>> - int ret;
>> -
>> - bootstage_mark_name(BOOTSTAGE_KERNELREAD_START, "tftp_start");
>> - ret = netboot_common(TFTPGET, cmdtp, argc, argv);
>> - bootstage_mark_name(BOOTSTAGE_KERNELREAD_STOP, "tftp_done");
>> - return ret;
>> -}
>> -
>> #if IS_ENABLED(CONFIG_IPV6)
>> U_BOOT_CMD(
>> - tftpboot, 4, 1, do_tftpb,
>> + tftpboot, 4, 1, do_lwip_tftp,
>>
>> It looks like LWIP doesn't support TFTP with IPv6 addressing. Perhaps we need to fall back onto the existing TFTP implementation until LWIP supports it?
> Is it that LWIP upstream doesn't support IPv6 with TFTP or it just
> hasn't been dealt with in this patch set? If the former might be
> useful to reference details.
Apologies for the misleading comment, LWIP does support IPv6 addressing,
it just hasn't been dealt with in this patch.
>
>> Note, that currently, IPv6 TFTP is enabled using the "-ipv6" argument. The intention is that netboot_common() sees the argument and sets the "use_ip6" variable. It looks like the new implementation in do_lwip_tftp() doesn't re-use the argument parsing in netboot_common() and that it doesn't handle the addition of the "-ipv6" flag.
> Is there a reason why there's a need of an explicit argument for IPv6?
> I would have thought if there was a local IPv6 address assigned that
> you would automatically try IPv6 and if it fails for back to v4, or
> even better do a DNS lookup and use what ever gets returned. Having to
> know what to use by manually specifying a parameter doesn't sound like
> a great user experience, what's the use case?
This how IPv6 was added to the TFTP commands in the initial patch
series. I added the "-ipv6" argument to the PXE commands. At the time
it was accepted that explicit selection was required. In our case, we
try IPv4 and then fallback to IPv6. For example:
< Try IPv4 >
setenv autoload no;
dhcp;
pxe get;
pxe boot;
< If IPv4 fails try IPv6 >
dhcp6;
pxe get -ipv6;
pxe boot -ipv6;
TFTP could intelligently select based on the environment variables. So,
we could try IPv4 first if env variable "serverip" is set, otherwise try
IPv6 if env variable "serverip6" is set. This would make things easier
to use and would simplify the code. It's not clear why the "-ipv6"
argument was used for the TFTP commands in the first place... I'm
guessing it was to provide more control to the user.
>> I support the addition of LWIP, but I'm concerned about how abrupt changes like this one will be for existing users. The underlying stack will change, with no easy way for the user to revert to the previous stack. Has there been any discussion about preserving the existing functionality, with an option to enable/disable LWIP stack? This would give the community time to transition/validate LWIP before deprecating the old u-boot networking stack.
> The problem is how long do we maintain dual stacks, do we default to
> which one, when do we switch the defaults, how long do we wait to
> remove the stack and the maintenance burden on the small amount of
> maintainers?
>
>> "boot image via network using TFTP protocol\n"
>> "To use IPv6 add -ipv6 parameter or use IPv6 hostIPaddr framed "
>> "with [] brackets",
>> @@ -60,7 +51,7 @@ U_BOOT_CMD(
>> );
>> #else
>> U_BOOT_CMD(
>> - tftpboot, 3, 1, do_tftpb,
>> + tftpboot, 3, 1, do_lwip_tftp,
>> "load file via network using TFTP protocol",
>> "[loadAddress] [[hostIPaddr:]bootfilename]"
>> );
>> @@ -139,7 +130,7 @@ U_BOOT_CMD(dhcp6, 3, 1, do_dhcp6,
>> static int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc,
>> char *const argv[])
>> {
>> - return netboot_common(DHCP, cmdtp, argc, argv);
>> + return do_lwip_dhcp();
>> }
>>
>> U_BOOT_CMD(
>> @@ -196,13 +187,11 @@ U_BOOT_CMD(
>> #endif
>>
>> #if defined(CONFIG_CMD_WGET)
>> -static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
>> -{
>> - return netboot_common(WGET, cmdtp, argc, argv);
>> -}
>> +int do_lwip_wget(struct cmd_tbl *cmdtp, int flag, int argc,
>> + char *const argv[]);
>>
>> U_BOOT_CMD(
>> - wget, 3, 1, do_wget,
>> + wget, 3, 1, do_lwip_wget,
>> "boot image via network using HTTP protocol",
>> "[loadAddress] [[hostIPaddr:]path and image name]"
>> );
>> @@ -456,28 +445,8 @@ static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc,
>> }
>>
>> #if defined(CONFIG_CMD_PING)
>> -static int do_ping(struct cmd_tbl *cmdtp, int flag, int argc,
>> - char *const argv[])
>> -{
>> - if (argc < 2)
>> - return CMD_RET_USAGE;
>> -
>> - net_ping_ip = string_to_ip(argv[1]);
>> - if (net_ping_ip.s_addr == 0)
>> - return CMD_RET_USAGE;
>> -
>> - if (net_loop(PING) < 0) {
>> - printf("ping failed; host %s is not alive\n", argv[1]);
>> - return CMD_RET_FAILURE;
>> - }
>> -
>> - printf("host %s is alive\n", argv[1]);
>> -
>> - return CMD_RET_SUCCESS;
>> -}
>> -
>> U_BOOT_CMD(
>> - ping, 2, 1, do_ping,
>> + ping, 2, 1, do_lwip_ping,
>> "send ICMP ECHO_REQUEST to network host",
>> "pingAddress"
>> );
>> @@ -601,45 +570,8 @@ U_BOOT_CMD(
>> #endif
>>
>> #if defined(CONFIG_CMD_DNS)
>> -int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>> -{
>> - if (argc == 1)
>> - return CMD_RET_USAGE;
>> -
>> - /*
>> - * We should check for a valid hostname:
>> - * - Each label must be between 1 and 63 characters long
>> - * - the entire hostname has a maximum of 255 characters
>> - * - only the ASCII letters 'a' through 'z' (case-insensitive),
>> - * the digits '0' through '9', and the hyphen
>> - * - cannot begin or end with a hyphen
>> - * - no other symbols, punctuation characters, or blank spaces are
>> - * permitted
>> - * but hey - this is a minimalist implmentation, so only check length
>> - * and let the name server deal with things.
>> - */
>> - if (strlen(argv[1]) >= 255) {
>> - printf("dns error: hostname too long\n");
>> - return CMD_RET_FAILURE;
>> - }
>> -
>> - net_dns_resolve = argv[1];
>> -
>> - if (argc == 3)
>> - net_dns_env_var = argv[2];
>> - else
>> - net_dns_env_var = NULL;
>> -
>> - if (net_loop(DNS) < 0) {
>> - printf("dns lookup of %s failed, check setup\n", argv[1]);
>> - return CMD_RET_FAILURE;
>> - }
>> -
>> - return CMD_RET_SUCCESS;
>> -}
>> -
>> U_BOOT_CMD(
>> - dns, 3, 1, do_dns,
>> + dns, 3, 1, do_lwip_dns,
>> "lookup the IP of a hostname",
>> "hostname [envvar]"
>> );
>> diff --git a/cmd/pxe.c b/cmd/pxe.c
>> index 677142520b..d44df428d2 100644
>> --- a/cmd/pxe.c
>> +++ b/cmd/pxe.c
>> @@ -8,6 +8,7 @@
>> #include <command.h>
>> #include <fs.h>
>> #include <net.h>
>> +#include <net/lwip.h>
>> #include <net6.h>
>> #include <malloc.h>
>>
>> @@ -29,21 +30,19 @@ const char *pxe_default_paths[] = {
>> static int do_get_tftp(struct pxe_context *ctx, const char *file_path,
>> char *file_addr, ulong *sizep)
>> {
>> - char *tftp_argv[] = {"tftp", NULL, NULL, NULL};
>> + ulong addr;
>> + char *end;
>> int ret;
>> - int num_args;
>>
>> - tftp_argv[1] = file_addr;
>> - tftp_argv[2] = (void *)file_path;
>> + addr = hextoul(file_addr, &end);
>> +
>> if (ctx->use_ipv6) {
>> - tftp_argv[3] = USE_IP6_CMD_PARAM;
>> - num_args = 4;
>> - } else {
>> - num_args = 3;
>> + /* @todo: check and fix me, here */
>>
>> Again, looks like LWIP doesn't support IPv6 addressing, we may want to fall back on existing TFTP implementation here.
>>
>> }
>>
>> - if (do_tftpb(ctx->cmdtp, 0, num_args, tftp_argv))
>> - return -ENOENT;
>> + ret = ulwip_tftp(addr, file_path);
>> + if (ret)
>> + return log_msg_ret("tftp", ret);
>>
>> ret = pxe_get_file_size(sizep);
>> if (ret)
>> diff --git a/include/net.h b/include/net.h
>> index e254df7d7f..de7baeb121 100644
>> --- a/include/net.h
>> +++ b/include/net.h
>> @@ -54,8 +54,10 @@ struct in_addr {
>> __be32 s_addr;
>> };
>>
>> +int do_lwip_dhcp(void);
>> +
>> /**
>> - * do_tftpb - Run the tftpboot command
>> + * do_lwip_tftp - Run the tftpboot command
>> *
>> * @cmdtp: Command information for tftpboot
>> * @flag: Command flags (CMD_FLAG_...)
>> @@ -63,7 +65,7 @@ struct in_addr {
>> * @argv: List of arguments
>> * Return: result (see enum command_ret_t)
>> */
>> -int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>> +int do_lwip_tftp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>>
>> /**
>> * dhcp_run() - Run DHCP on the current ethernet device
>> @@ -514,7 +516,7 @@ extern int net_restart_wrap; /* Tried all network devices */
>> enum proto_t {
>> BOOTP, RARP, ARP, TFTPGET, DHCP, DHCP6, PING, PING6, DNS, NFS, CDP,
>> NETCONS, SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT_UDP, FASTBOOT_TCP,
>> - WOL, UDP, NCSI, WGET, RS
>> + WOL, UDP, NCSI, WGET, RS, LWIP
>> };
>>
>> extern char net_boot_file_name[1024];/* Boot File name */
>> diff --git a/include/net/ulwip.h b/include/net/ulwip.h
>> new file mode 100644
>> index 0000000000..8eac7aa130
>> --- /dev/null
>> +++ b/include/net/ulwip.h
>> @@ -0,0 +1,64 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +
>> +/**
>> + * ulwip_init() - initialize lwIP network stack
>> + *
>> + * @return 0 if success, !0 if error
>> + */
>> +int ulwip_init(void);
>> +
>> +/**
>> + * ulwip_enabled() - check if lwIP network stack was initialized
>> + *
>> + * @return 1 lwip initialized, 0 if not yet initialized
>> + */
>> +int ulwip_enabled(void);
>> +
>> +/**
>> + * ulwip_in_loop() - lwIP controls packet net loop
>> + *
>> + * @return 1 lwIP owns packet loop, 0 lwip does not own packet loop
>> + */
>> +int ulwip_in_loop(void);
>> +
>> +/**
>> + * ulwip_loop_set() - make loop to be used by lwIP
>> + *
>> + * Function is used to make lwIP control network pool.
>> + *
>> + * @loop: 1. Rx packets go to lwIP 2. Rx packets go to the original stack.
>> + */
>> +void ulwip_loop_set(int loop);
>> +
>> +/**
>> + * ulwip_exit() - exit from lwIP with a return code
>> + *
>> + * Exit from lwIP application back to the U-Boot with specific error code.
>> + *
>> + * @err: Error code to return
>> + */
>> +void ulwip_exit(int err);
>> +
>> +/**
>> + * ulwip_poll() - polling function to feed lwIP with ethernet packet
>> + *
>> + * Function takes network packet and passes it to lwIP network stack
>> + */
>> +void ulwip_poll(void);
>> +
>> +/**
>> + * ulwip_app_get_err() - return error code from lwIP application
>> + *
>> + * @return error code
>> + */
>> +int ulwip_app_get_err(void);
>> +
>> +/**
>> + * ulwip_loop() - enter to packet polling loop
>> + *
>> + * When lwIP application did it's initialization stage, then it needs to enter
>> + * to packet polling loop to grab rx packets.
>> + *
>> + * Returns: 0 if success, !0 if error
>> + */
>> +int ulwip_loop(void);
next prev parent reply other threads:[~2023-10-03 23:44 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-26 9:41 [PATCHv10 00/15] net/lwip: add lwip library for the network stack Maxim Uvarov
2023-09-26 9:41 ` [PATCHv10 01/15] submodule: add lwIP as git submodule Maxim Uvarov
2023-09-26 11:37 ` Simon Glass
2023-09-26 13:41 ` Tom Rini
2023-09-26 14:16 ` Simon Glass
2023-09-26 14:19 ` Tom Rini
2023-10-02 6:34 ` Maxim Uvarov
2023-10-02 11:23 ` Maxim Uvarov
2023-10-02 14:46 ` Simon Glass
2023-10-04 7:52 ` Maxim Uvarov
2023-10-04 16:02 ` Tom Rini
2023-10-04 16:06 ` Simon Glass
2023-09-26 9:41 ` [PATCHv10 02/15] Makefile: init submodules Maxim Uvarov
2023-09-26 9:41 ` [PATCHv10 03/15] net/lwip: add doc/develop/net_lwip.rst Maxim Uvarov
2023-09-26 9:41 ` [PATCHv10 04/15] net/lwip: integrate lwIP library Maxim Uvarov
2023-09-26 9:41 ` [PATCHv10 05/15] net/lwip: implement dns cmd Maxim Uvarov
2023-09-26 9:41 ` [PATCHv10 06/15] net/lwip: implement dhcp cmd Maxim Uvarov
2023-10-02 1:17 ` Simon Glass
2023-09-26 9:41 ` [PATCHv10 07/15] net/lwip: implement tftp cmd Maxim Uvarov
2023-09-26 9:41 ` [PATCHv10 08/15] net/lwip: implement wget cmd Maxim Uvarov
2023-10-02 1:17 ` Simon Glass
2023-09-26 9:41 ` [PATCHv10 09/15] net/lwip: implement ping cmd Maxim Uvarov
2023-09-26 9:41 ` [PATCHv10 10/15] net/lwip: add lwIP configuration Maxim Uvarov
2023-10-02 1:17 ` Simon Glass
2023-09-26 9:41 ` [PATCHv10 11/15] net/lwip: implement lwIP port to U-Boot Maxim Uvarov
2023-09-26 9:41 ` [PATCHv10 12/15] net/lwip: update .gitignore with lwIP Maxim Uvarov
2023-10-02 1:17 ` Simon Glass
2023-09-26 9:41 ` [PATCHv10 13/15] net/lwip: connection between cmd and lwip apps Maxim Uvarov
2023-10-02 1:17 ` Simon Glass
2023-09-26 9:41 ` [PATCHv10 14/15] net/lwip: replace original net commands with lwip Maxim Uvarov
2023-10-02 1:17 ` Simon Glass
2023-10-03 17:58 ` Sean Edmond
2023-10-03 21:58 ` Peter Robinson
2023-10-03 23:44 ` Sean Edmond [this message]
2023-10-04 2:11 ` Simon Glass
2023-10-04 8:29 ` Maxim Uvarov
2023-10-04 20:14 ` Simon Goldschmidt
2023-09-26 9:41 ` [PATCHv10 15/15] net/lwip: split net.h to net.h, arp.h and eth.h Maxim Uvarov
2023-10-02 1:17 ` Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6ed884d1-427c-2c1d-275f-25eb817aef7c@linux.microsoft.com \
--to=seanedmond@linux.microsoft.com \
--cc=goldsimon@gmx.de \
--cc=ilias.apalodimas@linaro.org \
--cc=joe.hershberger@ni.com \
--cc=maxim.uvarov@linaro.org \
--cc=pbrobinson@gmail.com \
--cc=rfried.dev@gmail.com \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox