From patchwork Fri Jul 14 14:19:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 1807844 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=dcA7ZDcP; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R2YbM2Y6jz20bh for ; Sat, 15 Jul 2023 00:22:39 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B9C5586D90; Fri, 14 Jul 2023 16:22:19 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="dcA7ZDcP"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5EF8586D2E; Fri, 14 Jul 2023 16:22:16 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 53CFE86D67 for ; Fri, 14 Jul 2023 16:22:13 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=maxim.uvarov@linaro.org Received: by mail-lf1-x12e.google.com with SMTP id 2adb3069b0e04-4fa48b5dc2eso3317843e87.1 for ; Fri, 14 Jul 2023 07:22:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689344532; x=1691936532; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8KSMKzLHFo3bFtjtnVoiAzbvADJWL2Q2ENTIt9VRhwQ=; b=dcA7ZDcPuZeTzpSiVQaxwAcWBqsfYl23OjgvkuqGD5u5G67JxVvLunXhFc1iIfOqKY LFLHaTroxaDygz0KkfNMDANyz29GxqurkweoZtPL9UxH+cVJtSGNbrqRnmvK81CAV92y y2AhdQRIA7DJIwQe/S2ArdGTxnA3A+DLqmZxE15F9ZPKa/yiCQyow6DMvqeWWvbS1DlE wJR9O9B7TsSQYJkILhFn3yZ/cnACMbqIWJHv+8HBZBjBwPoYljkHkbhL+YxPIwadV/1c Eh1cWmjpanlRazjBHFku0hO+c9JEAiJqmWZPhtqOMZEpK7tYQjKIXsrds0AK+3vzYk4L iYqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689344532; x=1691936532; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8KSMKzLHFo3bFtjtnVoiAzbvADJWL2Q2ENTIt9VRhwQ=; b=JraOTc9SVSy9Vzx7VfgTKe7TelMaESZzAy4g1lyrkp2bN3a5vXikEuZE7J9UtPyOfv 9/0XyjvZ2s0lr3wze2BKKTrh0TaC4IE2jav6lBVyxXJrWpBCEFn4Sst8xYHV8VtvRkSN bMNldPVJx004g8kBYCRSpUpoEmmGqIpwUHArNiPGsZnlQkdD+n7A1FIQUHoUcU7wbUdn JLZINCu6iiYx0B12/BdNZ/LXtbjg6cOC9QHP5hKlPOm/zmNg8j2csBFkvm+sz7Alk98w 8QA/+NPqwjNvg2OHUkG2BA6DIDUMTXrFoJeQsglnxmjYxuJjfTLpAuKrzGWasGtohRbK r5hw== X-Gm-Message-State: ABy/qLbDFzQM/nqsPlCOMwlj/FLSvynL75MNpEI/UD4NElQCkqC3Ya4e 6E+VMhmZFIaSi7xjtLLGZtJ4b19wiYR8FbC6cGdfhA== X-Google-Smtp-Source: APBJJlF2D+zBG7G2b2FduhRAvoJg/eTn2mz+whLEEd8ckaVrL5fLwsXCDp5RR9SDYciq0AszQ2a7Lg== X-Received: by 2002:a05:6512:3e16:b0:4f8:5671:ed1 with SMTP id i22-20020a0565123e1600b004f856710ed1mr4612165lfv.29.1689344532445; Fri, 14 Jul 2023 07:22:12 -0700 (PDT) Received: from localhost.localdomain ([45.82.14.220]) by smtp.gmail.com with ESMTPSA id w28-20020ac2599c000000b004fb759964a9sm1504703lfn.168.2023.07.14.07.22.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jul 2023 07:22:12 -0700 (PDT) From: Maxim Uvarov To: u-boot@lists.denx.de Cc: pbrobinson@redhat.com, ilias.apalodimas@linaro.org, joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com, goldsimon@gmx.de, lwip-devel@nongnu.org, Maxim Uvarov Subject: [PATCHv4 1/5] net/lwip: add lwip-external submodule Date: Fri, 14 Jul 2023 20:19:56 +0600 Message-Id: <20230714142000.5534-2-maxim.uvarov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230714142000.5534-1-maxim.uvarov@linaro.org> References: <20230714142000.5534-1-maxim.uvarov@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean This commit adds the lwip library as a git submodule. I think there has to be advantages to compile lwip inside U-boot, i.e. use the same compiler and flags as the main code. One of them is LTO and the other is to enable additional debug options for network protocol during development. Also we can copy lwip library code inside U-boot, but for now I don't want to send all lwip code to the mailing list. So it's git submodule. Signed-off-by: Maxim Uvarov --- .gitmodules | 3 +++ lib/lwip/lwip-external | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 lib/lwip/lwip-external diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..afc709af10 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/lwip/lwip-external"] + path = lib/lwip/lwip-external + url = https://git.savannah.nongnu.org/git/lwip.git diff --git a/lib/lwip/lwip-external b/lib/lwip/lwip-external new file mode 160000 index 0000000000..3fe8d2fc43 --- /dev/null +++ b/lib/lwip/lwip-external @@ -0,0 +1 @@ +Subproject commit 3fe8d2fc43a9b69f7ed28c63d44a7744f9c0def9 From patchwork Fri Jul 14 14:19:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 1807847 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=kI2Pvnxr; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R2Ybl44PSz20bh for ; Sat, 15 Jul 2023 00:22:59 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id ACCC986D9F; Fri, 14 Jul 2023 16:22:28 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="kI2Pvnxr"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C031386CC6; Fri, 14 Jul 2023 16:22:25 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B1DD686CC6 for ; Fri, 14 Jul 2023 16:22:17 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=maxim.uvarov@linaro.org Received: by mail-lf1-x12a.google.com with SMTP id 2adb3069b0e04-4fb7dc16ff0so3315130e87.2 for ; Fri, 14 Jul 2023 07:22:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689344537; x=1691936537; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZgXCuwzjhuRTCwdXv1sIPhPGIm/FokDFwhisnFqbDf0=; b=kI2PvnxreBh51O0wrghZd54/jxuCMHm0yhB1NvPEdb9LMkKkzNOXB/8CZ5/MeMeDwA G9navq8x4AeHLGOE0YaN2P67TAFyZw7xhKvN66TOWocFAanQKbkDjuK2CtZbzQl5oR/Q XVern6043qVY20+ETN4+Q+kT8CD+ZkNOhOT1lMs6G+FccsvFGzymxOb3mdcYqXZ3IF2q jJP+qSapC4McLHiVMhO9M4KdpW60y85UJtF9XvSR9sNRKClWoLhf0zd7lhHwGn9qbwBU yVV+bPjdF5/VPhVehLRJA/8iU1xSIbEhnMT9WZ3wL96s6Wo0edPJxZaqyMS/ROs3vlgp RI6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689344537; x=1691936537; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZgXCuwzjhuRTCwdXv1sIPhPGIm/FokDFwhisnFqbDf0=; b=jI+V4zFzsqETGw8GRKa+Jixgr+soUt+GyuNycgltaCmyZDAq1a0ZespKKFJz9oMbUi WNm6wDunKBnkHF95zWHhPy8MPHdtaLBKuBwGBVqFLl+mgKa9VNqaPchqjnP6VHHn0qEq Oq/lQmymh1veADJDkhlpB14bOLDr5rVTkSLQThaCIk+XfTZGayFm4TiO6W0VDf/7PWac yDuVBDQIYfRwRwLLdR43ck+5LML0IcPfhPAllSiBMwlCX1U+DwAxeFzQdoXct/jQerI8 68IwI/FMMMIOnEFJuui9oltZhzKbAGXnXwb2Xv/a5jTXw2OVunUMWPCnbzlJvCOuJByG 7wLg== X-Gm-Message-State: ABy/qLaGMs6aAp/b6O4yZADKIYNObWY7GOO6ler0vS3vLBIwPlfnYNGH BhvbAvN3KpahawK8spGqAjhrvBtBPW6F73i2C/Q5nQ== X-Google-Smtp-Source: APBJJlFTWWFXizVG4/HlcU1pcwlpD13gcSBwYd3SAH8d+LuqXgMMkBQfIjr5mhdhRZ7i19KZi2fRJw== X-Received: by 2002:a05:6512:33ce:b0:4f7:66bf:b263 with SMTP id d14-20020a05651233ce00b004f766bfb263mr4240335lfg.24.1689344536360; Fri, 14 Jul 2023 07:22:16 -0700 (PDT) Received: from localhost.localdomain ([45.82.14.220]) by smtp.gmail.com with ESMTPSA id w28-20020ac2599c000000b004fb759964a9sm1504703lfn.168.2023.07.14.07.22.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jul 2023 07:22:16 -0700 (PDT) From: Maxim Uvarov To: u-boot@lists.denx.de Cc: pbrobinson@redhat.com, ilias.apalodimas@linaro.org, joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com, goldsimon@gmx.de, lwip-devel@nongnu.org, Maxim Uvarov Subject: [PATCHv4 2/5] net/lwip: add lwip library for the network stack Date: Fri, 14 Jul 2023 20:19:57 +0600 Message-Id: <20230714142000.5534-3-maxim.uvarov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230714142000.5534-1-maxim.uvarov@linaro.org> References: <20230714142000.5534-1-maxim.uvarov@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean This commit adds lwip library for the U-boot network stack. Supported commands: ping, tftp, dhcp and wget. Signed-off-by: Maxim Uvarov --- .gitignore | 9 + boot/bootmeth_pxe.c | 2 +- cmd/net.c | 48 +---- cmd/pxe.c | 2 +- include/net.h | 8 +- lib/Kconfig | 2 + lib/Makefile | 2 + lib/lwip/Kconfig | 63 ++++++ lib/lwip/Makefile | 101 ++++++++++ lib/lwip/apps/dhcp/lwip-dhcp.c | 52 +++++ lib/lwip/apps/http/lwip-wget.c | 74 +++++++ lib/lwip/apps/ping/lwip_ping.c | 37 ++++ lib/lwip/apps/ping/lwip_ping.h | 24 +++ lib/lwip/apps/ping/ping.h | 35 ++++ lib/lwip/apps/tftp/lwip-tftp.c | 124 ++++++++++++ lib/lwip/cmd-lwip.c | 269 ++++++++++++++++++++++++++ lib/lwip/lwipopts.h | 203 +++++++++++++++++++ lib/lwip/port/if.c | 260 +++++++++++++++++++++++++ lib/lwip/port/include/arch/cc.h | 46 +++++ lib/lwip/port/include/arch/sys_arch.h | 59 ++++++ lib/lwip/port/include/limits.h | 0 lib/lwip/port/sys-arch.c | 20 ++ lib/lwip/ulwip.h | 9 + net/Kconfig | 1 + net/net.c | 24 +++ 25 files changed, 1430 insertions(+), 44 deletions(-) create mode 100644 lib/lwip/Kconfig create mode 100644 lib/lwip/Makefile create mode 100644 lib/lwip/apps/dhcp/lwip-dhcp.c create mode 100644 lib/lwip/apps/http/lwip-wget.c create mode 100644 lib/lwip/apps/ping/lwip_ping.c create mode 100644 lib/lwip/apps/ping/lwip_ping.h create mode 100644 lib/lwip/apps/ping/ping.h create mode 100644 lib/lwip/apps/tftp/lwip-tftp.c create mode 100644 lib/lwip/cmd-lwip.c create mode 100644 lib/lwip/lwipopts.h create mode 100644 lib/lwip/port/if.c create mode 100644 lib/lwip/port/include/arch/cc.h create mode 100644 lib/lwip/port/include/arch/sys_arch.h create mode 100644 lib/lwip/port/include/limits.h create mode 100644 lib/lwip/port/sys-arch.c create mode 100644 lib/lwip/ulwip.h diff --git a/.gitignore b/.gitignore index eb769f144c..be3676c59e 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,12 @@ __pycache__ # pylint files /pylint.cur /pylint.out/ + +lib/lwip/lwip-external +lib/lwip/apps/ping/ping.c +lib/lwip/apps/http/http_client.c +lib/lwip/apps/http/http_client.h +lib/lwip/apps/tftp/tftp.c +lib/lwip/apps/tftp/tftp_client.h +lib/lwip/apps/tftp/tftp_common.h +lib/lwip/apps/tftp/tftp_example.h diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c index e6992168c0..30331a9806 100644 --- a/boot/bootmeth_pxe.c +++ b/boot/bootmeth_pxe.c @@ -118,7 +118,7 @@ static int distro_pxe_read_file(struct udevice *dev, struct bootflow *bflow, tftp_argv[1] = file_addr; tftp_argv[2] = (void *)file_path; - if (do_tftpb(ctx->cmdtp, 0, 3, tftp_argv)) + if (do_lwip_tftp(ctx->cmdtp, 0, 3, tftp_argv)) return -ENOENT; ret = pxe_get_file_size(&size); if (ret) diff --git a/cmd/net.c b/cmd/net.c index 0e9f200ca9..6d704fba86 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -36,19 +36,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, "boot image via network using TFTP protocol\n" "To use IPv6 add -ipv6 parameter or use IPv6 hostIPaddr framed " "with [] brackets", @@ -56,7 +46,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]" ); @@ -112,7 +102,7 @@ U_BOOT_CMD( 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( @@ -137,13 +127,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]" ); @@ -376,28 +364,10 @@ 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; -} - +extern int do_lwip_ping(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]); U_BOOT_CMD( - ping, 2, 1, do_ping, + ping, 2, 1, do_lwip_ping, "send ICMP ECHO_REQUEST to network host", "pingAddress" ); diff --git a/cmd/pxe.c b/cmd/pxe.c index db8e4697f2..bd4d6f5f2b 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -33,7 +33,7 @@ static int do_get_tftp(struct pxe_context *ctx, const char *file_path, tftp_argv[1] = file_addr; tftp_argv[2] = (void *)file_path; - if (do_tftpb(ctx->cmdtp, 0, 3, tftp_argv)) + if (do_lwip_tftp(ctx->cmdtp, 0, 3, tftp_argv)) return -ENOENT; ret = pxe_get_file_size(sizep); if (ret) diff --git a/include/net.h b/include/net.h index 1a99009959..6b573f3319 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[]); /** * An incoming packet handler. @@ -561,7 +563,7 @@ extern int net_restart_wrap; /* Tried all network devices */ enum proto_t { BOOTP, RARP, ARP, TFTPGET, DHCP, PING, PING6, DNS, NFS, CDP, NETCONS, - SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI, WGET + SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI, WGET, LWIP }; extern char net_boot_file_name[1024];/* Boot File name */ diff --git a/lib/Kconfig b/lib/Kconfig index 3c5a4ab386..7485a1f3bf 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -1031,3 +1031,5 @@ menu "FWU Multi Bank Updates" source lib/fwu_updates/Kconfig endmenu + +source lib/lwip/Kconfig diff --git a/lib/Makefile b/lib/Makefile index d77b33e7f4..3b80a41187 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -91,6 +91,8 @@ obj-$(CONFIG_LIBAVB) += libavb/ obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += libfdt/ obj-$(CONFIG_$(SPL_TPL_)OF_REAL) += fdtdec_common.o fdtdec.o +obj-y += lwip/ + ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16-ccitt.o obj-$(CONFIG_$(SPL_TPL_)HASH) += crc16-ccitt.o diff --git a/lib/lwip/Kconfig b/lib/lwip/Kconfig new file mode 100644 index 0000000000..3688ac3305 --- /dev/null +++ b/lib/lwip/Kconfig @@ -0,0 +1,63 @@ +menu "LWIP" +config LWIP_LIB + bool "Support LWIP library" + help + Selecting this option will enable the LWIP library code. + +menu "LWIP options" + +config LWIP_LIB_DEBUG + bool "enable debug" + default n + +config LWIP_LIB_NOASSERT + bool "disable asserts" + default y + help + Disabling asserts reduces binary size on 16k. + +config LWIP_LIB_TCP + bool "tcp" + default y + +config LWIP_LIB_UDP + bool "udp" + default y + +config LWIP_LIB_DNS + bool "dns" + default n + +config LWIP_LIB_DHCP + bool "dhcp" + default y + +config LWIP_LIB_LOOPBACK + bool "loopback" + help + Increases size on 1k. + +config LWIP_LIB_SOCKET + bool "socket API" + +config LWIP_LIB_NETCONN + bool "netconn API" + +config LWIP_LIB_MEM_SIZE + int "mem size" + default 1600 + range 1 4096 + help + MEM_SIZE: the size of the heap memory. If the application will send + a lot of data that needs to be copied, this should be set high. + +config LWIP_LIB_PBUF_LINK_HLEN + int "pbuf link hlen" + default 14 + range 4 1024 + help + PBUF_LINK_HLEN: the number of bytes that should be allocated for a + link level header. The default is 14, the standard value for Ethernet. +endmenu + +endmenu diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile new file mode 100644 index 0000000000..e1a8a2a7b7 --- /dev/null +++ b/lib/lwip/Makefile @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2023 Linaro Ltd. + +LWIPDIR=lwip-external/src + +ccflags-y += -I$(srctree)/lib/lwip/port/include +ccflags-y += -I$(srctree)/lib/lwip/lwip-external/src/include -I$(srctree)/lib/lwip + +obj-$(CONFIG_NET) += $(LWIPDIR)/core/init.o \ + $(LWIPDIR)/core/def.o \ + $(LWIPDIR)/core/dns.o \ + $(LWIPDIR)/core/inet_chksum.o \ + $(LWIPDIR)/core/ip.o \ + $(LWIPDIR)/core/mem.o \ + $(LWIPDIR)/core/memp.o \ + $(LWIPDIR)/core/netif.o \ + $(LWIPDIR)/core/pbuf.o \ + $(LWIPDIR)/core/raw.o \ + $(LWIPDIR)/core/stats.o \ + $(LWIPDIR)/core/sys.o \ + $(LWIPDIR)/core/altcp.o \ + $(LWIPDIR)/core/altcp_alloc.o \ + $(LWIPDIR)/core/altcp_tcp.o \ + $(LWIPDIR)/core/tcp.o \ + $(LWIPDIR)/core/tcp_in.o \ + $(LWIPDIR)/core/tcp_out.o \ + $(LWIPDIR)/core/timeouts.o \ + $(LWIPDIR)/core/udp.o + +# IPv4 +obj-$(CONFIG_NET) += $(LWIPDIR)/core/ipv4/acd.o \ + $(LWIPDIR)/core/ipv4/autoip.o \ + $(LWIPDIR)/core/ipv4/dhcp.o \ + $(LWIPDIR)/core/ipv4/etharp.o \ + $(LWIPDIR)/core/ipv4/icmp.o \ + $(LWIPDIR)/core/ipv4/igmp.o \ + $(LWIPDIR)/core/ipv4/ip4_frag.o \ + $(LWIPDIR)/core/ipv4/ip4.o \ + $(LWIPDIR)/core/ipv4/ip4_addr.o +# IPv6 +obj-$(CONFIG_NET) += $(LWIPDIR)/core/ipv6/dhcp6.o \ + $(LWIPDIR)/core/ipv6/ethip6.o \ + $(LWIPDIR)/core/ipv6/icmp6.o \ + $(LWIPDIR)/core/ipv6/inet6.o \ + $(LWIPDIR)/core/ipv6/ip6.o \ + $(LWIPDIR)/core/ipv6/ip6_addr.o \ + $(LWIPDIR)/core/ipv6/ip6_frag.o \ + $(LWIPDIR)/core/ipv6/mld6.o \ + $(LWIPDIR)/core/ipv6/nd6.o +# API +obj-$(CONFIG_NET) += $(LWIPDIR)/api/api_lib.o \ + $(LWIPDIR)/api/api_msg.o \ + $(LWIPDIR)/api/err.o \ + $(LWIPDIR)/api/if_api.o \ + $(LWIPDIR)/api/netbuf.o \ + $(LWIPDIR)/api/netdb.o \ + $(LWIPDIR)/api/netifapi.o \ + $(LWIPDIR)/api/sockets.o \ + $(LWIPDIR)/api/tcpip.o + +# Netdevs +obj-$(CONFIG_NET) += $(LWIPDIR)/netif/ethernet.o + +obj-$(CONFIG_NET) += port/if.o +obj-$(CONFIG_NET) += port/sys-arch.o + +obj-$(CONFIG_NET) += cmd-lwip.o + + +ccflags-y += -I$(srctree)/lib/lwip/apps/ping +.PHONY: $(obj)/apps/ping/ping.c +$(obj)/apps/ping/ping.o: $(obj)/apps/ping/ping.c +$(obj)/apps/ping/ping.c: + cp $(srctree)/lib/lwip/lwip-external/contrib/apps/ping/ping.c $(obj)/apps/ping/ping.c + +obj-$(CONFIG_CMD_PING) += apps/ping/ping.o +obj-$(CONFIG_CMD_PING) += apps/ping/lwip_ping.o + +$(obj)/apps/http/http_clinet.o: $(obj)/apps/http/http_client.c +.PHONY: $(obj)/apps/http/http_client.c +$(obj)/apps/http/http_client.c: + cp $(srctree)/lib/lwip/lwip-external/src/apps/http/http_client.c $(obj)/apps/http/http_client.c + cp $(srctree)/lib/lwip/lwip-external/src/include/lwip/apps/http_client.h $(obj)/apps/http/http_client.h + +obj-$(CONFIG_CMD_WGET) += apps/http/http_client.o +obj-$(CONFIG_CMD_WGET) += apps/http/lwip-wget.o + +ccflags-y += -I$(CURDIR)/lib/lwip/apps/tftp +$(obj)/apps/tftp/tftp.o: $(obj)/apps/tftp/tftp.c +.PHONY: $(obj)/apps/tftp/tftp.c +$(obj)/apps/tftp/tftp.c: + cp $(srctree)/lib/lwip/lwip-external/src/apps/tftp/tftp.c $(obj)/apps/tftp/tftp.c + cp $(srctree)/lib/lwip/lwip-external/src/include/lwip/apps/tftp_client.h $(obj)/apps/tftp/tftp_client.h + cp $(srctree)/lib/lwip/lwip-external/src/include/lwip/apps/tftp_common.h $(obj)/apps/tftp/tftp_common.h + cp $(srctree)/lib/lwip/lwip-external/contrib/examples/tftp/tftp_example.h $(obj)/apps/tftp/tftp_example.h + +obj-$(CONFIG_CMD_TFTPBOOT) += apps/tftp/tftp.o +obj-$(CONFIG_CMD_TFTPBOOT) += apps/tftp/lwip-tftp.o + +obj-$(CONFIG_CMD_DHCP) += apps/dhcp/lwip-dhcp.o diff --git a/lib/lwip/apps/dhcp/lwip-dhcp.c b/lib/lwip/apps/dhcp/lwip-dhcp.c new file mode 100644 index 0000000000..2e4812c7dd --- /dev/null +++ b/lib/lwip/apps/dhcp/lwip-dhcp.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +#include + +#include +#include + +#include "../../../lwip/ulwip.h" + +static struct dhcp dhcp; +static bool dhcp_is_set; +extern struct netif uboot_netif; + +static int ulwip_dhcp_tmo(void) +{ + switch (dhcp.state) { + case DHCP_STATE_BOUND: + env_set("bootfile", dhcp.boot_file_name); + env_set("ipaddr", ip4addr_ntoa(&dhcp.offered_ip_addr)); + env_set("netmask", ip4addr_ntoa(&dhcp.offered_sn_mask)); + env_set("serverip", ip4addr_ntoa(&dhcp.server_ip_addr)); + printf("DHCP client bound to address %s\n", ip4addr_ntoa(&dhcp.offered_ip_addr)); + break; + default: + return 0; + } + + return 0; +} + +int ulwip_dhcp(void) +{ + int err; + + ulwip_set_tmo(ulwip_dhcp_tmo); + + if (!dhcp_is_set) { + dhcp_set_struct(&uboot_netif, &dhcp); + dhcp_is_set = true; + } + err = dhcp_start(&uboot_netif); + if (err) + printf("dhcp_start error %d\n", err); + + return err; +} diff --git a/lib/lwip/apps/http/lwip-wget.c b/lib/lwip/apps/http/lwip-wget.c new file mode 100644 index 0000000000..0308b0b04a --- /dev/null +++ b/lib/lwip/apps/http/lwip-wget.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +#include + +#include "http_client.h" +#include "../../../lwip/ulwip.h" + +static ulong daddr; +static httpc_connection_t settings; + +static err_t httpc_recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct pbuf *q; + LWIP_UNUSED_ARG(err); + + if (!p) + return ERR_BUF; + + for (q = p; q != NULL; q = q->next) { + memcpy((void *)daddr, q->payload, q->len); + printf("downloaded chunk size %d, to addr 0x%lx\n", q->len, daddr); + daddr += q->len; + } + altcp_recved(pcb, p->tot_len); + pbuf_free(p); + return ERR_OK; +} + +static void httpc_result(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, + u32_t srv_res, err_t err) +{ + if (httpc_result == HTTPC_RESULT_OK) { + printf("\n%d bytes successfully downloaded.\n", rx_content_len); + env_set_ulong("filesize", rx_content_len); + ulwip_exit(0); + } else { + printf("\nhttp eroror: %d\n", httpc_result); + ulwip_exit(-1); + } +} + +int lwip_wget(ulong addr, char *url) +{ + err_t err; + int port = 80; + char *server_name; + httpc_state_t *connection; + + daddr = addr; + server_name = env_get("serverip"); + if (!server_name) { + printf("error: serverip variable has to be set\n"); + return CMD_RET_FAILURE; + } + + printf("downloading %s to addr 0x%lx\n", url, addr); + memset(&settings, 0, sizeof(httpc_connection_t)); + settings.result_fn = httpc_result; + err = httpc_get_file_dns(server_name, port, url, &settings, + httpc_recv, NULL, &connection); + if (err != ERR_OK) { + printf("httpc_init_connection failed\n"); + return err; + } + + env_set_hex("fileaddr", addr); + return 0; +} diff --git a/lib/lwip/apps/ping/lwip_ping.c b/lib/lwip/apps/ping/lwip_ping.c new file mode 100644 index 0000000000..a05dc76326 --- /dev/null +++ b/lib/lwip/apps/ping/lwip_ping.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "ping.h" + +#include "../../../lwip/ulwip.h" + +static ip_addr_t ip_target; + +static int ulwip_ping_tmo(void) +{ + + printf("ping failed; host %s is not alive\n", ipaddr_ntoa(&ip_target)); + return 0; +} + +int lwip_ping_init(char *ping_addr) +{ + int err; + + err = ipaddr_aton(ping_addr, &ip_target); + if (err == 0) { + printf("wrong ping addr string \"%s\" \n", ping_addr); + return -1; + } + + ulwip_set_tmo(ulwip_ping_tmo); + + ping_init(&ip_target); + + return 0; +} diff --git a/lib/lwip/apps/ping/lwip_ping.h b/lib/lwip/apps/ping/lwip_ping.h new file mode 100644 index 0000000000..7f08095427 --- /dev/null +++ b/lib/lwip/apps/ping/lwip_ping.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#ifndef LWIP_PING_H +#define LWIP_PING_H + +#include + +/** + * PING_USE_SOCKETS: Set to 1 to use sockets, otherwise the raw api is used + */ +#ifndef PING_USE_SOCKETS +#define PING_USE_SOCKETS 0 +#endif + +int lwip_ping_init(char *ping_addr); + +void ping_raw_init(void); +void ping_send_now(void); + +#endif /* LWIP_PING_H */ diff --git a/lib/lwip/apps/ping/ping.h b/lib/lwip/apps/ping/ping.h new file mode 100644 index 0000000000..0dd4bd78c7 --- /dev/null +++ b/lib/lwip/apps/ping/ping.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include "../../../lwip/ulwip.h" + +#include "lwip/prot/ip4.h" + +#define ip4_print_parts(a, b, c, d) \ + printf("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, a, b, c, d); + +#define ip4_print(ipaddr) \ + ip4_print_parts(\ + (u16_t)((ipaddr) != NULL ? ip4_addr1_16(ipaddr) : 0), \ + (u16_t)((ipaddr) != NULL ? ip4_addr2_16(ipaddr) : 0), \ + (u16_t)((ipaddr) != NULL ? ip4_addr3_16(ipaddr) : 0), \ + (u16_t)((ipaddr) != NULL ? ip4_addr4_16(ipaddr) : 0)) + + +#define LWIP_DEBUG 1 /* ping_time is under ifdef*/ +#define PING_RESULT(cond) { \ + if (cond == 1) { \ + printf("host "); \ + ip4_print(addr); \ + printf(" is alive\n"); \ + printf(" %"U32_F" ms\n", (sys_now() - ping_time)); \ + ulwip_exit(0); \ + } else { \ + printf("ping failed; host "); \ + ip4_print(addr); \ + printf(" is not alive\n"); \ + ulwip_exit(-1); \ + } \ + } while (0); + +#include "lwip/ip_addr.h" +void ping_init(const ip_addr_t *ping_addr); diff --git a/lib/lwip/apps/tftp/lwip-tftp.c b/lib/lwip/apps/tftp/lwip-tftp.c new file mode 100644 index 0000000000..511d82e600 --- /dev/null +++ b/lib/lwip/apps/tftp/lwip-tftp.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +#include + +#include "lwip/apps/tftp_client.h" +#include "lwip/apps/tftp_server.h" +#include + +#include + +#include "../../../lwip/ulwip.h" + +#if LWIP_UDP + +static ulong daddr; +static ulong size; + +static void *tftp_open(const char *fname, const char *mode, u8_t is_write) +{ + LWIP_UNUSED_ARG(mode); + return NULL; +} + +static void tftp_close(void *handle) +{ + printf("\ndone\n"); + printf("Bytes transferred = %ld (0x%lx hex)\n", size, size); + + env_set_ulong("filesize", size); + ulwip_exit(0); +} + +static int tftp_read(void *handle, void *buf, int bytes) +{ + return 0; +} + +static int tftp_write(void *handle, struct pbuf *p) +{ + struct pbuf *q; + + for (q = p; q != NULL; q = q->next) { + memcpy((void *)daddr, q->payload, q->len); + /* printf("downloaded chunk size %d, to addr 0x%lx\n", q->len, daddr); */ + daddr += q->len; + size += q->len; + printf("#"); + } + + return 0; +} + +/* For TFTP client only */ +static void tftp_error(void *handle, int err, const char *msg, int size) +{ + char message[100]; + + LWIP_UNUSED_ARG(handle); + + memset(message, 0, sizeof(message)); + MEMCPY(message, msg, LWIP_MIN(sizeof(message)-1, (size_t)size)); + + printf("TFTP error: %d (%s)", err, message); +} + +static const struct tftp_context tftp = { + tftp_open, + tftp_close, + tftp_read, + tftp_write, + tftp_error +}; + +int lwip_tftp(ulong addr, char *fname) +{ + void *f = (void *)0x1; /*fake handle*/ + err_t err; + ip_addr_t srv; + int ret; + char *server_ip; + + if (!fname || addr == 0) + return CMD_RET_FAILURE; + + size = 0; + daddr = addr; + server_ip = env_get("serverip"); + if (!server_ip) { + printf("error: serverip variable has to be set\n"); + return CMD_RET_FAILURE; + } + + ret = ipaddr_aton(server_ip, &srv); + LWIP_ASSERT("ipaddr_aton failed", ret == 1); + + printf("TFTP from server %s; our IP address is %s\n", + server_ip, env_get("ipaddr")); + printf("Filename '%s'.\n", fname); + printf("Load address: 0x%lx\n", daddr); + printf("Loading:"); + + err = tftp_init_client(&tftp); + if (!(err == ERR_OK || err == ERR_USE)) + printf("tftp_init_client err: %d\n", err); + + err = tftp_get(f, &srv, TFTP_PORT, fname, TFTP_MODE_OCTET); + /* might return different errors, like routing problems */ + if (err != ERR_OK) { + printf("tftp_get err=%d\n", err); + } + LWIP_ASSERT("tftp_get failed", err == ERR_OK); + + env_set_hex("fileaddr", addr); + return err; +} +#else +#error "UDP has to be supported" +#endif /* LWIP_UDP */ diff --git a/lib/lwip/cmd-lwip.c b/lib/lwip/cmd-lwip.c new file mode 100644 index 0000000000..625c8c53b8 --- /dev/null +++ b/lib/lwip/cmd-lwip.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Maxim Uvarov, maxim.uvarov@linaro.org + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "apps/ping/lwip_ping.h" +#include "ulwip.h" + +extern int uboot_lwip_init(void); +extern int uboot_lwip_loop_is_done(void); + +static int do_lwip_info(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + printf("TBD: %s\n", __func__); + return CMD_RET_SUCCESS; +} + +static int do_lwip_init(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (!uboot_lwip_init()) + return CMD_RET_SUCCESS; + return CMD_RET_FAILURE; +} + +static int lwip_empty_tmo(void) { return 0; }; +int (*ulwip_tmo)(void) = lwip_empty_tmo; +void ulwip_set_tmo(int (*tmo)(void)) +{ + ulwip_tmo = tmo; +} + +static void ulwip_clear_tmo(void) +{ + ulwip_tmo = lwip_empty_tmo; +} + +static void ulwip_timeout_handler(void) +{ + eth_halt(); + ulwip_tmo(); + net_set_state(NETLOOP_FAIL); /* we did not get the reply */ + ulwip_loop_set(0); +} + +static int ulwip_loop(void) +{ + ulwip_loop_set(1); + if (net_loop(LWIP) < 0) { + ulwip_loop_set(0); + return CMD_RET_FAILURE; + } + ulwip_loop_set(0); + return CMD_RET_SUCCESS; +} + +#if defined(CONFIG_CMD_PING) +int do_lwip_ping(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (argc < 2) { + printf("argc = %d, error\n", argc); + return CMD_RET_USAGE; + } + + uboot_lwip_init(); + + eth_init(); /* activate u-boot eth dev */ + + printf("Using %s device\n", eth_get_name()); + printf("pinging addr: %s\n", argv[1]); + + net_set_timeout_handler(1000UL, ulwip_timeout_handler); + + if (lwip_ping_init(argv[1])) { + printf("ping init fail\n"); + return CMD_RET_FAILURE; + } + + ping_send_now(); + + return ulwip_loop(); +} +#endif /* CONFIG_CMD_PING */ + +#if defined(CONFIG_CMD_WGET) +extern int lwip_wget(ulong addr, char *url); + +int do_lwip_wget(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + char *url; + + if (argc < 2) { + printf("argc = %d, error\n", argc); + return CMD_RET_USAGE; + } + url = argv[1]; + + uboot_lwip_init(); + + eth_init(); /* activate u-boot eth dev */ + + lwip_wget(image_load_addr, url); + + return ulwip_loop(); +} +#endif + +#if defined(CONFIG_CMD_TFTPBOOT) +extern int lwip_tftp(ulong addr, char *filename); + +int do_lwip_tftp(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + char *filename; + ulong addr; + char *end; + int ret; + + switch (argc) { + case 1: + filename = env_get("bootfile"); + break; + case 2: + /* + * Only one arg - accept two forms: + * Just load address, or just boot file name. The latter + * form must be written in a format which can not be + * mis-interpreted as a valid number. + */ + addr = hextoul(argv[1], &end); + if (end == (argv[1] + strlen(argv[1]))) { + image_load_addr = addr; + filename = env_get("bootfile"); + } else { + filename = argv[1]; + } + break; + case 3: + image_load_addr = hextoul(argv[1], NULL); + filename = argv[2]; + break; + default: + return CMD_RET_USAGE; + } + + uboot_lwip_init(); + + eth_init(); /* activate u-boot eth dev */ + + ret = lwip_tftp(image_load_addr, filename); + if (ret) + return ret; + + return ulwip_loop(); +} +#endif /* CONFIG_CMD_TFTPBOOT */ + +#if defined(CONFIG_CMD_DHCP) +extern int ulwip_dhcp(void); + +int do_lwip_dhcp(void) +{ + int ret; + char *filename; + + uboot_lwip_init(); + + ret = ulwip_dhcp(); + + net_set_timeout_handler(2000UL, ulwip_timeout_handler); + + ulwip_loop(); + if (IS_ENABLED(CONFIG_CMD_TFTPBOOT)) { + ulwip_clear_tmo(); + + filename = env_get("bootfile"); + if (!filename) { + printf("no bootfile\n"); + return CMD_RET_FAILURE; + } + + eth_init(); /* activate u-boot eth dev */ + net_set_timeout_handler(20000UL, ulwip_timeout_handler); + lwip_tftp(image_load_addr, filename); + + ret = ulwip_loop(); + } + + return ret; +} + +static int _do_lwip_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + return do_lwip_dhcp(); +} +#endif /* CONFIG_CMD_DHCP */ + +static struct cmd_tbl cmds[] = { + U_BOOT_CMD_MKENT(info, 1, 0, do_lwip_info, "Info and stats", ""), + U_BOOT_CMD_MKENT(init, 1, 0, do_lwip_init, + "initialize lwip stack", ""), +#if defined(CONFIG_CMD_LWIP_PING) + U_BOOT_CMD_MKENT(ping, 2, 0, do_lwip_ping, + "send ICMP ECHO_REQUEST to network host", + "pingAddress"), +#endif +#if defined(CONFIG_CMD_WGET) + U_BOOT_CMD_MKENT(wget, 2, 0, do_lwip_wget, "", ""), +#endif +#if defined(CONFIG_CMD_TFTPBOOT) + U_BOOT_CMD_MKENT(tftp, 3, 0, do_lwip_tftp, + "boot image via network using TFTP protocol\n", + "[loadAddress] [[hostIPaddr:]bootfilename]"), +#endif +#if defined(CONFIG_CMD_DHCP) + U_BOOT_CMD_MKENT(dhcp, 1, 0, _do_lwip_dhcp, + "boot image via network using DHCP/TFTP protocol", + ""), +#endif +}; + +static int do_ops(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct cmd_tbl *cp; + + cp = find_cmd_tbl(argv[1], cmds, ARRAY_SIZE(cmds)); + + argc--; + argv++; + + if (cp == NULL || argc > cp->maxargs) + return CMD_RET_USAGE; + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) + return CMD_RET_SUCCESS; + + return cp->cmd(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD( + lwip, 4, 1, do_ops, + "LWIP sub system", + "info - display info\n" + "init - init LWIP\n" + "ping addr - pingAddress\n" + "wget http://IPadress/url/\n" + "tftp [loadAddress] [[hostIPaddr:]bootfilename]\n" + "dhcp - boot image via network using DHCP/TFTP protocol\n" + ); + +/* Old command kept for compatibility. Same as 'mmc info' */ +U_BOOT_CMD( + lwipinfo, 1, 0, do_lwip_info, + "display LWIP info", + "- display LWIP stack info" +); diff --git a/lib/lwip/lwipopts.h b/lib/lwip/lwipopts.h new file mode 100644 index 0000000000..b943d7b9be --- /dev/null +++ b/lib/lwip/lwipopts.h @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#ifndef LWIP_LWIPOPTS_H +#define LWIP_LWIPOPTS_H + +#include "lwipopts.h" + +#if defined(CONFIG_LWIP_LIB_DEBUG) +#define LWIP_DEBUG 1 +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#define ETHARP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define IGMP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define TIMERS_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define SLIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_ON +#define AUTOIP_DEBUG LWIP_DBG_ON +#define DNS_DEBUG LWIP_DBG_OFF +#define IP6_DEBUG LWIP_DBG_OFF +#define DHCP6_DEBUG LWIP_DBG_OFF +#else +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#define LWIP_DBG_TYPES_ON LWIP_DBG_OFF +#define ETHARP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define IGMP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define TIMERS_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define SLIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_OFF +#define AUTOIP_DEBUG LWIP_DBG_OFF +#define DNS_DEBUG LWIP_DBG_OFF +#define IP6_DEBUG LWIP_DBG_OFF +#define DHCP6_DEBUG LWIP_DBG_OFF +#endif +#define LWIP_TESTMODE 0 + +#if defined(CONFIG_LWIP_LIB_NOASSERT) +#define LWIP_NOASSERT 1 +#define LWIP_ASSERT(message, assertion) +#endif + +#include "lwip/debug.h" + +#define SYS_LIGHTWEIGHT_PROT 0 +#define NO_SYS 0 + +#define MEM_ALIGNMENT 1 +#define MEM_SIZE CONFIG_LWIP_LIB_MEM_SIZE + +#define MEMP_NUM_PBUF 4 +#define MEMP_NUM_RAW_PCB 2 +#define MEMP_NUM_UDP_PCB 4 +#define MEMP_NUM_TCP_PCB 2 +#define MEMP_NUM_TCP_PCB_LISTEN 2 +#define MEMP_NUM_TCP_SEG 16 +#define MEMP_NUM_REASSDATA 1 +#define MEMP_NUM_ARP_QUEUE 2 +#define MEMP_NUM_SYS_TIMEOUT 4 +#define MEMP_NUM_NETBUF 2 +#define MEMP_NUM_NETCONN 32 +#define MEMP_NUM_TCPIP_MSG_API 8 +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#define PBUF_POOL_SIZE 8 + +#define LWIP_ARP 1 + +#define IP_FORWARD 0 +#define IP_OPTIONS_ALLOWED 1 +#define IP_REASSEMBLY 1 +#define IP_FRAG 1 +#define IP_REASS_MAXAGE 3 +#define IP_REASS_MAX_PBUFS 4 +#define IP_FRAG_USES_STATIC_BUF 0 + +#define IP_DEFAULT_TTL 255 + +#define LWIP_ICMP 1 + +#define LWIP_RAW 1 + +#if defined(CONFIG_LWIP_LIB_DHCP) +#define LWIP_DHCP 1 +#define LWIP_DHCP_BOOTP_FILE 1 +#else +#define LWIP_DHCP 0 +#endif +#define LWIP_DHCP_DOES_ACD_CHECK 0 + +#define LWIP_AUTOIP 0 + +#define LWIP_SNMP 0 + +#define LWIP_IGMP 0 + +#if defined(CONFIG_LWIP_LIB_DNS) +#define LWIP_DNS 1 +#else +#define LWIP_DNS 0 +#endif + +#if defined(CONFIG_LWIP_LIB_TCP) +#define LWIP_UDP 1 +#else +#define LWIP_UDP 0 +#endif + +#if defined(CONFIG_LWIP_LIB_TCP) +#define LWIP_TCP 1 +#else +#define LWIP_TCP 0 +#endif + +#define LWIP_LISTEN_BACKLOG 0 + +#define PBUF_LINK_HLEN CONFIG_LWIP_LIB_PBUF_LINK_HLEN +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS + 40 + PBUF_LINK_HLEN) + +#define LWIP_HAVE_LOOPIF 0 + +#if defined(CONFIG_LWIP_LIB_NETCONN) +#define LWIP_NETCONN 1 +#else +#define LWIP_NETCONN 0 +#define LWIP_DISABLE_MEMP_SANITY_CHECKS 1 +#endif + +#if defined(CONFIG_LWIP_LIB_SOCKET) +#define LWIP_SOCKET 1 + +#define SO_REUSE 1 +#else +#define LWIP_SOCKET 0 +#define SO_REUSE 0 +#endif + +#define LWIP_STATS 0 + +#define PPP_SUPPORT 0 + +#define LWIP_TCPIP_CORE_LOCKING 0 + +#if defined(CONFIG_LWIP_LIB_LOOPBACK) +#define LWIP_NETIF_LOOPBACK 1 +#else +#define LWIP_NETIF_LOOPBACK 0 +#endif +/* use malloc instead of pool */ +#define MEMP_MEM_MALLOC 1 +#define MEMP_MEM_INIT 1 +#define MEM_LIBC_MALLOC 1 + +#endif /* LWIP_LWIPOPTS_H */ diff --git a/lib/lwip/port/if.c b/lib/lwip/port/if.c new file mode 100644 index 0000000000..37c02a451f --- /dev/null +++ b/lib/lwip/port/if.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +extern int eth_init(void); /* net.h */ +extern void string_to_enetaddr(const char *addr, uint8_t *enetaddr); /* net.h */ +extern struct in_addr net_ip; +extern u8 net_ethaddr[6]; + +#include "lwip/debug.h" +#include "lwip/arch.h" +#include "netif/etharp.h" +#include "lwip/stats.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/netif.h" + +#include "lwip/ip.h" + +#define IFNAME0 'e' +#define IFNAME1 '0' + +static struct pbuf *low_level_input(struct netif *netif); +static int uboot_net_use_lwip; + +int ulwip_enabled(void) +{ + return uboot_net_use_lwip; +} + +/* 1 - in loop + * 0 - no loop + */ +static int loop_lwip; + +/* ret 1 - in loop + * 0 - no loop + */ +int ulwip_in_loop(void) +{ + return loop_lwip; +} + +void ulwip_loop_set(int loop) +{ + loop_lwip = loop; +} + +static int ulwip_app_err; + +void ulwip_exit(int err) +{ + ulwip_app_err = err; + ulwip_loop_set(0); +} + +int ulwip_app_get_err(void) +{ + return ulwip_app_err; +} + +struct uboot_lwip_if { +}; + +#if defined(CONFIG_CMD_DHCP) +struct netif uboot_netif; +#else +static struct netif uboot_netif; +#endif + +#define LWIP_PORT_INIT_NETMASK(addr) IP4_ADDR((addr), 255, 255, 255, 0) + +extern uchar *net_rx_packet; +extern int net_rx_packet_len; + +int uboot_lwip_poll(void) +{ + struct pbuf *p; + int err; + + p = low_level_input(&uboot_netif); + if (!p) { + printf("error p = low_level_input = NULL\n"); + return 0; + } + + err = ethernet_input(p, &uboot_netif); + if (err) + printf("ip4_input err %d\n", err); + + return 0; +} + +static struct pbuf *low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + u16_t len = net_rx_packet_len; + uchar *data = net_rx_packet; + +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + if (p) { +#if ETH_PAD_SIZE + pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */ +#endif + /* We iterate over the pbuf chain until we have read the entire + * packet into the pbuf. + */ + for (q = p; q != NULL; q = q->next) { + /* Read enough bytes to fill this pbuf in the chain. The + * available data in the pbuf is given by the q->len + * variable. + * This does not necessarily have to be a memcpy, you can also preallocate + * pbufs for a DMA-enabled MAC and after receiving truncate it to the + * actually received size. In this case, ensure the tot_len member of the + * pbuf is the sum of the chained pbuf len members. + */ + MEMCPY(q->payload, data, q->len); + data += q->len; + } + //acknowledge that packet has been read(); + +#if ETH_PAD_SIZE + pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + LINK_STATS_INC(link.recv); + } else { + //drop packet(); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + } + + return p; +} + +static int ethernetif_input(struct pbuf *p, struct netif *netif) +{ + struct ethernetif *ethernetif; + + ethernetif = netif->state; + + /* move received packet into a new pbuf */ + p = low_level_input(netif); + + /* if no packet could be read, silently ignore this */ + if (p) { + /* pass all packets to ethernet_input, which decides what packets it supports */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("%s: IP input error\n", __func__)); + pbuf_free(p); + p = NULL; + } + } + return 0; +} + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + int err; + + err = eth_send(p->payload, p->len); + if (err != 0) { + printf("eth_send error %d\n", err); + return ERR_ABRT; + } + return ERR_OK; +} + +err_t uboot_lwip_if_init(struct netif *netif) +{ + struct uboot_lwip_if *uif = (struct uboot_lwip_if *)malloc(sizeof(struct uboot_lwip_if)); + + if (!uif) { + printf("uboot_lwip_if: out of memory\n"); + return ERR_MEM; + } + netif->state = uif; + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + + netif->hwaddr_len = ETHARP_HWADDR_LEN; + string_to_enetaddr(env_get("ethaddr"), netif->hwaddr); +#if defined(CONFIG_LWIP_LIB_DEBUG) + printf(" MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", + netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2], + netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5]); +#endif + +#if LWIP_IPV4 + netif->output = etharp_output; +#endif /* LWIP_IPV4 */ +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif /* LWIP_IPV6 */ + netif->linkoutput = low_level_output; + netif->mtu = 1500; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + eth_init(); /* activate u-boot eth dev */ + + if (IS_ENABLED(CONFIG_LWIP_LIB_DEBUG)) { + printf("Initialized LWIP stack\n"); + } + + return ERR_OK; +} + +int uboot_lwip_init(void) +{ + ip4_addr_t ipaddr, netmask, gw; + + if (uboot_net_use_lwip) + return CMD_RET_SUCCESS; + + ip4_addr_set_zero(&gw); + ip4_addr_set_zero(&ipaddr); + ip4_addr_set_zero(&netmask); + + ipaddr_aton(env_get("ipaddr"), &ipaddr); + ipaddr_aton(env_get("ipaddr"), &netmask); + + LWIP_PORT_INIT_NETMASK(&netmask); + if (IS_ENABLED(CONFIG_LWIP_LIB_DEBUG)) { + printf("Starting lwIP, IP: %s\n", ip4addr_ntoa(&ipaddr)); + printf(" GW: %s\n", ip4addr_ntoa(&gw)); + printf(" mask: %s\n", ip4addr_ntoa(&netmask)); + } + + if (!netif_add(&uboot_netif, &ipaddr, &netmask, &gw, + &uboot_netif, uboot_lwip_if_init, ethernetif_input)) + printf("err: netif_add failed!\n"); + + netif_set_up(&uboot_netif); + netif_set_link_up(&uboot_netif); +#if LWIP_IPV6 + netif_create_ip6_linklocal_address(&uboot_netif, 1); + printf(" IPv6: %s\n", ip6addr_ntoa(netif_ip6_addr(uboot_netif, 0))); +#endif /* LWIP_IPV6 */ + + uboot_net_use_lwip = 1; + + return CMD_RET_SUCCESS; +} + +/* placeholder, not used now */ +void uboot_lwip_destroy(void) +{ + uboot_net_use_lwip = 0; +} diff --git a/lib/lwip/port/include/arch/cc.h b/lib/lwip/port/include/arch/cc.h new file mode 100644 index 0000000000..db30d7614e --- /dev/null +++ b/lib/lwip/port/include/arch/cc.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#ifndef LWIP_ARCH_CC_H +#define LWIP_ARCH_CC_H + +#include +#include + +#define LWIP_ERRNO_INCLUDE + +#define LWIP_ERRNO_STDINCLUDE 1 +#define LWIP_NO_UNISTD_H 1 +#define LWIP_TIMEVAL_PRIVATE 1 + +extern unsigned int lwip_port_rand(void); +#define LWIP_RAND() (lwip_port_rand()) + +/* different handling for unit test, normally not needed */ +#ifdef LWIP_NOASSERT_ON_ERROR +#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ + handler; }} while (0) +#endif + +#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS + +#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \ + x, __LINE__, __FILE__); } while (0) + +static inline int atoi(const char *str) +{ + int r = 0; + int i; + + for (i = 0; str[i] != '\0'; ++i) + r = r * 10 + str[i] - '0'; + + return r; +} + +#define LWIP_ERR_T int + +#endif /* LWIP_ARCH_CC_H */ diff --git a/lib/lwip/port/include/arch/sys_arch.h b/lib/lwip/port/include/arch/sys_arch.h new file mode 100644 index 0000000000..8d95146275 --- /dev/null +++ b/lib/lwip/port/include/arch/sys_arch.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#ifndef LWIP_ARCH_SYS_ARCH_H +#define LWIP_ARCH_SYS_ARCH_H + +#include "lwip/opt.h" +#include "lwip/arch.h" +#include "lwip/err.h" + +#define ERR_NEED_SCHED 123 + +void sys_arch_msleep(u32_t delay_ms); +#define sys_msleep(ms) sys_arch_msleep(ms) + +#if SYS_LIGHTWEIGHT_PROT +typedef u32_t sys_prot_t; +#endif /* SYS_LIGHTWEIGHT_PROT */ + +#include + +#define SYS_MBOX_NULL NULL +#define SYS_SEM_NULL NULL + +typedef u32_t sys_prot_t; + +struct sys_sem; +typedef struct sys_sem *sys_sem_t; +#define sys_sem_valid(sem) (((sem) != NULL) && (*(sem) != NULL)) +#define sys_sem_set_invalid(sem) do { if ((sem) != NULL) { *(sem) = NULL; }} while (0) + +/* let sys.h use binary semaphores for mutexes */ +#define LWIP_COMPAT_MUTEX 1 +#define LWIP_COMPAT_MUTEX_ALLOWED 1 + +struct sys_mbox; +typedef struct sys_mbox *sys_mbox_t; +#define sys_mbox_valid(mbox) (((mbox) != NULL) && (*(mbox) != NULL)) +#define sys_mbox_set_invalid(mbox) do { if ((mbox) != NULL) { *(mbox) = NULL; }} while (0) + +struct sys_thread; +typedef struct sys_thread *sys_thread_t; + +static inline u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) +{ + return 0; +}; + +static inline err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + return 0; +}; + +#define sys_sem_signal(s) + +#endif /* LWIP_ARCH_SYS_ARCH_H */ diff --git a/lib/lwip/port/include/limits.h b/lib/lwip/port/include/limits.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/lwip/port/sys-arch.c b/lib/lwip/port/sys-arch.c new file mode 100644 index 0000000000..609eeccf8c --- /dev/null +++ b/lib/lwip/port/sys-arch.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +#include "lwip/opt.h" + +u32_t sys_now(void) +{ + return get_timer(0); +} + +u32_t lwip_port_rand(void) +{ + return (u32_t)rand(); +} + diff --git a/lib/lwip/ulwip.h b/lib/lwip/ulwip.h new file mode 100644 index 0000000000..11ca52aa1f --- /dev/null +++ b/lib/lwip/ulwip.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +int ulwip_enabled(void); +int ulwip_in_loop(void); +int ulwip_loop_set(int loop); +int ulwip_exit(int err); +int uboot_lwip_poll(void); +int ulwip_app_get_err(void); +void ulwip_set_tmo(int (*tmo)(void)); diff --git a/net/Kconfig b/net/Kconfig index a1ec3f8542..2c5d8b8aca 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -5,6 +5,7 @@ menuconfig NET bool "Networking support" default y + select LWIP_LIB if NET diff --git a/net/net.c b/net/net.c index 57da9bda85..3d9a2e798a 100644 --- a/net/net.c +++ b/net/net.c @@ -121,6 +121,7 @@ #endif #include #include +#include "../lib/lwip/ulwip.h" /** BOOTP EXTENTIONS **/ @@ -438,7 +439,11 @@ int net_loop(enum proto_t protocol) #endif bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); +#if defined(CONFIG_LWIP_LIB) + if (!ulwip_enabled() || !ulwip_in_loop()) +#endif net_init(); + if (eth_is_on_demand_init()) { eth_halt(); eth_set_current(); @@ -619,6 +624,18 @@ restart: */ eth_rx(); +#if defined(CONFIG_LWIP_LIB) + if (ulwip_enabled()) { + net_set_state(NETLOOP_CONTINUE); + if (!ulwip_in_loop()) { + if (ulwip_app_get_err()) + net_set_state(NETLOOP_FAIL); + else + net_set_state(NETLOOP_SUCCESS); + goto done; + } + } +#endif /* * Abort if ctrl-c was pressed. */ @@ -1177,6 +1194,13 @@ void net_process_received_packet(uchar *in_packet, int len) if (len < ETHER_HDR_SIZE) return; +#if defined(CONFIG_LWIP_LIB) + if (ulwip_enabled()) { + uboot_lwip_poll(); + return; + } +#endif + #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER) if (push_packet) { (*push_packet)(in_packet, len); From patchwork Fri Jul 14 14:19:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 1807845 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=c3yN6FPj; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R2YbY4vJKz20bh for ; Sat, 15 Jul 2023 00:22:49 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4193C86DBF; Fri, 14 Jul 2023 16:22:25 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="c3yN6FPj"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7B83C86D9F; Fri, 14 Jul 2023 16:22:24 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C31A286D9F for ; Fri, 14 Jul 2023 16:22:20 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=maxim.uvarov@linaro.org Received: by mail-lf1-x12d.google.com with SMTP id 2adb3069b0e04-4fb41682472so3134445e87.2 for ; Fri, 14 Jul 2023 07:22:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689344539; x=1691936539; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0ly0A465EoWIthKLtFvQ0b0chJdW/3kWw9H5ChuX6P4=; b=c3yN6FPjX+1JvMuVTisswh+zZYQX0WfYVK6Fo1HwZt2v8D3Cg9yb2wWVF/UkDfOaoa ZRgy2azybiu6U1OLNNAJFb8KSwP3JXNvtBeMpDyK3cppccmGNVQ3rTFuB9LSns55tvY/ PBEQiP9E3MK1LY4XtJV0oZwwKbko74l2NJYhXZDPr9a54h6s8LS4xBcL+MSOU+F9iOsz blKfQOvRQ/OPRp94N8QBA4+xdh2e8PugXCA9pxKuMdcikoImFvnmJ3NGKNgxktpllrHc fSf5JUcCp4QlzG6MwUWueL89IYL8wOHdZuHn5IgkCAjy24zj5VfGXqi1J+O3ZSuKu1RN RXNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689344539; x=1691936539; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0ly0A465EoWIthKLtFvQ0b0chJdW/3kWw9H5ChuX6P4=; b=j3AVrjr/2JCM73KbN8xt9eeXqDBiNdOdTQH+bcSuP8vLvGLKyESWVQauVhUtD1oS4u HSgbjYCmTUT75AuS5vcFJKyh/w9EqD+qtM+fMcR7wsdtSRve2Ge/fEQp3dxleCF3n5uC IPLaqUMx67Eq7pDf/MmQbOmy828J9NkdFRwxbNhnkx6jLtuhhj7hoMK/wbknFZ6bjkIg JfmWluV9NMkstC4GELaSjnKyQU2fRYmfJo8KfiF0AOZ3N5q83w63ho08OL4kds9188aY 30J929/r+YTcVkynOD5EaOqAZest9lQXmAGgN9JjLi4RHeCBKmXfFY6x3A+/fmbKlHR4 f/kg== X-Gm-Message-State: ABy/qLa8jcJSI1LfRPWPP0vj6ogNffDXt3cZyO1hHI0xbl1tVMUlDHEN dtTZU6p9IpKOzNfj+1/EXTHCxUGvH6lU3RupnC2Zvg== X-Google-Smtp-Source: APBJJlFfDLHOHPHVpWjc9Jddqu0MWlwYdjc8WCvcOkbdgowxTBFvQ3sfFZxwGdNjt3on54VawjaqvA== X-Received: by 2002:a19:6703:0:b0:4f8:7781:9875 with SMTP id b3-20020a196703000000b004f877819875mr3895542lfc.60.1689344539690; Fri, 14 Jul 2023 07:22:19 -0700 (PDT) Received: from localhost.localdomain ([45.82.14.220]) by smtp.gmail.com with ESMTPSA id w28-20020ac2599c000000b004fb759964a9sm1504703lfn.168.2023.07.14.07.22.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jul 2023 07:22:19 -0700 (PDT) From: Maxim Uvarov To: u-boot@lists.denx.de Cc: pbrobinson@redhat.com, ilias.apalodimas@linaro.org, joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com, goldsimon@gmx.de, lwip-devel@nongnu.org, Maxim Uvarov Subject: [PATCHv4 3/5] net/lwip: add doc/develop/net_lwip.rst Date: Fri, 14 Jul 2023 20:19:58 +0600 Message-Id: <20230714142000.5534-4-maxim.uvarov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230714142000.5534-1-maxim.uvarov@linaro.org> References: <20230714142000.5534-1-maxim.uvarov@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Just add inital doc. Signed-off-by: Maxim Uvarov --- doc/develop/index.rst | 1 + doc/develop/net_lwip.rst | 59 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 doc/develop/net_lwip.rst diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 97c526e997..a092c33df0 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -43,6 +43,7 @@ Implementation smbios spl uefi/index + net_lwip vbe version diff --git a/doc/develop/net_lwip.rst b/doc/develop/net_lwip.rst new file mode 100644 index 0000000000..567234fff2 --- /dev/null +++ b/doc/develop/net_lwip.rst @@ -0,0 +1,59 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +LWIP IP stack intergation for U-Boot +==================================== + +Intro +----- + +LWIP is a library for implementation network protocols, which is commonly used +on embedded devices. + +https://savannah.nongnu.org/projects/lwip/ + +LwIP  license: +LwIP is licensed under a BSD-style license: http://lwip.wikia.com/wiki/License. + +Main features include: + +* Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE + +* DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) + +* APIs: specialized APIs for enhanced performance, optional Berkeley-alike socket API + +* Extended features: IP forwarding over multiple network interfaces, TCP congestion control, RTT estimation and fast recovery/fast retransmit + +* Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, NetBIOS nameserver, mDNS responder, MQTT client, TFTP server + +U-Boot implementation details +----------------------------- + +1. In general we can build lwIP as .a library and link it against u-boot or compile it in +the U-Boot tree in the same way as other U-Boot files. There are few reasons why I selected +the second variant: LwIP is very customizable with defines for features, memory size, types of +allocation, some internal types and platform specific code. And it was more easy to enable/disable +debug which is also done with defines, and is needed periodically. + +2. lwIP has 2 APIs - raw mode and sequential (as lwIP names it, or socket API as we name it in Linux). +For now only raw API is supported. + +Raw IP means that the call back function for RX path is registered and will be called when packet +data passes the IP stack and is ready for the application. + +Example is unmodified working ping example from lwip sources which registeres the callback: + +.. code-block:: c + + ping_pcb = raw_new(IP_PROTO_ICMP); + raw_recv(ping_pcb, ping_recv, NULL); <- ping_recv is app callback. + raw_bind(ping_pcb, IP_ADDR_ANY) + +Socket API also gives nice advantages due it will be easy to port linux socket applications to u-boot. +I.e. LwIP sockets compatible with the linux ones. But that will require RX thread running in the background. +So that means we need some kind of scheduler, locking and threading support or find some other solution. + +3.  Input and output + +RX packet path is injected to U-Boot eth_rx() polling loop and TX patch is in eth_send() accordingly. +So we do not touch any drivers code and just eat packets when they are ready. From patchwork Fri Jul 14 14:19:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 1807848 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=bXwNoIUT; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R2Yby1DNXz20bh for ; Sat, 15 Jul 2023 00:23:10 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1837886DAA; Fri, 14 Jul 2023 16:22:30 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="bXwNoIUT"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 92C2986D9F; Fri, 14 Jul 2023 16:22:27 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 7BCCA86D8E for ; Fri, 14 Jul 2023 16:22:23 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=maxim.uvarov@linaro.org Received: by mail-lf1-x12a.google.com with SMTP id 2adb3069b0e04-4fbc0314a7bso3321820e87.2 for ; Fri, 14 Jul 2023 07:22:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689344542; x=1691936542; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3v87f7cM/ERrbjQrT2cSQg9G1XnEhUz63Ih+ldOPrzs=; b=bXwNoIUTTKkR636YUuxO3S1/ScDiy2FTx8xX0UTahOSRKtju+7cTdF1UxnlPkgsjC0 Syv/IiKbIhT3YeEECHZeVgdRFWorkaci15x57f/u3qfkWGe0N9mSSfZkXVMMTElvt3E+ BItco0GxGVd6qXtUj50Zqct2HB66qx14ZI66v0NLlLvguIHjChIIedzQ4e40nbl4ylVp CMD5JVPwnxPMGd1foOTLjK+Tfi5U6LGbK8Hd/naiYGRXYq9Sk7sEMwOj3sn8g2cwuIUA EviOQpwSw2s0H/G3q4LgI1abPd1G0myw6bLJdgK7dZN0iA3kUnClwWgFhABS3q82IN16 vV/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689344542; x=1691936542; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3v87f7cM/ERrbjQrT2cSQg9G1XnEhUz63Ih+ldOPrzs=; b=RqQtiMrSpWMeF7tShj8CzIZV8EOXURZPXRhHP4aQz8m+GWZzoykskD4Q6wdNr4Wlql QEu/eRGRzGXNL6NA23LLcFA2EIaIvucVccN0z66k+xOo5hp/zemRA1cC8ZjMOJhXrDYY yb4u8qLnHzf5gPDLFuXunqz1bQutfAHACV/FZhlsXRqHqa5CbReiP6RlMew4CtHtTb41 peHS9ywJqOw94R0BZ6Yp5pAgi11Ihx4dTr/4ZX2GaMa55/ReWRDIRcMuQO+M+Yq8zo9i YC1ojXHfxf9bit1bX73+s/KwINa2x32JLocJs1FeUiGMmT8sob5TDTYcnsDk0rJZM1va 0f9Q== X-Gm-Message-State: ABy/qLaVXgEIA+Soap/wzbs08M/dqtLZ+iw04MbvWp/YbA2/FL/azpRD UBCOhuvJIOGEEs7f3pWmr1KfmN+I7zREW3Gh4jOyxA== X-Google-Smtp-Source: APBJJlHXi2UaPzQV7oIP2Kn7j8l5GlLAO9yPb3OaenzdYTTyUKDYr1qng9YE+xkxwptEmfU+6QtLCg== X-Received: by 2002:a19:9117:0:b0:4f9:b649:23d2 with SMTP id t23-20020a199117000000b004f9b64923d2mr3637234lfd.42.1689344542601; Fri, 14 Jul 2023 07:22:22 -0700 (PDT) Received: from localhost.localdomain ([45.82.14.220]) by smtp.gmail.com with ESMTPSA id w28-20020ac2599c000000b004fb759964a9sm1504703lfn.168.2023.07.14.07.22.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jul 2023 07:22:22 -0700 (PDT) From: Maxim Uvarov To: u-boot@lists.denx.de Cc: pbrobinson@redhat.com, ilias.apalodimas@linaro.org, joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com, goldsimon@gmx.de, lwip-devel@nongnu.org, Maxim Uvarov Subject: [PATCHv4 4/5] net/lwip: add dns command Date: Fri, 14 Jul 2023 20:19:59 +0600 Message-Id: <20230714142000.5534-5-maxim.uvarov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230714142000.5534-1-maxim.uvarov@linaro.org> References: <20230714142000.5534-1-maxim.uvarov@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean dns lwip version of the command. This commmit might be good example how to enable new network command. Signed-off-by: Maxim Uvarov --- cmd/net.c | 41 +++----------------------------- lib/lwip/Kconfig | 2 +- lib/lwip/Makefile | 2 ++ lib/lwip/apps/dns/lwip-dns.c | 46 ++++++++++++++++++++++++++++++++++++ lib/lwip/apps/dns/lwip-dns.h | 3 +++ lib/lwip/cmd-lwip.c | 39 ++++++++++++++++++++++++++++++ lib/lwip/lwipopts.h | 2 +- 7 files changed, 95 insertions(+), 40 deletions(-) create mode 100644 lib/lwip/apps/dns/lwip-dns.c create mode 100644 lib/lwip/apps/dns/lwip-dns.h diff --git a/cmd/net.c b/cmd/net.c index 6d704fba86..2a68477aae 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -491,45 +491,10 @@ 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; -} - +extern int do_lwip_dns(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]); 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/lib/lwip/Kconfig b/lib/lwip/Kconfig index 3688ac3305..5e9062a6da 100644 --- a/lib/lwip/Kconfig +++ b/lib/lwip/Kconfig @@ -26,7 +26,7 @@ config LWIP_LIB_UDP config LWIP_LIB_DNS bool "dns" - default n + default y config LWIP_LIB_DHCP bool "dhcp" diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile index e1a8a2a7b7..d6e511dff1 100644 --- a/lib/lwip/Makefile +++ b/lib/lwip/Makefile @@ -99,3 +99,5 @@ obj-$(CONFIG_CMD_TFTPBOOT) += apps/tftp/tftp.o obj-$(CONFIG_CMD_TFTPBOOT) += apps/tftp/lwip-tftp.o obj-$(CONFIG_CMD_DHCP) += apps/dhcp/lwip-dhcp.o + +obj-$(CONFIG_CMD_DNS) += apps/dns/lwip-dns.o diff --git a/lib/lwip/apps/dns/lwip-dns.c b/lib/lwip/apps/dns/lwip-dns.c new file mode 100644 index 0000000000..04fd53bfcb --- /dev/null +++ b/lib/lwip/apps/dns/lwip-dns.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +#include + +#include +#include + +#include "../../../lwip/ulwip.h" + +static void dns_found_cb(const char *name, const ip_addr_t *ipaddr, void *callback_arg) +{ + char *varname = (char *)callback_arg; + + if (varname) + env_set(varname, ip4addr_ntoa(ipaddr)); + + printf("resolved %s to %s\n", name, ip4addr_ntoa(ipaddr)); + ulwip_exit(0); +} + +int ulwip_dns(char *name, char *varname) +{ + int err; + ip_addr_t ipaddr; /* not used */ + ip_addr_t dns1; + ip_addr_t dns2; + + ipaddr_aton(env_get("dnsip"), &dns1); + ipaddr_aton(env_get("dnsip2"), &dns2); + + dns_init(); + dns_setserver(0, &dns1); + dns_setserver(1, &dns2); + + err = dns_gethostbyname(name, &ipaddr, dns_found_cb, varname); + if (err == ERR_OK) + dns_found_cb(name, &ipaddr, varname); + + return err; +} diff --git a/lib/lwip/apps/dns/lwip-dns.h b/lib/lwip/apps/dns/lwip-dns.h new file mode 100644 index 0000000000..c59f99e099 --- /dev/null +++ b/lib/lwip/apps/dns/lwip-dns.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +int ulwip_dns(char *name, char *varname); diff --git a/lib/lwip/cmd-lwip.c b/lib/lwip/cmd-lwip.c index 625c8c53b8..86b35ccff8 100644 --- a/lib/lwip/cmd-lwip.c +++ b/lib/lwip/cmd-lwip.c @@ -12,6 +12,7 @@ #include #include +#include "apps/dns/lwip-dns.h" #include "apps/ping/lwip_ping.h" #include "ulwip.h" @@ -208,6 +209,39 @@ static int _do_lwip_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, } #endif /* CONFIG_CMD_DHCP */ +#if defined(CONFIG_CMD_DNS) +int do_lwip_dns(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + char *name; + char *varname; + int LWIP_ERR_INPROGRESS = -5; + + if (argc == 1) + return CMD_RET_USAGE; + + name = argv[1]; + + if (argc == 3) + varname = argv[2]; + else + varname = NULL; + + uboot_lwip_init(); + + ret = ulwip_dns(name, varname); + if (ret == 0) + return CMD_RET_SUCCESS; + if (ret != LWIP_ERR_INPROGRESS) + return CMD_RET_FAILURE; + + net_set_timeout_handler(1000UL, ulwip_timeout_handler); + + return ulwip_loop(); +} +#endif /* CONFIG_CMD_DNS */ + static struct cmd_tbl cmds[] = { U_BOOT_CMD_MKENT(info, 1, 0, do_lwip_info, "Info and stats", ""), U_BOOT_CMD_MKENT(init, 1, 0, do_lwip_init, @@ -230,6 +264,11 @@ static struct cmd_tbl cmds[] = { "boot image via network using DHCP/TFTP protocol", ""), #endif +#if defined(CONFIG_CMD_DNS) + U_BOOT_CMD_MKENT(dns, 3, 0, do_lwip_dns, + "lookup dns name [and store address at variable]", + ""), +#endif }; static int do_ops(struct cmd_tbl *cmdtp, int flag, int argc, diff --git a/lib/lwip/lwipopts.h b/lib/lwip/lwipopts.h index b943d7b9be..7f99a536ee 100644 --- a/lib/lwip/lwipopts.h +++ b/lib/lwip/lwipopts.h @@ -43,7 +43,7 @@ #define SLIP_DEBUG LWIP_DBG_OFF #define DHCP_DEBUG LWIP_DBG_ON #define AUTOIP_DEBUG LWIP_DBG_ON -#define DNS_DEBUG LWIP_DBG_OFF +#define DNS_DEBUG LWIP_DBG_ON #define IP6_DEBUG LWIP_DBG_OFF #define DHCP6_DEBUG LWIP_DBG_OFF #else From patchwork Fri Jul 14 14:20:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 1807849 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=BlHxrmp1; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R2YcD5vp4z20bh for ; Sat, 15 Jul 2023 00:23:24 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1554E86DC8; Fri, 14 Jul 2023 16:22:35 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="BlHxrmp1"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 66BE886DBA; Fri, 14 Jul 2023 16:22:29 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id F22C886D20 for ; Fri, 14 Jul 2023 16:22:26 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=maxim.uvarov@linaro.org Received: by mail-lf1-x134.google.com with SMTP id 2adb3069b0e04-4f954d7309fso2394279e87.1 for ; Fri, 14 Jul 2023 07:22:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689344546; x=1691936546; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uhHKOSp14TbQWgMLwoQOm7YiaKI8a4TZyyde6l3hn6o=; b=BlHxrmp1A2PUIo3S/CZU2mAD83Cv4IfyuGgMFZEnaWjEp4CHdZc5rfmcj0uehOdUL6 HOJ0PUCy7NgylBO23LgTTfrHgtBbvfqAc5YJC8DTP/SsfewWwJhfi7skJI4E4p+AZ/Nw dBqIsWrjaO8CWfc3gXb9D+SW1Z/zpQ1IlhaFssHKob7zrVoVdh0kk6ZQ1RIHP8Y+l1Gn yplDVzWesDBpk+1ijHf7gHvj2dKR7HWDN3EgcmR7GdFsS0aSs8w6L2CIAeTrtPfyucYQ m3EN9KNusbKIWyuKl6RV7LCfs00dFS9u070p8YW9W/V88kxCHxgBrSI6YED3krY19gRU nL4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689344546; x=1691936546; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uhHKOSp14TbQWgMLwoQOm7YiaKI8a4TZyyde6l3hn6o=; b=hx5SI1JmHCltNgk4gFzDJttyH2WaPsHWauQmJRQ0Rn+ZynwJJk/tc74ZgOHyz0PlDe Kfa++g/2G6wQq+s4za+SSCTcwjDdSBaI9OOwYtp29DLFJMpPLwD696MX9N8IiYUrSjUy 8HcfzNm1FSNIAfG9YcgEffjSYtglcN9Hw3Tl+64DEPHdKz5qwI0w6RMlLMo5q83trtaJ JzQVXZlDFxJrzmWdysfnc7kHhWcCTWuq/H22w+dX3SpHJNtPrHdrvf76bVIqDeoIcVNi Pd6cBL3VbGNsO6xLirg9eZI6drOEvJ8fNel7omlvnjnJa2HVmaZgxv3C0zwE0KMes2Df 8XDQ== X-Gm-Message-State: ABy/qLZPNmjij07lcQ4BneNsY4NwmlArl+9Q0dQKcHYA6zqsPB4hN/IL ZJlwaedWgiiG/vHYL6iCuxHeleTqAJhKehtCB/9zLA== X-Google-Smtp-Source: APBJJlEQOeSFqe/xLsqNiA8ujGjbFEn6aM4cDlkFHYBoPES0ZWz576QzUDeqzowQRaH9K/qK/CsmhA== X-Received: by 2002:a05:6512:6d4:b0:4f8:5e4e:52ad with SMTP id u20-20020a05651206d400b004f85e4e52admr883332lff.23.1689344546046; Fri, 14 Jul 2023 07:22:26 -0700 (PDT) Received: from localhost.localdomain ([45.82.14.220]) by smtp.gmail.com with ESMTPSA id w28-20020ac2599c000000b004fb759964a9sm1504703lfn.168.2023.07.14.07.22.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jul 2023 07:22:25 -0700 (PDT) From: Maxim Uvarov To: u-boot@lists.denx.de Cc: pbrobinson@redhat.com, ilias.apalodimas@linaro.org, joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com, goldsimon@gmx.de, lwip-devel@nongnu.org, Maxim Uvarov Subject: [PATCHv4 5/5] net/lwip: apps/http: add dns support Date: Fri, 14 Jul 2023 20:20:00 +0600 Message-Id: <20230714142000.5534-6-maxim.uvarov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230714142000.5534-1-maxim.uvarov@linaro.org> References: <20230714142000.5534-1-maxim.uvarov@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean provide hostname to client and allow lwip to resolve it. Signed-off-by: Maxim Uvarov --- lib/lwip/apps/http/lwip-wget.c | 59 ++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/lib/lwip/apps/http/lwip-wget.c b/lib/lwip/apps/http/lwip-wget.c index 0308b0b04a..db553a0f14 100644 --- a/lib/lwip/apps/http/lwip-wget.c +++ b/lib/lwip/apps/http/lwip-wget.c @@ -45,18 +45,65 @@ static void httpc_result(void *arg, httpc_result_t httpc_result, u32_t rx_conten } } +/* http://hostname:port/url */ +static int parse_url(char *url, char *host, int *port) +{ + int ret; + char *p, *pp; + + p = strstr(url, "http://"); + if (!p) { + printf("err: no http://!\n"); + return -1; + } + + p += strlen("http://"); + + /* parse hostname */ + pp = strchr(p, ':'); + if (pp) { + char portstr[5]; + + memcpy(host, p, pp - p); + host[pp - p + 1] = '\0'; + + p = pp + 1; + pp = strchr(p, '/'); + if (!pp) { + printf("wrong url\n"); + return -2; + } + + memcpy(portstr, p, pp - p); + portstr[pp - p] = '\0'; + *port = atoi(portstr); + } else { + pp = strchr(p, '/'); + if (!pp) { + printf("wrong url\n"); + return -3; + } + memcpy(host, p, pp - p); + host[pp - p + 1] = '\0'; + *port = 80; /* default */ + } + + return 0; +} + int lwip_wget(ulong addr, char *url) { err_t err; - int port = 80; - char *server_name; + int port; + char server_name[80]; httpc_state_t *connection; daddr = addr; - server_name = env_get("serverip"); - if (!server_name) { - printf("error: serverip variable has to be set\n"); - return CMD_RET_FAILURE; + + err = parse_url(url, server_name, &port); + if (err) { + printf("error parse_url\n"); + return -1; } printf("downloading %s to addr 0x%lx\n", url, addr);