From patchwork Tue Sep 1 17:08:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296150 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=kftb0gdW; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=MTymjFA+; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC5q6JQdz1xwZ for ; Wed, 02 Sep 2026 03:09:51 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 96CCA4077F; Tue, 1 Sep 2026 17:09:47 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 6hiuutQxX6fy; Tue, 1 Sep 2026 17:09:45 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282585; bh=cWDW4ou5ukSTQEx/TRMHbtmjvGiOxYjc6aVG0YmFKhk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=kftb0gdWdG9dkCUMfDY6FADUgSAZpg9eQijgjAN2ZwfpTupvkjAL/PshnC0zYObB/ pMaSI/Dnz/aaxD06s6erg/sSAfQvrjBUNgTtvRmmgl7KNQiYf0Kqe1k0bCOdJUd48M RR7jYGzXPj6XY7iMM3xB0HUlQJIfkx3vT1HzWtrjTrO9qe1/LPI5KYidzOl3ks0TAN wRiKFQ7nB3fZSwjLRAJnLM+vcKkK4yPQUKFwej2jjP9GWNzgnN6Rg+4nFYhfxxjQTY 6HOyJZvmZIrqcnuVcESWa+r/QWb0Ow5T6YeZXpsjE/sG6QXel+4ZQaa844p9cstUT3 HfiGTdGGiQlcQ== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp4.osuosl.org (Postfix) with ESMTP id 8FD304073C; Tue, 1 Sep 2026 17:09:45 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists1.osuosl.org (Postfix) with ESMTP id 0DE33265 for ; Tue, 1 Sep 2026 17:09:43 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 00176401ED for ; Tue, 1 Sep 2026 17:09:42 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id HnOe0i36czOj for ; Tue, 1 Sep 2026 17:09:42 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::32d; helo=mail-ot1-x32d.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=MTymjFA+ Received: from mail-ot1-x32d.google.com (mail-ot1-x32d.google.com [IPv6:2607:f8b0:4864:20::32d]) by smtp2.osuosl.org (Postfix) with ESMTPS id 320704002B for ; Tue, 1 Sep 2026 17:09:41 +0000 (UTC) Received: by mail-ot1-x32d.google.com with SMTP id 46e09a7af769-7e9ecb1e13cso5140360a34.3 for ; Tue, 01 Sep 2026 10:09:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282580; x=1788887380; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=cWDW4ou5ukSTQEx/TRMHbtmjvGiOxYjc6aVG0YmFKhk=; b=MTymjFA+oTKLc3wxx50NeEaxzmgrLwTXU7lO74v28ZxL12rw8LxL5Qdb26DU+MwUjq DaAtbCGAT2NoVfvX91y0Kfh6BePWRpO0VFy3hd6yhcrxl1Syi2yTV7niI+1OIq2ZNolA qBlhSlDadGhRXNiGZW/YyL+pJ0v9xg7CfBdBFwOHuSCB7vSX02KCcslSVyMXLEeqjH/E tEEUq3AbvD4qzhz6rqqr9bJDSkUSPY7VXJ4RHARXNlzidDjBDRz5gXHTvWUeI0sFJRt1 JyAAmKGqOtoHmWYOd7P4gDNzpXmlXunw7kBA6QINqUeSReI9wWaVmBhzBJV01C46B656 fh1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282580; x=1788887380; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=cWDW4ou5ukSTQEx/TRMHbtmjvGiOxYjc6aVG0YmFKhk=; b=i/6AX06UGlJpDMeoi6Ljvo+u9Usnn13glDT13zVtdn7IUGflYGYVtQj+ThVwiq4vmB x+vWrxU7vtvCQo4jkUOutD6clnGnnuZrBqr3xt1Nn6byFGbs8cFWiItxyY1elqNSqFi/ 5ek7KsnRJvx49q4BGRNb+RFWg/nEY+BqDQv7oDNH730Zq6kbBQaqPdyU4fwRNUDXy0B0 rnlQGE7K7YZowQGAGfAKtTF2un1PFE7+YAVQjfOh9PpOwygHPGUTihsP5Au3Dn11VOnk a6M3oqPKJmZy2GHZrjhtvWNxrXx1tzMQhNyWqfyUNr1tGyQPKavQ4og7KGbtpT97l7qH XBnw== X-Gm-Message-State: AFuF++nAG1DfDpIqV4e5yG1xLT/6IjBXsD+IAjaoxhdL+0Da1UvcbJ+R qqqr/7EjMbOwQ5hKq1HwsThipGTMbPk+gZVuCf9Rv8rXGbgAJq6JYgdc X-Gm-Gg: AR+sD10aq0JlPz0IHa+28JTfBqOoPJepl45uaeg8HgsfBV9o+mWNrldOVUxQCpdcpQx 9fL29hDa9URtK9qImPglrdN51p1feuSl0+9Jz/pBnGfD0USoXKJmZSMLxEHUg385KlGdBRpnqFw UxecCz2daAq9urza2xG1BIdQjjKWAiaGfoiubvCT7jip6Ylt6hikD3uGaFMKHf5Wi+XpIMDYnax d9aaTSrEgVNsjMjFlY4MR2Gd6GsdOi+b6XBiBz0PM2K1VmN/rORmifG37rC75AIKpXlijM1JMBl HDayMbOSXKgSMaYrylqqsviVjR6EvmNhu57DanNwQ+sNlShbOHdHtcOWC2y1DzWBrdZVlD+rETo y0SheE3pc2TKh6X5ew9KB+KMkhBHADYfjCvIfsDdaAxYRJBQbCUBVawmNxaM8fmQ69tsfUpBDle W0UrlZNlrG0K4mboXjVQDX1phOLlB1t5WZ5+IOpqPt+s9E47FRnWrHEg70zIAUDUvwigwL+EP3c ZOYIYsRmHUICcfVt6p7HsnjxQzKCXNMdyaH2jgxyD1diRBP9k1mCNXFSTaWOS+Avn+TXrLrx1rj nYOW8+HdrWuGFY4uhdVzVJe0+eZ2BGZg8tLca2eIeZk/y2v+3A2fcabuADDJmbeewYZP2fPa0jA dIQz/MZa4CgD8Hx/9Lxo= X-Received: by 2002:a05:6830:f8c:b0:7f4:bba7:f547 with SMTP id 46e09a7af769-7f4f258280fmr39762636a34.10.1788282580257; Tue, 01 Sep 2026 10:09:40 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:39 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:08:55 -0600 Subject: [PATCH v2 01/10] net: lwip: return ERR_ABRT after aborting wget receive MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-1-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org altcp_abort() deallocates the connection PCB. A raw TCP receive callback which calls it must return ERR_ABRT so the TCP input path does not access the released PCB. The wget receive callback instead returns ERR_BUF when storing received data fails. Return ERR_ABRT after aborting the connection. Fixes: e40c910e88a9 ("net-lwip: wget: add LMB and buffer checks") Signed-off-by: James Hilliard --- net/lwip/wget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/lwip/wget.c b/net/lwip/wget.c index 247ece18e2b..e8930da410b 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -206,7 +206,7 @@ static err_t httpc_recv_cb(void *arg, struct altcp_pcb *pcb, struct pbuf *pbuf, for (buf = pbuf; buf; buf = buf->next) { if (store_block(ctx, buf->payload, buf->len) < 0) { altcp_abort(pcb); - ret = ERR_BUF; + ret = ERR_ABRT; goto out; } } From patchwork Tue Sep 1 17:08:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296154 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=YVNaw4+m; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=Fo+Lx8lk; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC5t0W2Wz1xyG for ; Wed, 02 Sep 2026 03:09:54 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 7E8E080E2F; Tue, 1 Sep 2026 17:09:50 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 6SuevxlCumdv; Tue, 1 Sep 2026 17:09:49 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282589; bh=n6IQVvs+//tzixIbtAg9AR6B13IDlVn256/OLCMEA9A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=YVNaw4+m5gSQE7ocoh9tD3J5z13zaGvQmC5IvrVstMRaVRCiPAXZ0s4B2VrCdzM9G kZ7tRtRYDS8qjlwqhRrJaZshfWCcj7Ver2z+1HW0xOnCMXwFrI8bve1skjXCgotHs0 ngSgY4x8nbJDnidqWSsiTnun1304PlWq2yPQEaIJkFpTuWnaJAhQMK7pkAccZ4wR13 /RugNuMJ+8h8ufT0n/6VmfbXSbOgugdYrj3686V+RWUjpYJ49354hUPuGZQYh9P3Iu EjHujsvQKD0KykZP6qmBOdQ/fvi98uNkooD8mUI1qeMwMqCtLmilbVjbX8+83abHBK xqVTX1mpW04jg== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp1.osuosl.org (Postfix) with ESMTP id 16E6680DE0; Tue, 1 Sep 2026 17:09:49 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists1.osuosl.org (Postfix) with ESMTP id BB75C2FD for ; Tue, 1 Sep 2026 17:09:45 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id AD9D040743 for ; Tue, 1 Sep 2026 17:09:45 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id Pb9rwbDJCF1F for ; Tue, 1 Sep 2026 17:09:44 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::330; helo=mail-ot1-x330.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp4.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=Fo+Lx8lk Received: from mail-ot1-x330.google.com (mail-ot1-x330.google.com [IPv6:2607:f8b0:4864:20::330]) by smtp4.osuosl.org (Postfix) with ESMTPS id 631A640731 for ; Tue, 1 Sep 2026 17:09:43 +0000 (UTC) Received: by mail-ot1-x330.google.com with SMTP id 46e09a7af769-7f4df360cc9so58911a34.1 for ; Tue, 01 Sep 2026 10:09:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282583; x=1788887383; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=n6IQVvs+//tzixIbtAg9AR6B13IDlVn256/OLCMEA9A=; b=Fo+Lx8lk32rAIrxpDEiVxw0SawVyW2jr37dtHCCJ3Hg14vtxg5q6he4bXawW5sGXi3 VCOzk6BIbEg1EyRxg6HxqwVK/aW+lbtdCYiuStKZny/p10zym3PyUnQnQ1as3zDQS/t8 Lv8eqVbKd3HieAMx7SKL18RlaKZIEwh+b6h5vsFnnrX+lZWPTbl1RvdQ3WqlTynlC04h 916UJTVbdYhRL/D8PKVBVVswGLpkEuNsP54LHY6gLQsLuiOMH8+pNGRzx2Wqt8CGK/+W 271c4AyDVtDShdPWzmg0FQaxQ7v3wZN8/rZ8ZoLhDppKKqtjzb0Yn5f/6ACegOMB33Bm dDFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282583; x=1788887383; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=n6IQVvs+//tzixIbtAg9AR6B13IDlVn256/OLCMEA9A=; b=SPINKVatwOSfxpfBYgU95XE1lRJdmaB+nnlyTTjxkyMcvtjv4UE+FKp2XKmFPjywtW +vAhIIHIIRooGZNxHVrHo+VEuQa/1x4ccgEk+/j0kiQd18/Fslu3m+ez6ZpcCgsSeSE9 Yysk88vq7ZecyJ0lLEl9L9UA2kplflp1AEDijS+KAInPOD8LqAH2U5cFD9eQJXOOz3jk 4lXEkf1VIQEVLWRgFYXL8V8jX0FfXl/yABqVIdpbuDcxpOq7F2MWP8Z5wO1LSnfsPqNm GVpxs50YN0Iw7ujueb7CHeOePAAxJQ9XfJ/QX/Ii/U7LCwN52Wjay8W1IyCd947JQtgJ jI/w== X-Gm-Message-State: AFuF++nWdQkENf60SnCWm75zuafsmq9SO2a83u1KufnR2ljUkLOIMUBn RiIvYGulaRdP6sBE4rvN1A+ZgJcA6bxmtpHOZdj0AFNc2RgJWHmvXZkb X-Gm-Gg: AR+sD112bMqfJeEX4WG4nce1DVwwMuZCC6Y+7vxJh/lMGqB0QFdJw5dR4ROL1kcZAiL iq33IXDZDJ3X8JCkOATdUelETd0b4vA+4HRzjxuIXPX7cLOMxb+jil61i28swk6/ZW1YRcigpQ/ rEoPtvxjlfmZ6MIFtX2pfAdBgITac8Y0kghs1/asCW2VEoF0qC5Qhje3x8tR3dZV3omA8B3zR+F MB19KCjra8P6pl87M8DCN+E+K9GUjr7stpvimQBnsOh/dGGqVX2+8IhzkG3X3ulQ6bsJrlabyLp cDTRNw5v1JZCx8CIAzXSQSlvsROwCfwQHcc25rECMsJXjb+Ao4/H+OYYxpZlMOH3Lx3zu9+4q9x 5QEBTKWuWDK5Ijxf6YkAz+liZm6ljhfvA00vROxBRmX7jGhdUw/OPDKPh2SVHai/ZeSfrBEEiRi 6/H6grZQ7wV5Z1QkB0k9pvRggsm9I/LHM1IhalVFN7jhxt9UMuAdzmbV4JNpste1YObIWeVFUnh rZ7mnndBLjzMn4FTeh8bDsgNve6qleYtfsgoA1TP3WQep2a6VY1ODFN+MAWz1XB1WQj6sd3wbTZ c0s2qidA3jEjb9DGac4/5riPu5GXAfGIR740/qA7TLxAFpHIOvdm76aDUMCg8PJDBvBkvDu26en 62iCky0Oe3osioTi3XyA= X-Received: by 2002:a05:6830:82ec:b0:7e9:e5df:5ee2 with SMTP id 46e09a7af769-7f68f6d3fa9mr5892781a34.6.1788282581213; Tue, 01 Sep 2026 10:09:41 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:40 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:08:56 -0600 Subject: [PATCH v2 02/10] net: split netconsole transport from stdio frontend MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-2-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org Netconsole's environment handling, input buffer and stdio registration do not depend on a particular network stack. Packet transmission and polling do. Move the existing net_loop and raw-packet code into a legacy transport file. This leaves legacy behavior unchanged and provides a transport interface for other network stacks. Signed-off-by: James Hilliard --- drivers/net/Makefile | 5 +- drivers/net/netconsole-legacy.c | 156 ++++++++++++++++++++++++++++++++++ drivers/net/netconsole.c | 184 ++++++++-------------------------------- drivers/net/netconsole.h | 29 +++++++ 4 files changed, 226 insertions(+), 148 deletions(-) diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 4c1f4094ab2..32bf86e14ae 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -82,7 +82,10 @@ obj-$(CONFIG_MVGBE) += mvgbe.o obj-$(CONFIG_MVMDIO) += mvmdio.o obj-$(CONFIG_MVNETA) += mvneta.o obj-$(CONFIG_MVPP2) += mvpp2.o -obj-$(CONFIG_NETCONSOLE) += netconsole.o +ifdef CONFIG_NETCONSOLE +obj-y += netconsole.o +obj-$(CONFIG_NET_LEGACY) += netconsole-legacy.o +endif obj-$(CONFIG_NET_NPCM750) += npcm750_eth.o obj-$(CONFIG_NET_OCTEON) += octeon/ obj-$(CONFIG_NET_OCTEONTX) += octeontx/ diff --git a/drivers/net/netconsole-legacy.c b/drivers/net/netconsole-legacy.c new file mode 100644 index 00000000000..c3c69a94a21 --- /dev/null +++ b/drivers/net/netconsole-legacy.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + */ + +#include +#include + +#include "netconsole.h" + +static int net_timeout; +static uchar nc_ether[ARP_HLEN]; +static const char *output_packet; +static int output_packet_len; + +/* + * Start with a default last protocol. + * We are only interested in NETCONS or not. + */ +enum proto_t net_loop_last_protocol = BOOTP; + +static void nc_wait_arp_handler(uchar *pkt, unsigned int dest, + struct in_addr sip, unsigned int src, + unsigned int len) +{ + net_set_state(NETLOOP_SUCCESS); +} + +static void nc_handler(uchar *pkt, unsigned int dest, struct in_addr sip, + unsigned int src, unsigned int len) +{ + if (nc_has_input()) + net_set_state(NETLOOP_SUCCESS); +} + +static void nc_timeout_handler(void) +{ + net_set_state(NETLOOP_SUCCESS); +} + +static int nc_legacy_refresh_settings(void) +{ + int ret; + + ret = nc_refresh_settings_from_env(); + if (ret <= 0) + return ret; + + if (nc_is_broadcast(nc_settings.ip)) + memset(nc_ether, 0xff, sizeof(nc_ether)); + else + memset(nc_ether, 0, sizeof(nc_ether)); + + return 0; +} + +/** + * nc_start() - Configure the legacy network loop for netconsole + * + * Called from net_loop() before processing each packet. + */ +void nc_start(void) +{ + nc_legacy_refresh_settings(); + if (!output_packet_len || memcmp(nc_ether, net_null_ethaddr, ARP_HLEN)) { + net_set_udp_handler(nc_handler); + net_set_timeout_handler(net_timeout, nc_timeout_handler); + } else { + uchar *pkt; + + net_set_arp_handler(nc_wait_arp_handler); + pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + + IP_UDP_HDR_SIZE; + memcpy(pkt, output_packet, output_packet_len); + net_send_udp_packet(nc_ether, nc_settings.ip, + nc_settings.out_port, nc_settings.in_port, + output_packet_len); + } +} + +void nc_transport_send(const char *buf, int len) +{ + struct udevice *eth; + int inited = 0; + uchar *pkt; + + debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf); + + eth = eth_get_dev(); + if (!eth) + return; + + if (!memcmp(nc_ether, net_null_ethaddr, ARP_HLEN)) { + if (eth_is_active(eth)) + return; + output_packet = buf; + output_packet_len = len; + nc_set_input_recursion(true); + net_loop(NETCONS); + nc_set_input_recursion(false); + output_packet_len = 0; + return; + } + + if (!eth_is_active(eth)) { + if (eth_is_on_demand_init()) { + if (eth_init() < 0) + return; + eth_set_last_protocol(NETCONS); + } else { + eth_init_state_only(); + } + + inited = 1; + } + + pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE; + memcpy(pkt, buf, len); + net_send_udp_packet(nc_ether, nc_settings.ip, nc_settings.out_port, + nc_settings.in_port, len); + + if (inited) { + if (eth_is_on_demand_init()) + eth_halt(); + else + eth_halt_state_only(); + } +} + +void nc_transport_poll(bool block) +{ + struct udevice *eth = eth_get_dev(); + + if (eth_is_active(eth)) + return; + + net_timeout = block ? 0 : 1; + net_loop(NETCONS); +} + +int nc_transport_start(void) +{ + int ret; + + ret = nc_legacy_refresh_settings(); + if (ret) + return ret; + + return net_init(); +} + +int nc_transport_stop(void) +{ + return 0; +} diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index c2ce4a80d12..305a6cf12c6 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -4,13 +4,14 @@ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. */ -#include #include #include #include #include #include +#include "netconsole.h" + #ifndef CFG_NETCONSOLE_BUFFER_SIZE #define CFG_NETCONSOLE_BUFFER_SIZE 512 #endif @@ -20,39 +21,9 @@ static int input_size; /* char count in input buffer */ static int input_offset; /* offset to valid chars in input buffer */ static int input_recursion; static int output_recursion; -static int net_timeout; -static uchar nc_ether[6]; /* server enet address */ -static struct in_addr nc_ip; /* server ip */ -static short nc_out_port; /* target output port */ -static short nc_in_port; /* source input port */ -static const char *output_packet; /* used by first send udp */ -static int output_packet_len; -/* - * Start with a default last protocol. - * We are only interested in NETCONS or not. - */ -enum proto_t net_loop_last_protocol = BOOTP; - -static void nc_wait_arp_handler(uchar *pkt, unsigned dest, - struct in_addr sip, unsigned src, - unsigned len) -{ - net_set_state(NETLOOP_SUCCESS); /* got arp reply - quit net loop */ -} +struct nc_settings nc_settings; -static void nc_handler(uchar *pkt, unsigned dest, struct in_addr sip, - unsigned src, unsigned len) -{ - if (input_size) - net_set_state(NETLOOP_SUCCESS); /* got input - quit net loop */ -} - -static void nc_timeout_handler(void) -{ - net_set_state(NETLOOP_SUCCESS); -} - -static int is_broadcast(struct in_addr ip) +bool nc_is_broadcast(struct in_addr ip) { static struct in_addr netmask; static struct in_addr our_ip; @@ -73,7 +44,7 @@ static int is_broadcast(struct in_addr ip) (netmask.s_addr | ip.s_addr) == ~0)); /* bcast to our net */ } -static int refresh_settings_from_env(void) +int nc_refresh_settings_from_env(void) { const char *p; static int env_changed_id; @@ -82,56 +53,41 @@ static int refresh_settings_from_env(void) /* update only when the environment has changed */ if (env_changed_id != env_id) { char *tmp = env_get("ncip"); + if (tmp) { - nc_ip = string_to_ip(tmp); - if (!nc_ip.s_addr) + nc_settings.ip = string_to_ip(tmp); + if (!nc_settings.ip.s_addr) return -1; /* ncip is 0.0.0.0 */ p = strchr(tmp, ':'); if (p != NULL) { - nc_out_port = dectoul(p + 1, NULL); - nc_in_port = nc_out_port; + nc_settings.out_port = dectoul(p + 1, NULL); + nc_settings.in_port = nc_settings.out_port; } } else { - nc_ip.s_addr = ~0; /* ncip is not set, so broadcast */ + nc_settings.ip.s_addr = ~0; } p = env_get("ncoutport"); if (p != NULL) - nc_out_port = dectoul(p, NULL); + nc_settings.out_port = dectoul(p, NULL); p = env_get("ncinport"); if (p != NULL) - nc_in_port = dectoul(p, NULL); - - if (is_broadcast(nc_ip)) - /* broadcast MAC address */ - memset(nc_ether, 0xff, sizeof(nc_ether)); - else - /* force arp request */ - memset(nc_ether, 0, sizeof(nc_ether)); + nc_settings.in_port = dectoul(p, NULL); + + return 1; } + return 0; } -/** - * Called from net_loop in net/net.c before each packet - */ -void nc_start(void) +bool nc_has_input(void) { - refresh_settings_from_env(); - if (!output_packet_len || memcmp(nc_ether, net_null_ethaddr, 6)) { - /* going to check for input packet */ - net_set_udp_handler(nc_handler); - net_set_timeout_handler(net_timeout, nc_timeout_handler); - } else { - /* send arp request */ - uchar *pkt; - net_set_arp_handler(nc_wait_arp_handler); - pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + - IP_UDP_HDR_SIZE; - memcpy(pkt, output_packet, output_packet_len); - net_send_udp_packet(nc_ether, nc_ip, nc_out_port, nc_in_port, - output_packet_len); - } + return input_size != 0; +} + +void nc_set_input_recursion(bool enable) +{ + input_recursion = enable; } int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, @@ -139,10 +95,11 @@ int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, { int end, chunk; - if (dest_port != nc_in_port || !len) + if (dest_port != nc_settings.in_port || !len) return 0; /* not for us */ - if (src_ip.s_addr != nc_ip.s_addr && !is_broadcast(nc_ip)) + if (src_ip.s_addr != nc_settings.ip.s_addr && + !nc_is_broadcast(nc_settings.ip)) return 0; /* not from our client */ debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); @@ -171,75 +128,17 @@ int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, return 1; } -static void nc_send_packet(const char *buf, int len) +static int nc_stdio_start(struct stdio_dev *dev) { - struct udevice *eth; - int inited = 0; - uchar *pkt; - uchar *ether; - struct in_addr ip; - - debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf); - - eth = eth_get_dev(); - if (eth == NULL) - return; + nc_settings.out_port = 6666; + nc_settings.in_port = nc_settings.out_port; - if (!memcmp(nc_ether, net_null_ethaddr, 6)) { - if (eth_is_active(eth)) - return; /* inside net loop */ - output_packet = buf; - output_packet_len = len; - input_recursion = 1; - net_loop(NETCONS); /* wait for arp reply and send packet */ - input_recursion = 0; - output_packet_len = 0; - return; - } - - if (!eth_is_active(eth)) { - if (eth_is_on_demand_init()) { - if (eth_init() < 0) - return; - eth_set_last_protocol(NETCONS); - } else { - eth_init_state_only(); - } - - inited = 1; - } - pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE; - memcpy(pkt, buf, len); - ether = nc_ether; - ip = nc_ip; - net_send_udp_packet(ether, ip, nc_out_port, nc_in_port, len); - - if (inited) { - if (eth_is_on_demand_init()) - eth_halt(); - else - eth_halt_state_only(); - } + return nc_transport_start(); } -static int nc_stdio_start(struct stdio_dev *dev) +static int nc_stdio_stop(struct stdio_dev *dev) { - int retval; - - nc_out_port = 6666; /* default port */ - nc_in_port = nc_out_port; - - retval = refresh_settings_from_env(); - if (retval != 0) - return retval; - - /* - * Initialize the static IP settings and buffer pointers - * incase we call net_send_udp_packet before net_loop - */ - net_init(); - - return 0; + return nc_transport_stop(); } static void nc_stdio_putc(struct stdio_dev *dev, char c) @@ -248,7 +147,7 @@ static void nc_stdio_putc(struct stdio_dev *dev, char c) return; output_recursion = 1; - nc_send_packet(&c, 1); + nc_transport_send(&c, 1); output_recursion = 0; } @@ -264,7 +163,7 @@ static void nc_stdio_puts(struct stdio_dev *dev, const char *s) len = strlen(s); while (len) { int send_len = min(len, (int)sizeof(input_buffer)); - nc_send_packet(s, send_len); + nc_transport_send(s, send_len); len -= send_len; s += send_len; } @@ -278,9 +177,8 @@ static int nc_stdio_getc(struct stdio_dev *dev) input_recursion = 1; - net_timeout = 0; /* no timeout */ while (!input_size) - net_loop(NETCONS); + nc_transport_poll(true); input_recursion = 0; @@ -295,23 +193,14 @@ static int nc_stdio_getc(struct stdio_dev *dev) static int nc_stdio_tstc(struct stdio_dev *dev) { - struct udevice *eth; - if (input_recursion) return 0; if (input_size) return 1; - eth = eth_get_dev(); - if (eth_is_active(eth)) - return 0; /* inside net loop */ - input_recursion = 1; - - net_timeout = 1; - net_loop(NETCONS); /* kind of poll */ - + nc_transport_poll(false); input_recursion = 0; return input_size != 0; @@ -327,6 +216,7 @@ int drv_nc_init(void) strcpy(dev.name, "nc"); dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; dev.start = nc_stdio_start; + dev.stop = nc_stdio_stop; dev.putc = nc_stdio_putc; dev.puts = nc_stdio_puts; dev.getc = nc_stdio_getc; diff --git a/drivers/net/netconsole.h b/drivers/net/netconsole.h new file mode 100644 index 00000000000..b2c3ecee6dd --- /dev/null +++ b/drivers/net/netconsole.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __NETCONSOLE_INTERNAL_H +#define __NETCONSOLE_INTERNAL_H + +#include +#include + +struct nc_settings { + struct in_addr ip; + short out_port; + short in_port; +}; + +extern struct nc_settings nc_settings; + +bool nc_has_input(void); +bool nc_is_broadcast(struct in_addr ip); +int nc_refresh_settings_from_env(void); +int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned int dest_port, + unsigned int src_port, unsigned int len); +void nc_set_input_recursion(bool enable); + +int nc_transport_start(void); +int nc_transport_stop(void); +void nc_transport_send(const char *buf, int len); +void nc_transport_poll(bool block); + +#endif /* __NETCONSOLE_INTERNAL_H */ From patchwork Tue Sep 1 17:08:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296151 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=kiLK46zR; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=UHvxdeCZ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC5r25smz1xyG for ; Wed, 02 Sep 2026 03:09:52 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 7C66780E36; Tue, 1 Sep 2026 17:09:48 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id EINugvksiUjR; Tue, 1 Sep 2026 17:09:46 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282586; bh=pjjgIwv4JDCpmWnG+Zstb/CqP097qj4rZjjTVs3qhaw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=kiLK46zRg1PYKNVTyuHHh1B7FkulrJo6VJ/fY+E05MLFEQtAzEeNGorvmW91rkSBS AtTdpMisnBV7iXVAZdzExpemf/EPEJORNP6ZyEk4RSgay7BG43knwVrjVIqdrgDdo0 xBdOjswI0lgI1QnKfemqYHgABGBhPdkcbtl+t8kuEOK2GCs0vCw2Js/uX5Yjo46WgR k54qD2F/QhJ/RJ0V6x9lCI15RJvO3pVZ8T00u5F5bmtR9kkmQCm/WdTBIA481Ppbw5 4InM4tSgKKP8CHo/w5DCmhB1wxzU92AbGN65efBIXXzK3DfzPtwL14dYhvvb5K5M3I Gbs4yX0FveABg== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp1.osuosl.org (Postfix) with ESMTP id B351F80E2C; Tue, 1 Sep 2026 17:09:46 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists1.osuosl.org (Postfix) with ESMTP id B4C942FE for ; Tue, 1 Sep 2026 17:09:44 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id A69784073C for ; Tue, 1 Sep 2026 17:09:44 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id yaQDnSO-M9w0 for ; Tue, 1 Sep 2026 17:09:44 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::332; helo=mail-ot1-x332.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp4.osuosl.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=UHvxdeCZ Received: from mail-ot1-x332.google.com (mail-ot1-x332.google.com [IPv6:2607:f8b0:4864:20::332]) by smtp4.osuosl.org (Postfix) with ESMTPS id D33CC40718 for ; Tue, 1 Sep 2026 17:09:43 +0000 (UTC) Received: by mail-ot1-x332.google.com with SMTP id 46e09a7af769-7f6617c7536so1604955a34.1 for ; Tue, 01 Sep 2026 10:09:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282582; x=1788887382; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=pjjgIwv4JDCpmWnG+Zstb/CqP097qj4rZjjTVs3qhaw=; b=UHvxdeCZIqxtkEXPRWauT58rEKdlyeHiBBaIjMbpmhZcrXUO2Ychc9rpqVK6syfCde Ye1I1OfzMbUb/BbFfhqbR82ZzGsGt9DZGZig/qrMdL1yXwNKcFWjjTYDqvdLeIItWAZq u1noiXQZhHhNwUOZ81rLdNpfVi+C6h7Z94ICKFD8Zd3Z72kvSecgLjxajbcnGGxEdO4U sinH7phSCM1Hy3hFJ8Ry7I5rDkOFcyYYpZkmWKB0NLxJChHGXEI0DYn3h906D5uHxWB8 4dnPJ8vCPl6zBdsQahIeDxdm3JeWe2x3JjDD4dfvGnc8ctl22Xr5ChgiDWQk6H2ywMuv VS4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282582; x=1788887382; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=pjjgIwv4JDCpmWnG+Zstb/CqP097qj4rZjjTVs3qhaw=; b=No7JaahcuV53uHGS5TV4iLwGsSq0u1Mg0lYYPYKGHDniwEoHIuvubnX2pkYBo89eWY GNjMaxdUhJ8KAe916VA6yo+sRViNg30dbY0aZlmTEQ/6CSVqeCKS83h2X5IZ1uGNUx9e qsVeEqXd3gpj1G3HyXse3J53HImqMr7DtgwtnAJVBjWfayw3uAgPBIOI8DX+a0uHvEPU kWvALmK2lFgtdNUFSuyjEWw+tkb/L6MFY8UBpHR5c44PKxl0sndnk0GLkimooqRMa9Gi 90j9SPPRCrvjFH0NwgtI1TNTm1K2GzZnYTooFriXV7CAF/r5ofsE5O+juGQgjAfLW+Hs dp5Q== X-Gm-Message-State: AFuF++nVbC4JoU8iKtZ48hpIfZYHkX2mY4Gdapa75ro8ZLnXwIGzRS1K pZqNPIJFXD3HsDPw/g4Kj1huIkPovFJWuQzEh4RXprx45/6mrstuVOEC X-Gm-Gg: AR+sD13/VH0fxUNWebId8k+kxd0+ymMS5yilZlhdLfNBTdbQhWSzGlkqDPmt8BOFtMQ LWJz3VyrH3IzNeLPj4usRQGGoZXvG/bZid5msKcbY/IfXWYouHWOwzqk1hVBc8aHTlrQoUbggZK N8GRNxhWbZFypetPjoyCMmEN2oqBnGisbLYAIyuiP18uofLKpptonYe6PSHKG4h9S8hIP7c57/X 55xjgszmaXoSWDqs/lw2lXO+MmORQU/Vd2LAj/LdXevYFs3CGJVzg0TkvfLf5uJADbSdzC/qUp0 +4bq7PwW2pWBcWAtw8Ubeisbd1FPF58Cx+KPUbX+krCd8Lc+pAveJtI98K7SefR3CnQSdo5slNB V8ii0X1xkyuWyFQQu3QN8Go6mLfA//8tgd1x0OUh1l1i44Vo9G4HC6blgbIu13otih4W7yBoZCT wPdj+XdcuZW+GSJx/B3IFb1bBSs/oyQVHl6mRwNI5Af6DH9bOygo/zEXxXwqcF6z+5fog6uWajj KGig2GsT5CVj94TZNORKyShDXrubkxXkP55hTb9n11nO3SLkf3NoV1GpWIoVM49fFuuiGbYiUAU mLlfz/LnswTbJywS9wStRfvulpI8y+4PBGeL/psn6zEKXTiQiSOEtNz6AUESE2GKVeJvt1lruP+ 5CjySKCk7KJprYnnLQPc= X-Received: by 2002:a05:6830:828c:b0:7f4:d68b:dff6 with SMTP id 46e09a7af769-7f4f22fb1efmr38713831a34.7.1788282582227; Tue, 01 Sep 2026 10:09:42 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:41 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:08:57 -0600 Subject: [PATCH v2 03/10] net: netconsole: use unsigned port numbers MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-3-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org UDP ports use the full unsigned 16-bit range. Storing netconsole ports in signed shorts makes values above 32767 negative and prevents them from matching the unsigned destination port on receive. Store both ports as u16. Signed-off-by: James Hilliard --- drivers/net/netconsole.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/netconsole.h b/drivers/net/netconsole.h index b2c3ecee6dd..11c2d1e0f48 100644 --- a/drivers/net/netconsole.h +++ b/drivers/net/netconsole.h @@ -8,8 +8,8 @@ struct nc_settings { struct in_addr ip; - short out_port; - short in_port; + u16 out_port; + u16 in_port; }; extern struct nc_settings nc_settings; From patchwork Tue Sep 1 17:08:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296153 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=00Rw1Ue5; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=IdktXeQy; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC5s6fT6z1xwZ for ; Wed, 02 Sep 2026 03:09:53 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 59FE240743; Tue, 1 Sep 2026 17:09:52 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id X2RUbhv8ViBW; Tue, 1 Sep 2026 17:09:51 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282591; bh=GQW0pwqeN1QS31ge4KITeUwSENzJgroI67hI1Ww1hbY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=00Rw1Ue5TwzuMArBiFnan6YQ5Bgc/uBoIQWZNWV+VVGY+enYl0wUKtch8KrHZsKQI vGLGpmISNjIfOhTF94onxfzXf2Z5Cuc2vu30uIRqYITgDzjlL64GtJUnTFNQpPnGdA 0kMmulqSw/nxO1lBUHxH61vOGDkfwsXOOvysW1cLMUS8W70PWEVM4maTmXoBc05yig abdAaWvIl4RRByVjYAD2KbArCUGLa+qQH3T5vLmHeZD9mwcO3iGiR3MuPg4VHJY3AU 2kY7lt7xp9hHhpQ8UNtXyEvmeKcUSfbIhZfwbV9PTWZrtu5gLbobC78u/aHiMVxfjG W3shbYYI0x5Gw== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp4.osuosl.org (Postfix) with ESMTP id D555E40791; Tue, 1 Sep 2026 17:09:50 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists1.osuosl.org (Postfix) with ESMTP id 2AEC72FE for ; Tue, 1 Sep 2026 17:09:46 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 11765606F6 for ; Tue, 1 Sep 2026 17:09:46 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id kwSCKW0SEGrD for ; Tue, 1 Sep 2026 17:09:45 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::331; helo=mail-ot1-x331.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp3.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=IdktXeQy Received: from mail-ot1-x331.google.com (mail-ot1-x331.google.com [IPv6:2607:f8b0:4864:20::331]) by smtp3.osuosl.org (Postfix) with ESMTPS id 1FA4160633 for ; Tue, 1 Sep 2026 17:09:44 +0000 (UTC) Received: by mail-ot1-x331.google.com with SMTP id 46e09a7af769-7f4f3683fbcso91133a34.0 for ; Tue, 01 Sep 2026 10:09:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282584; x=1788887384; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=GQW0pwqeN1QS31ge4KITeUwSENzJgroI67hI1Ww1hbY=; b=IdktXeQyu9qb3dietw1H+g1Y0uUQXykftACrksWtvBJlrAhjYyBl48ELKSZ0Tpb0vf VgvF4Ow672ixboqwDnIWPtJql0ZLXiz4s/cDJywY4ZHaoWDtWznXbAKSub6+r0yS/10w IgsPxnujQUrrFiJrAsBTwsDlPkz4mnSKOhtTsvEEO0TeRJV/Oa6qIdIt3OJAHheCvvkl X99t8x8O07Dh5u1L2YseBex28KJYcj1dKio91FZsgujBr7AFfJtPS9zVWCUpL/511vxT 5SAKGZtC63Vspw8IH5eMDfZmQXu2X1lGp4AHreQ2F7j+KWKIGY4VvPDdYz09rdIURMJT 2Iow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282584; x=1788887384; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=GQW0pwqeN1QS31ge4KITeUwSENzJgroI67hI1Ww1hbY=; b=f0KEqHvoi2zSR7RpKbz7fIYNi1Y59DDXo5931ViqxVu0BFlsBDKfI4uxvNc8dPJAlH 4Ln9igihhEJ3F+pd2wlNRoF4LmEKgSnAPe4WEo4yWWe+fwoRva89yLodmqo8sm0YKV3N VcU7G1IJ9+nkg4H0WQmvf6mHB1Nyy/A1HXIPuqjXrLuBOQh0j0sgqVCSH5LgPVoVPWDH 9WhajJpLP9XqkS9HUvs0D6lrcL2f2KPBt12M0lyy9etr+/CVo4FkcKwsFvMZVxaYUvHR wbBqGAsh5hZYjmXFW/0md4ZrFjPTAAYPNBbAWECgeV0ipIWincjzclO7297OypfsBqCC 8Mqw== X-Gm-Message-State: AFuF++lZ6wrsctvwXWF2AyIyTKg6ROo5YvMB6JW6RYh06UXBC4LHlKLC kRk9U0DqW/uGfo0Ue0n89QFPd5CbM2P5gU87RXOUFPCPNFvSwwN8EE9i X-Gm-Gg: AR+sD11flXWWn08dBfZ+Z+IV3GhpfuuVH/wiWn2ckXCJR5pQkmzBb/PHAE7fkKWkaI8 p6FDZxW1qfx83IzSvqMRqKT0yq62lpVvSPf4gkY4XIIPIywjZIUbacUqH1TZAiFzFpZbhlHrRBL hAisu7eY8ND0fXaOuC+AIdbZV5cafQIfJRt+4St1zXXjnFaje1RpkL0pq4NlkoxqXDN41f0znp/ /2fkzpy3wXaqfOh1IlG0Wfw4eqh/HVtle6Ncccu1DOHyD5FiGvpkDx4cuBLcHbzbNiT+MXR1HxI RA+r9+QXEmOgp7+JTP+/2SGMKnB3gue77JQVxStJs0Q+SrAPQoZ+SprSeUQ9CmlQW2BMV6Zdr1V b5lWA94Fo2Uop4wr9Jqv7VP5P9s7ZZRlnXZ3btl50S3eGrDrJ9KgcNJ1eEDJjdMzOviPCEIuix6 +0ebwtUOC+6SK8lLYpjAOUkFIgABGiwmfomxW9fj9uR1I3oR3ZMUA2UZA1H6HlFnC5QIe0g5ZKM QwG9dEzD4Ag3DRn2QFDG8cacK0MkBQE7H2eY8pHXJAK7xiEEBQlIrNphSHPH92jHE32+xil8MAb +z8dR1EwAUdFY5onj001lufK/1NpOSDlTc/I8eeIuxaKdh3WMi2H6dylvVoeSs+7yMbC/72jc35 Wi7KjpUFc15QY/Am1aNIX X-Received: by 2002:a05:6830:84d4:20b0:7e9:f6b7:7752 with SMTP id 46e09a7af769-7f68f7ad81cmr3868021a34.12.1788282583534; Tue, 01 Sep 2026 10:09:43 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:42 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:08:58 -0600 Subject: [PATCH v2 04/10] net: netconsole: cache environment settings MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-4-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org nc_refresh_settings_from_env() compares the current environment ID with a cached value, but never updates the cache. It consequently reparses the environment for every packet. Build a complete settings value from the defaults whenever the environment changes, publish it after successful parsing and record the new ID. Keeping the defaults with the cached settings also avoids resetting configured ports when another stdio stream starts. Signed-off-by: James Hilliard --- drivers/net/netconsole.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 305a6cf12c6..63b92e12bf4 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -16,12 +16,18 @@ #define CFG_NETCONSOLE_BUFFER_SIZE 512 #endif +#define NC_DEFAULT_PORT 6666 + static char input_buffer[CFG_NETCONSOLE_BUFFER_SIZE]; static int input_size; /* char count in input buffer */ static int input_offset; /* offset to valid chars in input buffer */ static int input_recursion; static int output_recursion; -struct nc_settings nc_settings; +struct nc_settings nc_settings = { + .ip.s_addr = ~0, + .out_port = NC_DEFAULT_PORT, + .in_port = NC_DEFAULT_PORT, +}; bool nc_is_broadcast(struct in_addr ip) { @@ -46,8 +52,13 @@ bool nc_is_broadcast(struct in_addr ip) int nc_refresh_settings_from_env(void) { + struct nc_settings settings = { + .ip.s_addr = ~0, + .out_port = NC_DEFAULT_PORT, + .in_port = NC_DEFAULT_PORT, + }; const char *p; - static int env_changed_id; + static int env_changed_id = -1; int env_id = env_get_id(); /* update only when the environment has changed */ @@ -55,25 +66,25 @@ int nc_refresh_settings_from_env(void) char *tmp = env_get("ncip"); if (tmp) { - nc_settings.ip = string_to_ip(tmp); - if (!nc_settings.ip.s_addr) + settings.ip = string_to_ip(tmp); + if (!settings.ip.s_addr) return -1; /* ncip is 0.0.0.0 */ p = strchr(tmp, ':'); if (p != NULL) { - nc_settings.out_port = dectoul(p + 1, NULL); - nc_settings.in_port = nc_settings.out_port; + settings.out_port = dectoul(p + 1, NULL); + settings.in_port = settings.out_port; } - } else { - nc_settings.ip.s_addr = ~0; } p = env_get("ncoutport"); if (p != NULL) - nc_settings.out_port = dectoul(p, NULL); + settings.out_port = dectoul(p, NULL); p = env_get("ncinport"); if (p != NULL) - nc_settings.in_port = dectoul(p, NULL); + settings.in_port = dectoul(p, NULL); + nc_settings = settings; + env_changed_id = env_id; return 1; } @@ -130,9 +141,6 @@ int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, static int nc_stdio_start(struct stdio_dev *dev) { - nc_settings.out_port = 6666; - nc_settings.in_port = nc_settings.out_port; - return nc_transport_start(); } From patchwork Tue Sep 1 17:08:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296155 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=LNSjXNu9; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=Te/vID5Y; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC5x4XB1z1xwZ for ; Wed, 02 Sep 2026 03:09:57 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 8A7A280E64; Tue, 1 Sep 2026 17:09:55 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id tHRnH0-XcbxK; Tue, 1 Sep 2026 17:09:52 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282592; bh=8E2mRdmavLoQo26QKJCcQwyIQOHXXd3cmOULwif2dVY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=LNSjXNu9Vc5hTudhNxPYKJrpGIJprcDWAkr+Boysrpgb53gaNPmXxr0RZEIpRz0LE hm3uDbz+cGW4A0RnlAjM3lq6ddBClUdolwSRsNTSOxZH9ZiLPl95AXJKDyOdcVRQr5 bwZsvSj045ExAy2Z32DSGSZeSWD4CZXVTg+klxDpzj8E5Yjr3hZoQSXnPH0KaIGXje /CbMqLcWbTvn3cp8XOprmyIW6mPP/8GOa/Vk1C8GI4PUrFWRsU+Y2/tlSfZ39DqjCi 05hIhI6SYbFqRd0HsVr03imd2+Z4KellHQ5DZwPW247vr5p6eULzchLubsKd4BfJ88 Xtv0nGSmUwP0w== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp1.osuosl.org (Postfix) with ESMTP id 3437680E4B; Tue, 1 Sep 2026 17:09:52 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists1.osuosl.org (Postfix) with ESMTP id 885452FD for ; Tue, 1 Sep 2026 17:09:47 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 7717780E2D for ; Tue, 1 Sep 2026 17:09:47 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id r6sUMCmue-OD for ; Tue, 1 Sep 2026 17:09:46 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::32c; helo=mail-ot1-x32c.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp1.osuosl.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=Te/vID5Y Received: from mail-ot1-x32c.google.com (mail-ot1-x32c.google.com [IPv6:2607:f8b0:4864:20::32c]) by smtp1.osuosl.org (Postfix) with ESMTPS id AF4E080DDE for ; Tue, 1 Sep 2026 17:09:46 +0000 (UTC) Received: by mail-ot1-x32c.google.com with SMTP id 46e09a7af769-7f4f3683fbcso91155a34.0 for ; Tue, 01 Sep 2026 10:09:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282585; x=1788887385; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=8E2mRdmavLoQo26QKJCcQwyIQOHXXd3cmOULwif2dVY=; b=Te/vID5YEwrfmO2HBYvLPLzBgzvGLv7hTsrQXRLzWmDjpJRHqxcrX+GBV+CsgDlW65 uYW6AiDXYjjZZ3blwRgcwqsvj2heiXZ1Iy+rBSOyFMA+dUh/2jARnD0GDdTsM4gThNqw znzLkYkMTprknwUTAh8MGFlAFp6ts/PBwFi4wFINFG2fAGOyaWrT7h5l2VBWyLXrfobr lqK2czsWXozdVJaEsXvJKT0rhav0UFejo9+bSgN4b+iYDqML/K2SvYwE0WAJisfnhR22 F8Q33LXVXoNa+gZuIWt9nrzfcUIZntFiKToi3Ohdl57YLdcPGkm3qfIKrFHsvVnBhhb8 N0CQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282585; x=1788887385; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=8E2mRdmavLoQo26QKJCcQwyIQOHXXd3cmOULwif2dVY=; b=Y/Gc9p23WevZLAIK6KmL1GXs6jcu8bvCNt0ET1qCNZGAIT9XCcn5trvOjkec4CgHhb 4ttAEELCSLrkSi+JHA7vKCDK7YrS0GqCqneYt1zQJk+5rCCpXWpD3i5DqG24Sxlf5UQN 4W/22Ld3s1VjuBFz0NxHYf/8EFZ9UBNJ0CY5y/1WACIdy93jMW+CIM6DAJzwTEhNb3wV tN3lT+xal7AJxfXzNlZK0Z50ejwdgpdnHHh/LrzRj34egEknSX+YTAos4vY0XZwEk/SE BMny1XLrN/Ed9fFsgTO6REThQ083l6tsuGmeZF7qqJ0YkzHi5dCLVyyQVWF1f2vicR5P 5vvg== X-Gm-Message-State: AFuF++k8ORbg+3qJkIsK/QHTKkoBwVpJyY0Wz7yQ4K6E+8egZBAYWjU2 IlTe0pTl68cou/gr2ZK8f6vENY0rsVX9TbgOuAToKQv4edGbEuMpPkLW X-Gm-Gg: AR+sD11BruS742ftEkNlMUAhR/c4EcMSihAXmuHcenne4NhLVrMVBv0Cr1twrv+6/e2 fEYCokHJCeriGp97Ns1vTLUlFYVW7b1lTbyEhdz6wJk9KnpXRCCjtyGgGitt/wq7pAei0URU1Dw efXSqivNMsCqh0efXJI7yeHh5LOaoKjJYpbk1O4sTCIn145yuAiDN96eM9oa279+mm22ZMvB22r FO9T05rQ9FPIubvUC00o0fEKW5d/ejlv8bgiAknGqAGzHd+fTzHTwpPu2FIjD9a6YcL6cgZAFot BajY9NtWn0HWo5sSlzmoIbr1W+UUnnibKQ4xRAkD0BX8KKTWi+j3oWvvvhXHwuHue4O8UnUt+pp NORHERs9QCzh6zn5a3zcCtSdcwN/eEQd20OerPoYm9Rs4r2OhG/cu7NPEPJzBbu71SOk7r5b/FU FSOQuQloGezxLiqT/8Sumr2IoXbTscUKg9xQ85J/oskH9MlusuZ6rfPfWVzwCpga6cMmLRkORog n9ROKUfIC/Rp7DL7fM7eQz/EssgfGO6V9KN0krEyp0ZmvJidG6/SLZn0CNDXu50u+0iR7WFen8I 3s5pJoE4WZyHTkvWqQUv5YdIMUrNxxLslUtDyEDF8u8cBhP+4xsyU0zHBBS2/cblUY+g9pNJo+B qNRkjPHCWKDQeE5mj130= X-Received: by 2002:a05:6830:3c81:b0:7e9:dc11:5920 with SMTP id 46e09a7af769-7f68f756e5amr6032066a34.8.1788282584562; Tue, 01 Sep 2026 10:09:44 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:44 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:08:59 -0600 Subject: [PATCH v2 05/10] net: lwip: allow DNS callbacks to be canceled MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-5-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org A caller can stop waiting for a DNS result while the resolver keeps the request and callback. If another lwIP client continues polling, that callback can later use state which its owner has already released. Add dns_cancel() to remove matching callbacks without canceling a query shared by other callers. Use it when stopping SNTP so a pending name lookup cannot outlive the client. Signed-off-by: James Hilliard --- lib/lwip/lwip/src/apps/sntp/sntp.c | 3 +++ lib/lwip/lwip/src/core/dns.c | 26 ++++++++++++++++++++++++++ lib/lwip/lwip/src/include/lwip/dns.h | 1 + 3 files changed, 30 insertions(+) diff --git a/lib/lwip/lwip/src/apps/sntp/sntp.c b/lib/lwip/lwip/src/apps/sntp/sntp.c index 0e7f36520fa..a37699f65b7 100644 --- a/lib/lwip/lwip/src/apps/sntp/sntp.c +++ b/lib/lwip/lwip/src/apps/sntp/sntp.c @@ -711,6 +711,9 @@ void sntp_stop(void) { LWIP_ASSERT_CORE_LOCKED(); +#if SNTP_SERVER_DNS + dns_cancel(sntp_dns_found, NULL); +#endif if (sntp_pcb != NULL) { #if SNTP_MONITOR_SERVER_REACHABILITY u8_t i; diff --git a/lib/lwip/lwip/src/core/dns.c b/lib/lwip/lwip/src/core/dns.c index 6540f143bac..5762647ee27 100644 --- a/lib/lwip/lwip/src/core/dns.c +++ b/lib/lwip/lwip/src/core/dns.c @@ -387,6 +387,32 @@ dns_getserver(u8_t numdns) } } +/** + * @ingroup dns + * Cancel pending callbacks registered by dns_gethostbyname(). + * + * DNS queries shared with other callers continue so their result can still be + * cached and delivered. Only callbacks matching both arguments are removed. + * + * @param found callback passed to dns_gethostbyname() + * @param callback_arg callback argument passed to dns_gethostbyname() + */ +void +dns_cancel(dns_found_callback found, void *callback_arg) +{ + u8_t i; + + LWIP_ASSERT_CORE_LOCKED(); + + for (i = 0; i < DNS_MAX_REQUESTS; i++) { + if ((dns_requests[i].found == found) && + (dns_requests[i].arg == callback_arg)) { + dns_requests[i].found = NULL; + dns_requests[i].arg = NULL; + } + } +} + /** * The DNS resolver client timer - handle retries and timeouts and should * be called every DNS_TMR_INTERVAL milliseconds (every second by default). diff --git a/lib/lwip/lwip/src/include/lwip/dns.h b/lib/lwip/lwip/src/include/lwip/dns.h index 091341544f3..82579f09f35 100644 --- a/lib/lwip/lwip/src/include/lwip/dns.h +++ b/lib/lwip/lwip/src/include/lwip/dns.h @@ -111,6 +111,7 @@ err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg, u8_t dns_addrtype); +void dns_cancel(dns_found_callback found, void *callback_arg); #if DNS_LOCAL_HOSTLIST From patchwork Tue Sep 1 17:09:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296156 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=arJ1Jazt; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=jgOJUnhm; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC5z2rxdz1xwZ for ; Wed, 02 Sep 2026 03:09:59 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 094264077E; Tue, 1 Sep 2026 17:09:58 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id RNWjF6ilOBPD; Tue, 1 Sep 2026 17:09:57 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282597; bh=GG91exDkbJxW3sE81/CLe3y18QtiSmy5LYzVyP8TeHU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=arJ1JaztfRDI5HBpnBE9gShRE4jRHVP3OvFnZNxGE+Fk9Jd1KcKTAbuD3dl3q0RjV 1gEEu3fCTkjArhoGT6gzd9vFrY0S/KVOwahD+0C4wrh3Z+WqZbEDgSgBio7+rPyijx PgFC1wCbtPUdjdEcq0Z9ziqKmbM6dzBI4Alkn2c+UENA2EMOppARsFnLdqdF7Oomi/ wsu5+rZGwpBIBVw8aJ6THCfPHEgRrn7/tcxdLr8Gu66sMqn/KKXRFRKWdzWoQE2Ngi OKAkSsDEjd7rO2k3RZyJcpOdqh2bZswbto+/Lft+7v8VUakTOmy6m5LfAByBhcoey8 cqm2LD1QXewfw== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp4.osuosl.org (Postfix) with ESMTP id 49FE140795; Tue, 1 Sep 2026 17:09:57 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists1.osuosl.org (Postfix) with ESMTP id B0BB5279 for ; Tue, 1 Sep 2026 17:09:50 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 9690740791 for ; Tue, 1 Sep 2026 17:09:50 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id jaTKbF8oABpj for ; Tue, 1 Sep 2026 17:09:49 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::334; helo=mail-ot1-x334.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp4.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=jgOJUnhm Received: from mail-ot1-x334.google.com (mail-ot1-x334.google.com [IPv6:2607:f8b0:4864:20::334]) by smtp4.osuosl.org (Postfix) with ESMTPS id 9D6D740743 for ; Tue, 1 Sep 2026 17:09:48 +0000 (UTC) Received: by mail-ot1-x334.google.com with SMTP id 46e09a7af769-7f6617c7536so1605031a34.1 for ; Tue, 01 Sep 2026 10:09:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282587; x=1788887387; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=GG91exDkbJxW3sE81/CLe3y18QtiSmy5LYzVyP8TeHU=; b=jgOJUnhmc6hKDMMIX25G/Tn4UcW5yT9fZ5EJBz2lN1bT56P2sGHQ1FpjrrL5G92n7z AXl5e/Db0eDjAXxSkCQyfbv8b+f6ULpIGKHtZDUNGvJwCl67pUVGzzgdiywFqn4s4q64 FnogLROUpOq4QW2bPAaj+3h5NAqVN8ibSRsdQp6GuCwnvriEVrZ0rUD41guI7gTfj2df zCIQIPs0cu5BZPdBqKvAjL3RlwtY/ENjvvi1GuTscdKPWQzPS7X32vyg8FMxKyMwmPxK Ce7M9NvqxsACimMovKC8pfhpReIxgpAwZ22pqLOnGEMYK7lglbjlEUf0b6FNzesEU9zA 7EXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282587; x=1788887387; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=GG91exDkbJxW3sE81/CLe3y18QtiSmy5LYzVyP8TeHU=; b=AT2YHaMfESXSi75zLinLsH8g3osK+42Dnbxq0EEXrWBcV3m0xPRoiNLKkFg9akjidX 4x0UwYRsthS4hnNI3djl6vui3l/hNPsf4uDiGFWZiaNmFtiSg9EdQIhBnRAuTXa/ZNDx s2VUxaBe3vS0YM2BItsNIwANpiefQidW745178sKcsSPGl4t9IGTHHhsombCdLYZKMJD JEP6xZWzDCfIMD9aZFzaBG8dLsn0WQ+CA8QyjchXASuwjb5E0xrvOCPl+zTZXYcQEqyx p+2RxfAVN52RYGJW3vCFLvCa126jCrrM4Mhx06bxhAzOuoLM0AnYN6HYVd7yDQUCJ8Of 92Ew== X-Gm-Message-State: AFuF++mdGPIvUpdVSWmowU1YYukUwGBmYmPMhdYcTHHB8+oB0whVCjte lPf4n3l8T3l6Eetdud+e0AEAW5weA3dOsaUXqQbiivzJbDYGJn+v8xum X-Gm-Gg: AR+sD11c3JjjqDS4VYDknjsX2RWUtrv8dZ9s3irkbQYMaQPIYY7ei9QCwum+n6fz7f6 f//niN72XgdXtdXplINCWFi6ArdzXSnGIipXQeFGA8otsBlr9xZfahuOqqQLpXUNTWM663F4yVP YgM6Z8rAzDhrVW57zigNKwoKgyTmYto5FtLSUWUo53uywcaKtNphuZIOx89H0F/VZlO7QM5x2G+ Dw9ehhqjoDExGuEjPeYoqUfOlZ1TH1WaIUDtcDStSPQa77l7uxzyJ0FHEmG7BlSgwinbFCCwiBm fzy3yk3T399Y02M+GnLOseh8baEbIzKGisDUZAcNfOV8Q1exB7KcpyYQfFHQonNrieNcNGus+Zs pqTjS7Ryeyo0MWTItsYGgz6kGYKrb5vw8qjt+YD/t3jGljIZ79FJD5TjlTQmkqIYhFJYVvPK8fh AEQWpi/vXXcYsHglQ7Kyx/MnRm9wBkNXymkI6i57w4biCMl/DohgZ1+2OBt0SXx2t0+GM4Pw99X W+eJCHDjX++rzwHZxqLCo+p+/VOZXbwtD4M5qn6XhxdmTTRfjUoCyLeFuoCDHQ8qAUzefu4wYm5 IM0dj5x+AKkA2l+1kWcGsa5xtsAFzuuESycb3Z1KDx5lHgFN58wrCEsm5v2HYxJIzrWOBu3T44/ 3EPpdi+XpzgQrA9b6D5o= X-Received: by 2002:a05:6830:3745:b0:7e9:e488:3bce with SMTP id 46e09a7af769-7f4f22bd9c3mr37988985a34.6.1788282585777; Tue, 01 Sep 2026 10:09:45 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:45 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:09:00 -0600 Subject: [PATCH v2 06/10] net: lwip: add an HTTP client abort operation MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-6-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org The HTTP client has no public way to cancel a request. Returning from wget while DNS or TCP work remains pending can therefore leave callbacks referencing its released command state. Track pending DNS resolution and add httpc_abort(). The operation removes a pending DNS callback, detaches the HTTP callbacks and immediately aborts the altcp connection. Report a local abort through the normal result callback. Signed-off-by: James Hilliard --- lib/lwip/lwip/src/apps/http/http_client.c | 71 ++++++++++++++++++++--- lib/lwip/lwip/src/include/lwip/apps/http_client.h | 1 + 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/lib/lwip/lwip/src/apps/http/http_client.c b/lib/lwip/lwip/src/apps/http/http_client.c index 1973e79e723..2bc2a0db97e 100644 --- a/lib/lwip/lwip/src/apps/http/http_client.c +++ b/lib/lwip/lwip/src/apps/http/http_client.c @@ -146,15 +146,23 @@ typedef struct _httpc_state u32_t rx_content_len; u32_t hdr_content_len; httpc_parse_state_t parse_state; +#if LWIP_DNS + u8_t dns_pending; +#endif #if HTTPC_DEBUG_REQUEST char* server_name; char* uri; #endif } httpc_state_t; -/** Free http client state and deallocate all resources within */ -static err_t -httpc_free_state(httpc_state_t* req) +#if LWIP_DNS +static void httpc_dns_found(const char* hostname, const ip_addr_t *ipaddr, + void *arg); +#endif + +/** Free http client state and detach its connection callbacks */ +static struct altcp_pcb * +httpc_detach_state(httpc_state_t* req) { struct altcp_pcb* tpcb; @@ -168,16 +176,26 @@ httpc_free_state(httpc_state_t* req) } tpcb = req->pcb; - mem_free(req); - req = NULL; - if (tpcb != NULL) { - err_t r; altcp_arg(tpcb, NULL); altcp_recv(tpcb, NULL); altcp_err(tpcb, NULL); altcp_poll(tpcb, NULL, 0); altcp_sent(tpcb, NULL); + } + mem_free(req); + return tpcb; +} + +/** Free http client state and deallocate all resources within */ +static err_t +httpc_free_state(httpc_state_t* req) +{ + struct altcp_pcb* tpcb; + + tpcb = httpc_detach_state(req); + if (tpcb != NULL) { + err_t r; r = altcp_close(tpcb); if (r != ERR_OK) { altcp_abort(tpcb); @@ -202,6 +220,38 @@ httpc_close(httpc_state_t* req, httpc_result_t result, u32_t server_response, er return ERR_OK; } +/** Abort an HTTP client request. */ +err_t +httpc_abort(httpc_state_t *req) +{ + struct altcp_pcb *tpcb; + + if (req == NULL) { + return ERR_ARG; + } + +#if LWIP_DNS + if (req->dns_pending) { + dns_cancel(httpc_dns_found, req); + req->dns_pending = 0; + } +#endif + + if (req->conn_settings != NULL) { + if (req->conn_settings->result_fn != NULL) { + req->conn_settings->result_fn(req->callback_arg, + HTTPC_RESULT_LOCAL_ABORT, req->rx_content_len, 0, ERR_ABRT); + } + } + + tpcb = httpc_detach_state(req); + if (tpcb != NULL) { + altcp_abort(tpcb); + } + + return ERR_OK; +} + /** Parse http header response line 1 */ static err_t http_parse_response_status(struct pbuf *p, u16_t *http_version, u16_t *http_status, u16_t *http_status_str_offset) @@ -447,6 +497,7 @@ httpc_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg) LWIP_UNUSED_ARG(hostname); + req->dns_pending = 0; if (ipaddr != NULL) { err = httpc_get_internal_addr(req, ipaddr); if (err == ERR_OK) { @@ -479,9 +530,13 @@ httpc_get_internal_dns(httpc_state_t* req, const char* server_name) if (err == ERR_OK) { /* cached or IP-string */ err = httpc_get_internal_addr(req, &req->remote_addr); - } else if (err == ERR_INPROGRESS) { + } +#if LWIP_DNS + else if (err == ERR_INPROGRESS) { + req->dns_pending = 1; return ERR_OK; } +#endif return err; } diff --git a/lib/lwip/lwip/src/include/lwip/apps/http_client.h b/lib/lwip/lwip/src/include/lwip/apps/http_client.h index d39e1bf829a..3f62150dca1 100644 --- a/lib/lwip/lwip/src/include/lwip/apps/http_client.h +++ b/lib/lwip/lwip/src/include/lwip/apps/http_client.h @@ -143,6 +143,7 @@ err_t httpc_get_file(const ip_addr_t* server_addr, u16_t port, const char* uri, altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection); err_t httpc_get_file_dns(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings, altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection); +err_t httpc_abort(httpc_state_t *connection); #if LWIP_HTTPC_HAVE_FILE_IO err_t httpc_get_file_to_disk(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings, From patchwork Tue Sep 1 17:09:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296157 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=l2Z8DBcW; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=T7xzSHi/; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC5z3DDdz1xyG for ; Wed, 02 Sep 2026 03:09:59 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id B88DB80E50; Tue, 1 Sep 2026 17:09:56 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id v8YIJXtaBR3g; Tue, 1 Sep 2026 17:09:55 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282594; bh=VvmlYc4uR60GhmkrwN/xcN5jfUNAxmKzvS90Ij+le74=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=l2Z8DBcWTRCsilbcWiMBK53BA/k8Y8PYtO4KBM+THGc7/hqOUwg2RS4KdfUgNzgEf Rtsy8eXVfxsujjeEJvDhdvdr1+tWM9gdBiyxONgNgaaQ5gbC8cjNnjfNFKYhq1saw1 1z6yQH+VtJp6CcS2jc9n3tB63Azwaht9hYL4Gt1v9IWw5UG58O8AS+52ARXi/UaKHZ fyIlFWC8V7leUDekePCOhzILrdXZN6fEw/HSIk53vhV5v7tEP1jR6Pw9XesMU8LPsz elwFCVKhntKcFplgjtvTRr0e4+TcWjKOd7DquCprw99/7rMPH75MEf+dQvQc7dxOz6 mquNVq3Hge4Yg== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp1.osuosl.org (Postfix) with ESMTP id BD0F680E68; Tue, 1 Sep 2026 17:09:54 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists1.osuosl.org (Postfix) with ESMTP id 6CB992FD for ; Tue, 1 Sep 2026 17:09:50 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 5F38E606F6 for ; Tue, 1 Sep 2026 17:09:50 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id hi3xp-dlyI7o for ; Tue, 1 Sep 2026 17:09:49 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::32e; helo=mail-ot1-x32e.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp3.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=T7xzSHi/ Received: from mail-ot1-x32e.google.com (mail-ot1-x32e.google.com [IPv6:2607:f8b0:4864:20::32e]) by smtp3.osuosl.org (Postfix) with ESMTPS id 88D3060633 for ; Tue, 1 Sep 2026 17:09:48 +0000 (UTC) Received: by mail-ot1-x32e.google.com with SMTP id 46e09a7af769-7f4e6b5bd30so986571a34.0 for ; Tue, 01 Sep 2026 10:09:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282587; x=1788887387; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VvmlYc4uR60GhmkrwN/xcN5jfUNAxmKzvS90Ij+le74=; b=T7xzSHi/RlozCPQgcvvyh9YlwQmfEVaymIOsDyUg+piAjnYfIxVcR88g3av74J0Uzt g4D38I3hjwSOejKcrbjLRk1x6xZFc7wuUo6Q5Cg59fOmdm7jL85GRj8GdZhoVQaerb6R XDt0GP1DVah4is+WHdHUsAJhAdrzcasL0Wv0sis/ep/lcu0gytc5uGqgIKt7it3RVUXS rjnKIU0bk3JQy9083XqUU/pTycdlvoh3ehUw5K9VWORu30uZeHKWz0xO9a6hy+PougXQ 4SdgqhhVvGcFkKFoB9k4Eo0sd4jCnl7CRX0Eiv/+SIq07YqoDwQJvmurLYLfzhkPNC8l bgrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282587; x=1788887387; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=VvmlYc4uR60GhmkrwN/xcN5jfUNAxmKzvS90Ij+le74=; b=FN9YW0I71xiSQ/g+GMseVd3iFVuQC6F10Bj8l5oPmKfAXHLblO/QmsGUyfLaiu6Mnc FUfiLWy/8vt/JZOcAJAjxqwYgobfb/95R06IV4E6N0zPtLtN3nnxIa+IpserCaJw9at9 7ltiDX/d/asfXYmtHoKP/yYw0QsjKnW1xHwnizbS55ltlS+sKl9tY2jQNOmw8H1LhPoP 9HU0K4Zfav3hba9oTbZ2ck7X3ecRn6nwXTJ+mUbhngB05xhdqieFfnK7zrUNkXKJKNqz yDWhfHorN1aZE9oD0FsaNH7uVV+5pOvM0dk5YW5TTpulNBz8vcS5hTQLcZ/G7JTUSaFT FKxQ== X-Gm-Message-State: AFuF++myPNfxyCpW9DNFbEGUpWF2ZZIfu5U6lGl/JlTYH6XNvSXtdj/B Q8wj3W5SMG3pQRBB5vBov4kvXvmpDNX4cjCfoUfEjqedUamt/2puw1ey X-Gm-Gg: AR+sD13k4zF43uxIHIc9poxZ0j3hfr4GkD90sh+p8pxuPCKVsA7p4Ne7iMRyQCauJOf 90lHucFi1s9EWfbtZ+IhzHtDksaLuKC4OVp+XcVvs7kU2CcA0EMtp1LRYYqLmBh/t+JuI1JEmSz b6mrMwhqo6IahIYzIUDthSgDhJXQOO6yNHZuopv6Zbhpfhe4nKoxBd6r9y/X0zvjmMivd3IanZa 6nlwp+7hU+MAjOSYKq6v8Z2+vDT3TKIPCtRyaTqOBsxdto9B5xiRYMYwqqY2tivf6RSQdpsdIW+ S8JJvq27scHfu0Nmltujx1cQutNX9cYq4OMVefwop3aL3cRlEv34FFq+pWccGjs4JIEVeZDC1Hx cJMpormvT+4RZhbvT0CHG5fBSsmXGEsocrgAmYrJYMP6ce8ou3rLlEkUsVchz4iiBEzoqHFK0Aa FaCQ1SpFwZiiPySLzDPUtnP2IqjDjKwMDIFpLcJA6X7ScY2bhZwRGN1eVyXkRm4eX3AiidNBDbU sv9GeOyPHhp1VrRUvJWFN6Ex2pX3L31A1tnHjmHKWo1dN8i0jOXimnmWmFYePH9LyDNgwDh6W0D klP0Nnly/jFpNPDeMRItR5BJ61I1PksKsMCosI2IHIhpzb5j5d5A3LA2NCjYWVlQ8+dHNlWiL8I 8+MFlmlXzwc6ixjdlu8s= X-Received: by 2002:a05:6830:33e6:b0:7e9:d34a:f436 with SMTP id 46e09a7af769-7f68f893dfamr4315441a34.17.1788282586932; Tue, 01 Sep 2026 10:09:46 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:46 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:09:01 -0600 Subject: [PATCH v2 07/10] net: lwip: allow DHCP to stop without releasing its lease MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-7-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org U-Boot keeps using the address acquired by the dhcp command. The existing lwIP stop operation sends DHCPRELEASE and clears the interface address, which is unsuitable when the interface remains active for another client. Factor the common shutdown path and add dhcp_stop_without_release(). It stops the state machine and drops its UDP PCB reference without sending DHCPRELEASE or clearing the interface address. Signed-off-by: James Hilliard --- lib/lwip/lwip/src/core/ipv4/dhcp.c | 39 ++++++++++++++++++++++++++--------- lib/lwip/lwip/src/include/lwip/dhcp.h | 1 + 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/lwip/lwip/src/core/ipv4/dhcp.c b/lib/lwip/lwip/src/core/ipv4/dhcp.c index d9ed8b0f37a..bfc6cfe488e 100644 --- a/lib/lwip/lwip/src/core/ipv4/dhcp.c +++ b/lib/lwip/lwip/src/core/ipv4/dhcp.c @@ -1315,20 +1315,15 @@ dhcp_reboot(struct netif *netif) return result; } -/** - * @ingroup dhcp4 - * Release a DHCP lease and stop DHCP statemachine (and AUTOIP if LWIP_DHCP_AUTOIP_COOP). - * - * @param netif network interface - */ -void -dhcp_release_and_stop(struct netif *netif) +/** Stop the DHCP state machine, optionally releasing its lease. */ +static void +dhcp_stop_internal(struct netif *netif, int release) { struct dhcp *dhcp = netif_dhcp_data(netif); ip_addr_t server_ip_addr; LWIP_ASSERT_CORE_LOCKED(); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release_and_stop()\n")); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop_internal()\n")); if (dhcp == NULL) { return; } @@ -1352,7 +1347,7 @@ dhcp_release_and_stop(struct netif *netif) dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0; /* send release message when current IP was assigned via DHCP */ - if (dhcp_supplied_address(netif)) { + if (release && dhcp_supplied_address(netif)) { /* create and initialize the DHCP message header */ struct pbuf *p_out; u16_t options_out_len; @@ -1391,6 +1386,30 @@ dhcp_release_and_stop(struct netif *netif) } } +/** + * @ingroup dhcp4 + * Stop DHCP without sending DHCPRELEASE or removing the configured address. + * + * @param netif network interface + */ +void +dhcp_stop_without_release(struct netif *netif) +{ + dhcp_stop_internal(netif, 0); +} + +/** + * @ingroup dhcp4 + * Release a DHCP lease and stop DHCP statemachine (and AUTOIP if LWIP_DHCP_AUTOIP_COOP). + * + * @param netif network interface + */ +void +dhcp_release_and_stop(struct netif *netif) +{ + dhcp_stop_internal(netif, 1); +} + /** * @ingroup dhcp4 * This function calls dhcp_release_and_stop() internally. diff --git a/lib/lwip/lwip/src/include/lwip/dhcp.h b/lib/lwip/lwip/src/include/lwip/dhcp.h index b413fa63f96..e7a79174f54 100644 --- a/lib/lwip/lwip/src/include/lwip/dhcp.h +++ b/lib/lwip/lwip/src/include/lwip/dhcp.h @@ -127,6 +127,7 @@ err_t dhcp_start(struct netif *netif); err_t dhcp_renew(struct netif *netif); err_t dhcp_release(struct netif *netif); void dhcp_stop(struct netif *netif); +void dhcp_stop_without_release(struct netif *netif); void dhcp_release_and_stop(struct netif *netif); void dhcp_inform(struct netif *netif); void dhcp_network_changed_link_up(struct netif *netif); From patchwork Tue Sep 1 17:09:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296159 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=ha+THKhI; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=DX61FbHF; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC6C0BJfz1xwZ for ; Wed, 02 Sep 2026 03:10:11 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id A8CFC80E98; Tue, 1 Sep 2026 17:10:09 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id pZ_v7ixFXE93; Tue, 1 Sep 2026 17:10:03 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282602; bh=nsyHfgTYMGTe+YD6G9vA5VOMo+1Jo0L8gAIAMWPqM5c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ha+THKhIV5DC556mcb7Y7Mu0/LA8wZZjPfBfgXpkiaze70K1QyNv3S0fYml+qzrKe Fli+dVQENgnler+sfQL3Az4BH+Oy21VbUcwDWDvcK07JuRiS05erM8EnrWF6H7U5HL 1/TZQIBFpOzGSb2eFd4cMAzRPJ/mlwCweSNwecOvlD9VzKd2RZ1L4vKFBL/XrqGXXU DO9W9SacvJYGY3lF160B3f7bmBHRV6Qt5ofJHHXmDqYHi+zJyFLIuyolzMFvKoM1TE lPzvB2GpiQrM1DthHvV9XHI9XZ0svMLIziq5zDZtpcUcVMx8OO4DVhSGm1eYIeKhjj Jdgapje4S4c4A== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp1.osuosl.org (Postfix) with ESMTP id 36F9580E2F; Tue, 1 Sep 2026 17:10:02 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists1.osuosl.org (Postfix) with ESMTP id 3CD7A2FD for ; Tue, 1 Sep 2026 17:09:55 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 227DC80E73 for ; Tue, 1 Sep 2026 17:09:55 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id D2_hGXbaY0US for ; Tue, 1 Sep 2026 17:09:50 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::32b; helo=mail-ot1-x32b.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp1.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=DX61FbHF Received: from mail-ot1-x32b.google.com (mail-ot1-x32b.google.com [IPv6:2607:f8b0:4864:20::32b]) by smtp1.osuosl.org (Postfix) with ESMTPS id C7D6A80E46 for ; Tue, 1 Sep 2026 17:09:49 +0000 (UTC) Received: by mail-ot1-x32b.google.com with SMTP id 46e09a7af769-7ee4f241f42so946119a34.1 for ; Tue, 01 Sep 2026 10:09:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282588; x=1788887388; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=nsyHfgTYMGTe+YD6G9vA5VOMo+1Jo0L8gAIAMWPqM5c=; b=DX61FbHFkQBMZcCRU2S2/tze9idEAIe+RnPIjoxVigFPVj/AYP7EW+cNWc9XWWvHFV T62RWefHU7qWX2Ow3SKx86qY9k2TooJ73DsLGDABv4Xz2HMAUznGgejkbQqr8iUmPuG1 JV4pRr2YlYL3dAZYpd6o8L+cX4Dv2+WLPS2cwHJ33DOpuLHALWawMgMgjSgvSDacC29f T8ogfeMgWhdnNjxLK3bqBfk0rAulxIWqljFkHbsPGMfkp2UB4NDU8xyR5K0RMs2TUsKq NR3A0V42eDL+4xRhDgklKYhwviFAqQBstm6fHYQfGaLyFgFcE+bn51QEca3mjy8ay3dE Zuyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282588; x=1788887388; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=nsyHfgTYMGTe+YD6G9vA5VOMo+1Jo0L8gAIAMWPqM5c=; b=bxu6MDjAlVFlyt/JlK6fc/nP5WY06uxW9AGlKK0MUKkZP8hkLav8Q/Ti2Wm/wPXE7z HwfOxRB6WeXAtDmyqUgRGS+lcZ/3rU6OkXLpy78XV3TwMPHCOpKcMyRJfHVqtZVRATDc 2fWYrR/tElHHss7ziHwObf8KwE54wd7ZwBaDqFd3Pxt2TSbUB74ffm0j66dV/KGaFVuM ezXfjwHGzcJEYVnxoVjJ+eg0m2g7lEZOASRdk0jC9V3es1f/v62/PeasU6nC9mILqsQ4 VseLMtVCLj2sUg3Alf00X58MosRdHooZyOaYQiz65KfHwjf9n6XgXTm5m/bozL3yZzMV T9pA== X-Gm-Message-State: AFuF++lCJO1eFr18cUH0UasMzpU/NEIdOImJ6znkgsUDQKOpxN1lP5j2 lfTWploMi73961qGOnbxfhjOhkt6aHC37/R9ytWAFWnKeS8Zr79ZxRMD X-Gm-Gg: AR+sD11u6MZLzGZkb224DDYg2HpPUy4GQLggwSYAdXM/j5YyTbFg/JtxBsV/2n9ZsKs sAMHEbTVPSliEfdNdLqQevAuYHbMLwUx6+Hr/lEk9fvEoBPgQBWdQ9EnZiL7Ypbzvvm4zMMiBdi aQAuU3hqBPhU64H3ItZwYQgiEfZoygkv6p92WRhtU+b8sVO1hFZZUbfvyMOGRtFhDEi5N/TXGe1 9zgMCAxJkIrFhUWRjn7L0l/5ePfY4251wHMT26Vm+GUmePdEjfLImHvku2V9LH6BIdvI1dMzyGv zpQU75lA2fVJWxTt1YqmoBq1JSR355pFH+wbjQwicZJ76vBeTJDwAysMuY5kR9kfk8ISGQ+iG2a rDO2SIYVdLFX2CgLl83/is3gsJ7JwMujycioaufWOZRR4xwAJfv10r8g83b3RwLY/5NbKCHup1v 263iUvBC9LQSdzFoWzjy9N83Oae/XdDK3ZZEV6KHqXDXkIxKGXurIn0y0XyN/mAS9zmuQhdt7J7 VupbAKPeL0zlrYpQAuwMYKo+dw4Lu8qBoEQJ/1zlVPqSpFn+8YLoY1bnJ6WORT6Todjh57AWpni qqU6L02DK4BgGTwnsx5CUalgaHuM91WJ1063KYLBQx5S3nTbBKMh2xYRkP43asXX1j/gNQSOSaC 8xNpQsXoF8H0MqavGhjo= X-Received: by 2002:a05:6830:6a93:b0:7e9:e19c:75f3 with SMTP id 46e09a7af769-7f68f572a66mr6738582a34.2.1788282588090; Tue, 01 Sep 2026 10:09:48 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:47 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:09:02 -0600 Subject: [PATCH v2 08/10] net: lwip: share one network runtime between clients MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-8-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org Each lwIP command currently creates the only netif and removes it when the command exits. A second client therefore replaces the first client's interface, and the first exit can stop Ethernet while the second is active. Add a reference-counted runtime attachment which owns one Ethernet device and netif. All attached clients use the global poll function, so lwIP dispatches packets to every registered PCB. Distinguish clients which require stable environment addressing from clients which can tolerate a temporary address change. An address-less DHCP attachment can coexist only with flexible clients, and the environment configuration is restored when it leaves. Migrate the existing commands and clean up their PCBs, callbacks and timeouts before detaching. Wget now aborts an interrupted request and releases its TLS configuration, while DHCP leaves its acquired address configured. Signed-off-by: James Hilliard --- cmd/lwip/ping.c | 41 ++++---- cmd/lwip/sntp.c | 19 ++-- include/net-lwip.h | 48 ++++++++-- net/lwip/dhcp.c | 57 ++++------- net/lwip/dns.c | 24 ++--- net/lwip/net-lwip.c | 270 +++++++++++++++++++++++++++++++++++++++++++++------- net/lwip/nfs.c | 25 ++--- net/lwip/tftp.c | 54 ++++------- net/lwip/wget.c | 70 ++++++++------ 9 files changed, 400 insertions(+), 208 deletions(-) diff --git a/cmd/lwip/ping.c b/cmd/lwip/ping.c index 98fa8e22bce..1498a86a15a 100644 --- a/cmd/lwip/ping.c +++ b/cmd/lwip/ping.c @@ -116,30 +116,23 @@ static void ping_send(void *arg) } } -static int ping_loop(struct udevice *udev, const ip_addr_t *addr) +static int ping_loop(struct net_lwip_ctx *net, const ip_addr_t *addr) { struct ping_ctx ctx = {}; - struct netif *netif; int ret; - netif = net_lwip_new_netif(udev); - if (!netif) - return -ENODEV; - - printf("Using %s device\n", udev->name); + printf("Using %s device\n", net->dev->name); ret = ping_raw_init(&ctx); - if (ret < 0) { - net_lwip_remove_netif(netif); + if (ret < 0) return ret; - } ctx.target = *addr; ping_send(&ctx); do { - net_lwip_rx(udev, netif); + net_lwip_poll(); if (ctx.alive) break; if (ctrlc()) { @@ -151,8 +144,6 @@ static int ping_loop(struct udevice *udev, const ip_addr_t *addr) sys_untimeout(ping_send, &ctx); ping_raw_stop(&ctx); - net_lwip_remove_netif(netif); - if (ctx.alive) return 0; @@ -162,6 +153,7 @@ static int ping_loop(struct udevice *udev, const ip_addr_t *addr) int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct net_lwip_ctx net = {}; ip_addr_t addr; int ret; @@ -174,13 +166,22 @@ int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) net_try_count = 1; do { - if (net_lwip_eth_start() == 0) { - ret = ping_loop(eth_get_dev(), &addr); - net_lwip_eth_stop(); - if (ret == 0) - return CMD_RET_SUCCESS; - } - } while (net_start_again() == 0); + ret = net_lwip_start(&net, NET_LWIP_ADDR_ENV_STRICT); + if (!ret) + break; + } while (!net_start_again()); + if (ret) + return CMD_RET_FAILURE; + + do { + ret = ping_loop(&net, &addr); + if (!ret) + break; + } while (!net_lwip_restart(&net)); + + net_lwip_stop(&net); + if (!ret) + return CMD_RET_SUCCESS; return CMD_RET_FAILURE; } diff --git a/cmd/lwip/sntp.c b/cmd/lwip/sntp.c index 584151ba7d1..d941060cd5c 100644 --- a/cmd/lwip/sntp.c +++ b/cmd/lwip/sntp.c @@ -54,14 +54,8 @@ static bool ntp_server_known(void) return false; } -static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) +static int sntp_loop(struct net_lwip_ctx *net, ip_addr_t *srvip) { - struct netif *netif; - - netif = net_lwip_new_netif(udev); - if (!netif) - return -1; - sntp_state = NOT_DONE; sntp_setoperatingmode(SNTP_OPMODE_POLL); @@ -71,7 +65,6 @@ static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) } else { if (!ntp_server_known()) { log_err("error: ntpserverip not set\n"); - net_lwip_remove_netif(netif); return -1; } } @@ -79,7 +72,7 @@ static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) sys_timeout(SNTP_TIMEOUT, no_response, NULL); while (sntp_state == NOT_DONE) { - net_lwip_rx(udev, netif); + net_lwip_poll(); if (ctrlc()) { printf("\nAbort\n"); sntp_state = ABORTED; @@ -89,7 +82,6 @@ static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) sys_untimeout(no_response, NULL); sntp_stop(); - net_lwip_remove_netif(netif); if (sntp_state == SUCCESS) return 0; @@ -99,6 +91,7 @@ static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct net_lwip_ctx net = {}; ip_addr_t *srvip; char *server; ip_addr_t ipaddr; @@ -125,16 +118,16 @@ int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return CMD_RET_USAGE; } - if (net_lwip_eth_start() < 0) + if (net_lwip_start(&net, NET_LWIP_ADDR_ENV_STRICT)) return CMD_RET_FAILURE; - if (sntp_loop(eth_get_dev(), srvip) < 0) + if (sntp_loop(&net, srvip) < 0) goto out; ret = CMD_RET_SUCCESS; out: - net_lwip_eth_stop(); + net_lwip_stop(&net); return ret; } diff --git a/include/net-lwip.h b/include/net-lwip.h index 8e59a2299e0..c1e7ae05be6 100644 --- a/include/net-lwip.h +++ b/include/net-lwip.h @@ -6,6 +6,41 @@ #include #include +struct udevice; + +/** + * enum net_lwip_addr_mode - IPv4 requirements of a runtime client + * @NET_LWIP_ADDR_ENV_STRICT: Use environment addressing and require it to + * remain stable while the client is attached + * @NET_LWIP_ADDR_ENV_FLEXIBLE: Use environment addressing, but permit another + * client to temporarily change or clear the shared interface configuration + * @NET_LWIP_ADDR_NONE: Temporarily own the shared interface configuration and + * start without an IPv4 address. This mode can coexist only with flexible + * clients + */ +enum net_lwip_addr_mode { + NET_LWIP_ADDR_ENV_STRICT, + NET_LWIP_ADDR_ENV_FLEXIBLE, + NET_LWIP_ADDR_NONE, +}; + +/** + * struct net_lwip_ctx - Attachment to the shared lwIP runtime + * @dev: Ethernet device used by the runtime + * @netif: Shared lwIP network interface + * @addr_mode: Address mode requested by this client + * + * Clients must zero-initialize this structure before passing it to + * net_lwip_start(). Multiple active clients share @dev and @netif. A client + * must remove its callbacks and protocol control blocks before calling + * net_lwip_stop(). + */ +struct net_lwip_ctx { + struct udevice *dev; + struct netif *netif; + enum net_lwip_addr_mode addr_mode; +}; + /* HTTPS authentication mode */ enum auth_mode { AUTH_NONE, @@ -34,13 +69,12 @@ static inline int eth_is_on_demand_init(void) int eth_init_state_only(void); /* Set active state */ int net_lwip_dns_init(void); -int net_lwip_eth_start(void); -void net_lwip_eth_stop(void); -struct netif *net_lwip_new_netif(struct udevice *udev); -struct netif *net_lwip_new_netif_noip(struct udevice *udev); -void net_lwip_remove_netif(struct netif *netif); -struct netif *net_lwip_get_netif(void); -int net_lwip_rx(struct udevice *udev, struct netif *netif); +int net_lwip_start(struct net_lwip_ctx *ctx, + enum net_lwip_addr_mode addr_mode); +void net_lwip_stop(struct net_lwip_ctx *ctx); +int net_lwip_restart(struct net_lwip_ctx *ctx); +int net_lwip_refresh(struct net_lwip_ctx *ctx); +int net_lwip_poll(void); int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip); /** diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c index a5e2e7d4da0..0494e3981d5 100644 --- a/net/lwip/dhcp.c +++ b/net/lwip/dhcp.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -22,34 +21,23 @@ static char boot_file_name[DHCP_BOOT_FILE_LEN]; #endif -static void call_lwip_dhcp_fine_tmr(void *ctx) -{ - dhcp_fine_tmr(); - sys_timeout(DHCP_FINE_TIMER_MSECS, call_lwip_dhcp_fine_tmr, NULL); -} - -static int dhcp_loop(struct udevice *udev) +static int dhcp_loop(struct net_lwip_ctx *net) { char ipstr[] = "ipaddr\0\0\0"; char maskstr[] = "netmask\0\0\0"; char gwstr[] = "gatewayip\0\0\0"; const ip_addr_t *ntpserverip; unsigned long start; - struct netif *netif; struct dhcp *dhcp; - bool bound; + bool bound = false; int idx; - idx = dev_seq(udev); + idx = dev_seq(net->dev); if (idx < 0 || idx > 99) { log_err("unexpected idx %d\n", idx); return CMD_RET_FAILURE; } - netif = net_lwip_new_netif_noip(udev); - if (!netif) - return CMD_RET_FAILURE; - /* * Request the DHCP stack to parse and store the NTP servers for * eventual use by the SNTP command @@ -59,15 +47,13 @@ static int dhcp_loop(struct udevice *udev) start = get_timer(0); - if (dhcp_start(netif)) + if (dhcp_start(net->netif)) return CMD_RET_FAILURE; - call_lwip_dhcp_fine_tmr(NULL); - /* Wait for DHCP to complete */ do { - net_lwip_rx(udev, netif); - bound = dhcp_supplied_address(netif); + net_lwip_poll(); + bound = dhcp_supplied_address(net->netif); if (bound) break; if (ctrlc()) { @@ -77,14 +63,10 @@ static int dhcp_loop(struct udevice *udev) mdelay(1); } while (get_timer(start) < DHCP_TIMEOUT_MS); - sys_untimeout(call_lwip_dhcp_fine_tmr, NULL); - - if (!bound) { - net_lwip_remove_netif(netif); + if (!bound) return CMD_RET_FAILURE; - } - dhcp = netif_dhcp_data(netif); + dhcp = netif_dhcp_data(net->netif); env_set("bootfile", dhcp->boot_file_name); @@ -123,26 +105,18 @@ static int dhcp_loop(struct udevice *udev) printf("DHCP client bound to address %pI4 (%lu ms)\n", &dhcp->offered_ip_addr, get_timer(start)); - net_lwip_remove_netif(netif); return CMD_RET_SUCCESS; } int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct net_lwip_ctx net = {}; int ret; - struct udevice *dev; - if (net_lwip_eth_start() < 0) + if (net_lwip_start(&net, NET_LWIP_ADDR_NONE)) return CMD_RET_FAILURE; - dev = eth_get_dev(); - if (!dev) { - log_err("No network device\n"); - ret = CMD_RET_FAILURE; - goto out; - } - - ret = dhcp_loop(dev); + ret = dhcp_loop(&net); if (ret) goto out; @@ -156,7 +130,14 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ret = CMD_RET_SUCCESS; out: - net_lwip_eth_stop(); + if (net.netif) { + if (dhcp_supplied_address(net.netif)) + dhcp_stop_without_release(net.netif); + else + dhcp_release_and_stop(net.netif); + dhcp_cleanup(net.netif); + } + net_lwip_stop(&net); return ret; } diff --git a/net/lwip/dns.c b/net/lwip/dns.c index b620b0611d6..e932b3c6965 100644 --- a/net/lwip/dns.c +++ b/net/lwip/dns.c @@ -34,24 +34,18 @@ static void dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg) ip_addr_set(&dns_cb_arg->host_ipaddr, ipaddr); } -static int dns_loop(struct udevice *udev, const char *name, const char *var) +static int dns_loop(struct net_lwip_ctx *net, const char *name, + const char *var) { struct dns_cb_arg dns_cb_arg = { }; - struct netif *netif; const char *ipstr; ip_addr_t ipaddr; ulong start; int ret; - netif = net_lwip_new_netif(udev); - if (!netif) + if (net_lwip_dns_init()) return CMD_RET_FAILURE; - if (net_lwip_dns_init()) { - net_lwip_remove_netif(netif); - return CMD_RET_FAILURE; - } - dns_cb_arg.done = false; ret = dns_gethostbyname(name, &ipaddr, dns_cb, &dns_cb_arg); @@ -62,7 +56,7 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var) start = get_timer(0); sys_timeout(DNS_RESEND_MS, do_dns_tmr, NULL); do { - net_lwip_rx(udev, netif); + net_lwip_poll(); if (dns_cb_arg.done) break; if (ctrlc()) { @@ -71,10 +65,9 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var) } } while (get_timer(start) < DNS_TIMEOUT_MS); sys_untimeout(do_dns_tmr, NULL); + dns_cancel(dns_cb, &dns_cb_arg); } - net_lwip_remove_netif(netif); - if (dns_cb_arg.done && !ip_addr_isany(&dns_cb_arg.host_ipaddr)) { ipstr = ipaddr_ntoa(&dns_cb_arg.host_ipaddr); if (var) @@ -89,6 +82,7 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var) int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct net_lwip_ctx net = {}; char *name; char *var = NULL; int ret; @@ -101,12 +95,12 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc == 3) var = argv[2]; - if (net_lwip_eth_start() < 0) + if (net_lwip_start(&net, NET_LWIP_ADDR_ENV_STRICT)) return CMD_RET_FAILURE; - ret = dns_loop(eth_get_dev(), name, var); + ret = dns_loop(&net, name, var); - net_lwip_eth_stop(); + net_lwip_stop(&net); return ret; } diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index 8f8f9d69020..30941ce4116 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -31,7 +31,15 @@ void (*push_packet)(void *, int len) = 0; int net_try_count; static int net_restarted; int net_restart_wrap; -static int net_lwip_eth_started; +static struct { + struct udevice *dev; + struct netif *netif; + unsigned int users; + unsigned int env_users; + unsigned int strict_env_users; + unsigned int no_addr_users; + bool polling; +} net_lwip_runtime; static uchar net_pkt_buf[(PKTBUFSRX) * PKTSIZE_ALIGN + PKTALIGN] __aligned(PKTALIGN); const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -107,19 +115,6 @@ static void eth_init_rings(void) net_rx_packets[i] = net_pkt_buf + i * PKTSIZE_ALIGN; } -struct netif *net_lwip_get_netif(void) -{ - struct netif *netif, *found = NULL; - - NETIF_FOREACH(netif) { - if (!found) - found = netif; - else - printf("Error: more than one netif in lwIP\n"); - } - return found; -} - static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip, ip4_addr_t *mask, ip4_addr_t *gw) { @@ -196,19 +191,15 @@ int net_lwip_dns_init(void) /* * Initialize the network stack if needed and start the current device if valid */ -int net_lwip_eth_start(void) +static int net_lwip_eth_start(void) { int ret; - if (net_lwip_eth_started++ > 0) - return 0; - net_init(); eth_halt(); eth_set_current(); ret = eth_init(); if (ret < 0) { - net_lwip_eth_started--; eth_halt(); return ret; } @@ -216,14 +207,8 @@ int net_lwip_eth_start(void) return 0; } -void net_lwip_eth_stop(void) +static void net_lwip_eth_stop(void) { - if (!net_lwip_eth_started) - return; - - if (--net_lwip_eth_started) - return; - eth_halt(); } @@ -243,8 +228,6 @@ static struct netif *new_netif(struct udevice *udev, bool with_ip) return NULL; } - netif_remove(net_lwip_get_netif()); - ip4_addr_set_zero(&ip); ip4_addr_set_zero(&mask); ip4_addr_set_zero(&gw); @@ -287,20 +270,209 @@ static struct netif *new_netif(struct udevice *udev, bool with_ip) return netif; } -struct netif *net_lwip_new_netif(struct udevice *udev) +static void net_lwip_remove_netif(struct netif *netif) { - return new_netif(udev, true); + netif_remove(netif); + free(netif); } -struct netif *net_lwip_new_netif_noip(struct udevice *udev) +static int net_lwip_configure(enum net_lwip_addr_mode addr_mode) { - return new_netif(udev, false); + ip4_addr_t ip, mask, gw; + + if (addr_mode != NET_LWIP_ADDR_NONE) { + if (get_udev_ipv4_info(net_lwip_runtime.dev, &ip, &mask, &gw)) + return -EINVAL; + } else { + ip4_addr_set_zero(&ip); + ip4_addr_set_zero(&mask); + ip4_addr_set_zero(&gw); + } + + if (ip4_addr_cmp(netif_ip4_addr(net_lwip_runtime.netif), &ip) && + ip4_addr_cmp(netif_ip4_netmask(net_lwip_runtime.netif), &mask) && + ip4_addr_cmp(netif_ip4_gw(net_lwip_runtime.netif), &gw)) + return 0; + + if (net_lwip_runtime.strict_env_users) + return -EBUSY; + + netif_set_addr(net_lwip_runtime.netif, &ip, &mask, &gw); + + return 0; } -void net_lwip_remove_netif(struct netif *netif) +/** + * net_lwip_start - Attach a client to the shared lwIP runtime + * @ctx: Zero-initialized client attachment + * @addr_mode: Initial IPv4 address configuration requested by the client + * + * The first client starts the selected Ethernet device and creates the lwIP + * network interface. Later clients share both resources. Strict environment + * clients and address-less clients are mutually exclusive. Flexible clients + * can remain attached while an address-less client temporarily owns the + * interface configuration. + * + * Return: 0 on success, or a negative error code. + */ +int net_lwip_start(struct net_lwip_ctx *ctx, + enum net_lwip_addr_mode addr_mode) { - netif_remove(netif); - free(netif); + struct netif *netif; + int ret; + + if (!ctx) + return -EINVAL; + if (ctx->netif || ctx->dev) + return -EBUSY; + if (addr_mode != NET_LWIP_ADDR_ENV_STRICT && + addr_mode != NET_LWIP_ADDR_ENV_FLEXIBLE && + addr_mode != NET_LWIP_ADDR_NONE) + return -EINVAL; + if ((addr_mode == NET_LWIP_ADDR_NONE && + (net_lwip_runtime.strict_env_users || + net_lwip_runtime.no_addr_users)) || + (addr_mode == NET_LWIP_ADDR_ENV_STRICT && + net_lwip_runtime.no_addr_users)) + return -EBUSY; + + if (!net_lwip_runtime.users) { + ret = net_lwip_eth_start(); + if (ret) + return ret; + + net_lwip_runtime.dev = eth_get_dev(); + netif = new_netif(net_lwip_runtime.dev, + addr_mode != NET_LWIP_ADDR_NONE); + if (!netif) { + net_lwip_runtime.dev = NULL; + net_lwip_eth_stop(); + return -ENODEV; + } + net_lwip_runtime.netif = netif; + } else if (addr_mode == NET_LWIP_ADDR_NONE && + !net_lwip_runtime.no_addr_users) { + ret = net_lwip_configure(NET_LWIP_ADDR_NONE); + if (ret) + return ret; + } else if (addr_mode != NET_LWIP_ADDR_NONE && + !net_lwip_runtime.no_addr_users) { + ret = net_lwip_configure(addr_mode); + if (ret) + return ret; + } + + net_lwip_runtime.users++; + if (addr_mode == NET_LWIP_ADDR_NONE) { + net_lwip_runtime.no_addr_users++; + } else { + net_lwip_runtime.env_users++; + if (addr_mode == NET_LWIP_ADDR_ENV_STRICT) + net_lwip_runtime.strict_env_users++; + } + + ctx->dev = net_lwip_runtime.dev; + ctx->netif = net_lwip_runtime.netif; + ctx->addr_mode = addr_mode; + + return 0; +} + +/** + * net_lwip_stop - Detach a client from the shared lwIP runtime + * @ctx: Active client attachment + * + * The final client removes the lwIP interface and stops Ethernet. When the + * last address-less client leaves, environment addressing is restored for + * any clients which remain attached. Callers must first remove every lwIP + * callback and protocol control block owned by @ctx. This function must not + * be called from a callback dispatched by net_lwip_poll(). + */ +void net_lwip_stop(struct net_lwip_ctx *ctx) +{ + if (!ctx || ctx->netif != net_lwip_runtime.netif || + ctx->dev != net_lwip_runtime.dev || !net_lwip_runtime.users) + return; + + if (ctx->addr_mode == NET_LWIP_ADDR_NONE) { + net_lwip_runtime.no_addr_users--; + } else { + net_lwip_runtime.env_users--; + if (ctx->addr_mode == NET_LWIP_ADDR_ENV_STRICT) + net_lwip_runtime.strict_env_users--; + } + net_lwip_runtime.users--; + + ctx->dev = NULL; + ctx->netif = NULL; + + if (!net_lwip_runtime.users) { + net_lwip_remove_netif(net_lwip_runtime.netif); + net_lwip_runtime.netif = NULL; + net_lwip_runtime.dev = NULL; + net_lwip_eth_stop(); + return; + } + + if (!net_lwip_runtime.no_addr_users && + net_lwip_runtime.env_users && + net_lwip_configure(NET_LWIP_ADDR_ENV_FLEXIBLE)) + log_err("Failed to restore lwIP interface addressing\n"); +} + +/** + * net_lwip_restart - Restart an exclusively held lwIP runtime + * @ctx: Active client attachment + * + * Stop the current interface, select the next interface according to the + * normal network retry policy and attach @ctx to the replacement interface. + * A shared runtime cannot be restarted without disrupting other clients. + * + * Return: 0 on success, -EBUSY if other clients are attached, or another + * negative error code. + */ +int net_lwip_restart(struct net_lwip_ctx *ctx) +{ + enum net_lwip_addr_mode addr_mode; + int ret; + + if (!ctx || ctx->netif != net_lwip_runtime.netif || + ctx->dev != net_lwip_runtime.dev || !net_lwip_runtime.users) + return -EINVAL; + if (net_lwip_runtime.users != 1) + return -EBUSY; + + addr_mode = ctx->addr_mode; + net_lwip_stop(ctx); + + ret = net_start_again(); + if (ret) + return ret; + + return net_lwip_start(ctx, addr_mode); +} + +/** + * net_lwip_refresh - Refresh environment addressing for the shared interface + * @ctx: Active environment-addressed client attachment + * + * Address-less clients take priority, so flexible-client refreshes are + * deferred until the last such client detaches. A refresh which would change + * the address while a strict client is attached fails with -EBUSY. + * + * Return: 0 on success, or a negative error code. + */ +int net_lwip_refresh(struct net_lwip_ctx *ctx) +{ + if (!ctx || ctx->netif != net_lwip_runtime.netif || + ctx->dev != net_lwip_runtime.dev || + ctx->addr_mode == NET_LWIP_ADDR_NONE) + return -EINVAL; + + if (net_lwip_runtime.no_addr_users) + return 0; + + return net_lwip_configure(ctx->addr_mode); } /* @@ -343,7 +515,7 @@ static struct pbuf *alloc_pbuf_and_copy(uchar *data, int len) return p; } -int net_lwip_rx(struct udevice *udev, struct netif *netif) +static int net_lwip_rx(struct udevice *udev, struct netif *netif) { struct pbuf *pbuf; uchar *packet; @@ -387,6 +559,32 @@ int net_lwip_rx(struct udevice *udev, struct netif *netif) return len; } +/** + * net_lwip_poll - Service the shared lwIP runtime + * + * Run lwIP timers, schedule other U-Boot work and dispatch received packets + * to all registered lwIP protocol control blocks. Reentrant calls are rejected + * so protocol callbacks may safely invoke code which attempts to poll. + * + * Return: Receive status, -ENODEV with no active clients, or -EBUSY when a + * poll is already in progress. + */ +int net_lwip_poll(void) +{ + int ret; + + if (!net_lwip_runtime.users) + return -ENODEV; + if (net_lwip_runtime.polling) + return -EBUSY; + + net_lwip_runtime.polling = true; + ret = net_lwip_rx(net_lwip_runtime.dev, net_lwip_runtime.netif); + net_lwip_runtime.polling = false; + + return ret; +} + /** * net_lwip_dns_resolve() - find IP address from name or IP * diff --git a/net/lwip/nfs.c b/net/lwip/nfs.c index 4cc36373fdd..42ce5dad946 100644 --- a/net/lwip/nfs.c +++ b/net/lwip/nfs.c @@ -98,10 +98,9 @@ static int nfs_timeout_check(void) return 1; } -static int nfs_loop(struct udevice *udev, ulong addr, char *fname, +static int nfs_loop(struct net_lwip_ctx *net, ulong addr, char *fname, ip_addr_t srvip) { - struct netif *netif; int ret; nfs_download_state = NETLOOP_FAIL; @@ -110,16 +109,12 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname, if (!fname || addr == 0) return -1; - netif = net_lwip_new_netif(udev); - if (!netif) - return -1; - strlcpy(nfs_path_buff, fname, sizeof(nfs_path_buff)); nfs_filename = nfs_basename(nfs_path_buff); nfs_path = nfs_dirname(nfs_path_buff); - printf("Using %s device\n", udev->name); + printf("Using %s device\n", net->dev->name); printf("File transfer via NFS from server %s; our IP address is %s\n", ipaddr_ntoa(&srvip), env_get("ipaddr")); @@ -139,7 +134,6 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname, ret = nfs_udp_init(&sess_ctx); if (ret < 0) { - net_lwip_remove_netif(netif); debug("Failed to init network interface, aborting for error = %d\n", ret); return ret; } @@ -152,7 +146,7 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname, timer_start = get_timer(0); do { - net_lwip_rx(udev, netif); + net_lwip_poll(); if (net_state != NETLOOP_CONTINUE) break; if (ctrlc()) { @@ -165,7 +159,8 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname, } while (true); debug("%s: Loop exit at %lu\n", __func__, get_timer(0)); - net_lwip_remove_netif(netif); + udp_remove(sess_ctx.pcb); + sess_ctx.pcb = NULL; if (net_state == NETLOOP_SUCCESS) { ret = 0; @@ -186,8 +181,8 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname, int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct net_lwip_ctx net = {}; int ret = CMD_RET_SUCCESS; - bool started = false; char *arg = NULL; char *words[2] = { }; char *fname = NULL; @@ -278,17 +273,15 @@ int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) goto out; } - if (net_lwip_eth_start() < 0) { + if (net_lwip_start(&net, NET_LWIP_ADDR_ENV_STRICT)) { ret = CMD_RET_FAILURE; goto out; } - started = true; - if (nfs_loop(eth_get_dev(), laddr, fname, srvip) < 0) + if (nfs_loop(&net, laddr, fname, srvip) < 0) ret = CMD_RET_FAILURE; out: - if (started) - net_lwip_eth_stop(); + net_lwip_stop(&net); if (arg != net_boot_file_name) free(arg); return ret; diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index d6a9f29a260..48c6eb7022a 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -226,11 +226,10 @@ static void no_response(void *arg) ctx->done = FAILURE; } -static int tftp_loop(struct udevice *udev, ulong addr, char *fname, +static int tftp_loop(struct net_lwip_ctx *net, ulong addr, char *fname, ip_addr_t srvip, uint16_t srvport) { int blksize = CONFIG_TFTP_BLOCKSIZE; - struct netif *netif; struct tftp_ctx ctx; const char *ep; err_t err; @@ -241,10 +240,6 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, if (!srvport) srvport = TFTP_PORT; - netif = net_lwip_new_netif(udev); - if (!netif) - return -1; - ctx.done = NOT_DONE; ctx.size = 0; ctx.block_count = 0; @@ -254,7 +249,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, ctx.wrq_accepted = false; ctx.fname[0] = '\0'; - printf("Using %s device\n", udev->name); + printf("Using %s device\n", net->dev->name); printf("TFTP from server %s; our IP address is %s\n", ipaddr_ntoa(&srvip), env_get("ipaddr")); printf("Filename '%s'.\n", fname); @@ -262,8 +257,10 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, printf("Loading: "); err = tftp_init_client(&tftp_context); - if (!(err == ERR_OK || err == ERR_USE)) + if (err != ERR_OK) { log_err("tftp_init_client err: %d\n", err); + return -1; + } ep = env_get("tftpblocksize"); if (ep) @@ -275,13 +272,13 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, /* might return different errors, like routing problems */ if (err != ERR_OK) { printf("tftp_get() error %d\n", err); - net_lwip_remove_netif(netif); + tftp_cleanup(); return -1; } sys_timeout(NO_RSP_TIMEOUT_MS, no_response, &ctx); while (!ctx.done) { - net_lwip_rx(udev, netif); + net_lwip_poll(); if (ctrlc()) { printf("\nAbort\n"); ctx.done = ABORTED; @@ -292,8 +289,6 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, tftp_cleanup(); - net_lwip_remove_netif(netif); - if (ctx.done == SUCCESS) { if (env_set_hex("fileaddr", addr)) { log_err("fileaddr not updated\n"); @@ -318,9 +313,8 @@ static void no_request(void *arg) ctx->done = FAILURE; } -static int tftpsrv_loop(struct udevice *udev, ulong addr) +static int tftpsrv_loop(struct net_lwip_ctx *net, ulong addr) { - struct netif *netif; struct tftp_ctx ctx; const char *ipaddr; int ret = -1; @@ -335,16 +329,12 @@ static int tftpsrv_loop(struct udevice *udev, ulong addr) return -1; } - netif = net_lwip_new_netif(udev); - if (!netif) - return -1; - memset(&ctx, 0, sizeof(ctx)); ctx.done = NOT_DONE; ctx.daddr = addr; ctx.is_server = true; - printf("Using %s device\n", udev->name); + printf("Using %s device\n", net->dev->name); printf("Listening for TFTP transfer on %s\n", ipaddr); printf("Load address: 0x%lx\n", ctx.daddr); @@ -352,13 +342,13 @@ static int tftpsrv_loop(struct udevice *udev, ulong addr) err = tftp_init_server(&tftp_context); if (err != ERR_OK) { log_err("tftp_init_server err: %d\n", err); - goto out_remove_netif; + goto out; } ctx.start_time = get_timer(0); sys_timeout(TFTPSRV_LISTEN_TIMEOUT_MS, no_request, &ctx); while (!ctx.done) { - net_lwip_rx(udev, netif); + net_lwip_poll(); if (ctrlc()) { printf("\nAbort\n"); ctx.done = ABORTED; @@ -373,22 +363,22 @@ static int tftpsrv_loop(struct udevice *udev, ulong addr) if (ctx.done == SUCCESS) { if (env_set_hex("fileaddr", addr)) { log_err("fileaddr not updated\n"); - goto out_remove_netif; + goto out; } efi_set_bootdev("Net", "", ctx.fname, map_sysmem(addr, 0), ctx.size); ret = 0; } -out_remove_netif: +out: tftpsrv_active_ctx = NULL; - net_lwip_remove_netif(netif); return ret; } int do_tftpsrv(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct net_lwip_ctx net = {}; int ret = CMD_RET_SUCCESS; char *end; ulong laddr; @@ -421,25 +411,25 @@ int do_tftpsrv(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) goto out; } - if (net_lwip_eth_start() < 0) { + if (net_lwip_start(&net, NET_LWIP_ADDR_ENV_STRICT)) { ret = CMD_RET_FAILURE; goto out; } - if (tftpsrv_loop(eth_get_dev(), laddr) < 0) + if (tftpsrv_loop(&net, laddr) < 0) ret = CMD_RET_FAILURE; else image_load_addr = laddr; - net_lwip_eth_stop(); out: + net_lwip_stop(&net); return ret; } int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct net_lwip_ctx net = {}; int ret = CMD_RET_SUCCESS; - bool started = false; char *arg = NULL; char *words[3] = { }; char *fname = NULL; @@ -540,19 +530,17 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) goto out; } - if (net_lwip_eth_start() < 0) { + if (net_lwip_start(&net, NET_LWIP_ADDR_ENV_STRICT)) { ret = CMD_RET_FAILURE; goto out; } - started = true; - if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0) + if (tftp_loop(&net, laddr, fname, srvip, port) < 0) ret = CMD_RET_FAILURE; else image_load_addr = laddr; out: - if (started) - net_lwip_eth_stop(); + net_lwip_stop(&net); if (arg != net_boot_file_name) free(arg); return ret; diff --git a/net/lwip/wget.c b/net/lwip/wget.c index e8930da410b..96ee600c5e1 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -39,6 +39,7 @@ struct wget_ctx { ulong content_len; ulong hash_count; enum done_state done; + bool aborted; }; static void wget_lwip_fill_info(struct pbuf *hdr, u16_t hdr_len, u32_t hdr_cont_len) @@ -229,6 +230,10 @@ static void httpc_result_cb(void *arg, httpc_result_t httpc_result, ctx->done = FAILURE; return; } + if (httpc_result == HTTPC_RESULT_LOCAL_ABORT && ctx->aborted) { + ctx->done = FAILURE; + return; + } if (httpc_result != HTTPC_RESULT_OK) { log_err("\nHTTP client error %d\n", httpc_result); @@ -293,13 +298,15 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct #endif static int wget_handle_request(struct wget_ctx *ctx, bool is_https, - struct udevice *udev, struct netif *netif) + struct net_lwip_ctx *net) { #if CONFIG_IS_ENABLED(WGET_HTTPS) + struct altcp_tls_config *tls_config = NULL; altcp_allocator_t tls_allocator; #endif httpc_connection_t conn; httpc_state_t *state; + err_t err; int ret; /* if URL with hostname init dns */ @@ -348,11 +355,11 @@ static int wget_handle_request(struct wget_ctx *ctx, bool is_https, printf("HTTPS connections not authenticated\n"); } tls_allocator.alloc = &altcp_tls_alloc; - tls_allocator.arg = - altcp_tls_create_config_client(ca, ca_sz, - ctx->server_name); + tls_config = altcp_tls_create_config_client(ca, ca_sz, + ctx->server_name); + tls_allocator.arg = tls_config; - if (!tls_allocator.arg) { + if (!tls_config) { log_err("error: Cannot create a TLS connection\n"); return -ENODEV; } @@ -363,33 +370,44 @@ static int wget_handle_request(struct wget_ctx *ctx, bool is_https, conn.result_fn = httpc_result_cb; conn.headers_done_fn = httpc_headers_done_cb; - if (httpc_get_file_dns(ctx->server_name, ctx->port, ctx->path, &conn, - httpc_recv_cb, ctx, &state)) { - return -ENODEV; + err = httpc_get_file_dns(ctx->server_name, ctx->port, ctx->path, &conn, + httpc_recv_cb, ctx, &state); + if (err) { + ret = -ENODEV; + goto out; } errno = 0; while (!ctx->done) { - net_lwip_rx(udev, netif); - if (ctrlc()) + net_lwip_poll(); + if (!ctx->done && ctrlc()) { + ctx->aborted = true; + httpc_abort(state); break; + } } - if (ctx->done == SUCCESS) - return 0; - - if (errno == EPERM && !wget_info->silent) - printf("Certificate verification failed\n"); + if (ctx->done == SUCCESS) { + ret = 0; + } else { + if (errno == EPERM && !wget_info->silent) + printf("Certificate verification failed\n"); + ret = -errno ?: -EIO; + } - return -errno ?: -EIO; +out: +#if CONFIG_IS_ENABLED(WGET_HTTPS) + if (tls_config) + altcp_tls_free_config(tls_config); +#endif + return ret; } int wget_do_request(ulong dst_addr, char *uri) { - struct udevice *udev; + struct net_lwip_ctx net = {}; struct wget_ctx ctx; - struct netif *netif; bool is_https; int ret; @@ -401,30 +419,22 @@ int wget_do_request(ulong dst_addr, char *uri) ctx.start_time = 0; ctx.content_len = 0; ctx.hash_count = 0; + ctx.aborted = false; ret = parse_url(uri, ctx.server_name, &ctx.port, &ctx.path, &is_https); if (ret) return ret; - ret = net_lwip_eth_start(); + ret = net_lwip_start(&net, NET_LWIP_ADDR_ENV_STRICT); if (ret) return ret; if (!wget_info) wget_info = &default_wget_info; - udev = eth_get_dev(); - - netif = net_lwip_new_netif(udev); - if (!netif) { - net_lwip_eth_stop(); - return -ENODEV; - } - - ret = wget_handle_request(&ctx, is_https, udev, netif); + ret = wget_handle_request(&ctx, is_https, &net); - net_lwip_remove_netif(netif); - net_lwip_eth_stop(); + net_lwip_stop(&net); return ret; } From patchwork Tue Sep 1 17:09:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296160 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=trQx49ea; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=srIB3/Xx; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC6F6m4kz1xwZ for ; Wed, 02 Sep 2026 03:10:13 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 9384180E36; Tue, 1 Sep 2026 17:10:12 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id xz0cxF9onPlh; Tue, 1 Sep 2026 17:10:10 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282603; bh=HP31mekP/N+rBHT3J/oOqdRhGEYQks/BgkITwkHcSUw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=trQx49eaX5L4MD5qnl4ZIaEAVZ3Qe91PUTuJJGEFjL4oLcnlARI9wwoEX5AlMTQZC O1iu7D9h6pyHxcyW7jP2bJQd6eRkcn6ec2Os81/Sls7STTq+I79U3J1MX3pjhBXkX9 Q40h6pnOhFyxrIb1veebddtJCqmUoRdcgCyHknIzG7Qzmb1XUkFKlLmcNEBhKT2lP0 BWwQTZRqSyZe6XoizwBQddKJbMeTMxaBpIDIOdZy8r37zuaU3VReSxXvbXvtvv3WY+ FKexvy77w0gdQkUQkypTDe2lyxxl0psptAC/6iEKfHmAWW5+kSLpd5n8pRLbUEpEVq ciuE1uPLVzjrg== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp1.osuosl.org (Postfix) with ESMTP id 421C080E84; Tue, 1 Sep 2026 17:10:03 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists1.osuosl.org (Postfix) with ESMTP id 59E172FD for ; Tue, 1 Sep 2026 17:09:55 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 3E84780E46 for ; Tue, 1 Sep 2026 17:09:55 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id SYydAaEnF0CL for ; Tue, 1 Sep 2026 17:09:51 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::331; helo=mail-ot1-x331.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp1.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=srIB3/Xx Received: from mail-ot1-x331.google.com (mail-ot1-x331.google.com [IPv6:2607:f8b0:4864:20::331]) by smtp1.osuosl.org (Postfix) with ESMTPS id 2178280DE0 for ; Tue, 1 Sep 2026 17:09:50 +0000 (UTC) Received: by mail-ot1-x331.google.com with SMTP id 46e09a7af769-7f4f53975e6so883739a34.3 for ; Tue, 01 Sep 2026 10:09:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282589; x=1788887389; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=HP31mekP/N+rBHT3J/oOqdRhGEYQks/BgkITwkHcSUw=; b=srIB3/XxXwtQfVl30cm9z3xjCCyTMdPh84kgPGNNPn6WYgxZUnep5oSFqIAqgawdKg V+NRKMOkbJNelOi2YaEeBaotbfMpAKIFmI7fub+ApttJWRCI6/MBGtGp6ymSvz5xrb30 KzBdIxsh9jAq78/OY1UnBgg4eSZuf+9mb730py5vvB1JYoNDyfszykT49cwKh6nZqf/X Ql5RAEItJ6FgvAwFNk2bpsQBro/CQ9lrUpYuoTVqMpjdR7fHN7aG2L5/eSyYakNhm2iU Ze1babyoyCnIZGXOUdqgZgHAU6nIh3Af/D5/yySipnYoLouRmNSEIck8yNPC/zIjjaVy WgTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282589; x=1788887389; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=HP31mekP/N+rBHT3J/oOqdRhGEYQks/BgkITwkHcSUw=; b=qm6qsLJN/iRIYyGrFRLcUQg1dOn8YA0sCpdiJCPdWW9E+aInCcqjmZaLZpRtGv04Lc z4OLlZy7sXkLDYJDp0jH9YWfqRkaUNSXBcFPeWUNPUrXCZZuYyRhr3GGQ49nI3kVtstL smNJGuuv1lfW37Tf3EYu4TkbFmPzILHL3qOEas7Op7Uk2jBkHyG41CNaCxVaFQKYMBmV bfOckzYPRloHJ9vIovVe48hG/MVkYLt95zct0xXE5HuTDL/g60SbIkCGOs19FT4OKGRr Wm0eVu/wZCGBMtNIX7ceN8QtI5HV89oJqhiEoGgfxUIlE/pPQM2RggJR2ZZVu0yaX55V RzXg== X-Gm-Message-State: AFuF++l3ut20nsagx/6qby5bvn27s2H6lP1QtopPCMZ3JNQPTMUxzS7k hlyf1sf8j/yIQkU6LmXoDZiunlsGAlZJeRgjeiZYFAGhqgIYAQBTR98k X-Gm-Gg: AR+sD10XsxGqHsHmijV3vKeFLXgU38mW4Pw5ufzDFv0oTzj2Nq5Drw3jelbpexJWWNG oSKNDKQjsFrc/PA0chRX3+qm2mm+tze1MIM18MupvRErsmx+Y+TRfv6Eyjp2he0JqA0sPt7uABA HFsv2pOedDijQ0nyElwP5RBTSEei1oWaFaYSUALO7NwcK4CCY/O27U3jeATPiWy0qSob+YFIBwc cdFGdWUiES9CaGw24SCnwC8nIbKzn0KVF2Q1WS8ASp2koy6Mf8hn+zwEbDVYWB7hXEJigNGxedj 2MPQBK6hxntAiiD25+qC0YXyuFui5Lichk2jSOyyhnP3yDqM2v141cn0OGEPtx617LDhBW3YupA vHHunFNxSwKh7HwUQvS8PwJ0Bu9hd79MKgkcI9N1cuOCTnlIpJ8UwTASVqAhG8ZVncZjPjZnfZm 2wrsLU42nhAz1szz5c2HrfdFCPosuqujt+TyDitajOzKNt+2BObeUg8Hkw1mv1lUOnjqMo7e1ZK HOZx3r768Z0+q2/kuuUU/1gxTfkprzJXJ66oo/o26VYqFkqweWr8H8acTFWKBGfviuHEU61pvZU GdU4oiJ9UVJdmlE3IFVm8gVpgmRuTBRwN22h18AIu/gORtNs0TkTTQ2ZynyslYs384ROL0I2M9c ik8AmNut/B5EY1TJqL0elsU3Blx2N4A== X-Received: by 2002:a05:6830:490d:b0:7f4:f0af:bf with SMTP id 46e09a7af769-7f4f223702emr38759580a34.3.1788282589305; Tue, 01 Sep 2026 10:09:49 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:48 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:09:03 -0600 Subject: [PATCH v2 09/10] test: dm: cover the shared lwIP runtime MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-9-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org Exercise two clients and UDP PCBs on one netif, address ownership and refresh, reentrant polling, per-client detach and final Ethernet shutdown. Also cover DHCP shutdown, DNS callback cancellation and immediate abort of an established HTTP connection when the corresponding protocols are enabled. Signed-off-by: James Hilliard --- test/dm/Makefile | 3 + test/dm/lwip.c | 375 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 378 insertions(+) diff --git a/test/dm/Makefile b/test/dm/Makefile index fb3e6a7008f..a3e8bb4bc7e 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -49,6 +49,9 @@ obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o obj-$(CONFIG_DM_HASH) += hash.o obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o obj-$(CONFIG_DM_ETH) += eth.o +ifeq ($(CONFIG_NET_LWIP)$(CONFIG_PROT_UDP_LWIP),yy) +obj-y += lwip.o +endif obj-$(CONFIG_EXTCON) += extcon.o ifneq ($(CONFIG_EFI_PARTITION),) obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o diff --git a/test/dm/lwip.c b/test/dm/lwip.c new file mode 100644 index 00000000000..5df8ad138df --- /dev/null +++ b/test/dm/lwip.c @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright 2026 James Hilliard */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if CONFIG_IS_ENABLED(PROT_DNS_LWIP) +#include +#endif +#if CONFIG_IS_ENABLED(PROT_DHCP_LWIP) +#include +#include +#endif +#if CONFIG_IS_ENABLED(WGET) +#include +#include +#endif + +struct lwip_test_eth_hdr { + u8 dst[ARP_HLEN]; + u8 src[ARP_HLEN]; + __be16 type; +} __packed; + +struct lwip_test_recv_ctx { + unsigned int packets; + int nested_poll_ret; +}; + +#if CONFIG_IS_ENABLED(PROT_DNS_LWIP) +struct lwip_test_dns_ctx { + unsigned int callbacks; + bool address_missing; +}; + +static void lwip_test_dns_found(const char *name, const ip_addr_t *ipaddr, + void *arg) +{ + struct lwip_test_dns_ctx *ctx = arg; + + ctx->callbacks++; + ctx->address_missing = !ipaddr; +} +#endif + +#if CONFIG_IS_ENABLED(WGET) +struct lwip_test_http_ctx { + unsigned int callbacks; + httpc_result_t result; +}; + +static void lwip_test_http_result(void *arg, httpc_result_t result, + u32_t rx_content_len, u32_t server_response, + err_t err) +{ + struct lwip_test_http_ctx *ctx = arg; + + ctx->callbacks++; + ctx->result = result; +} + +static err_t lwip_test_http_recv(void *arg, struct altcp_pcb *conn, + struct pbuf *p, err_t err) +{ + if (p) + pbuf_free(p); + + return ERR_OK; +} +#endif + +static void lwip_test_udp_recv(void *arg, struct udp_pcb *pcb, + struct pbuf *p, const ip_addr_t *addr, + u16_t port) +{ + struct lwip_test_recv_ctx *recv_ctx = arg; + + recv_ctx->packets++; + recv_ctx->nested_poll_ret = net_lwip_poll(); + pbuf_free(p); +} + +#if CONFIG_IS_ENABLED(PROT_DHCP_LWIP) +static int lwip_test_dhcp_stop(struct unit_test_state *uts, + struct netif *netif) +{ + struct dhcp *dhcp; + ip4_addr_t address; + int i; + + ip4addr_aton("1.1.2.5", &address); + for (i = 0; i < 2; i++) { + ut_asserteq(ERR_OK, dhcp_start(netif)); + dhcp = netif_dhcp_data(netif); + ut_assertnonnull(dhcp); + dhcp->state = DHCP_STATE_BOUND; + netif_set_ipaddr(netif, &address); + ut_assert(dhcp_supplied_address(netif)); + dhcp_stop_without_release(netif); + ut_assert(ip4_addr_cmp(netif_ip4_addr(netif), &address)); + ut_asserteq(0, dhcp->pcb_allocated); + dhcp_cleanup(netif); + ut_assertnull(netif_dhcp_data(netif)); + ut_assertok(net_lwip_poll()); + } + + return 0; +} +#endif + +static int lwip_test_inject_udp(struct udevice *dev, const char *payload, + struct in_addr src_ip, u16 src_port, + u16 dest_port) +{ + struct eth_sandbox_priv *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_plat(dev); + struct lwip_test_eth_hdr *eth; + unsigned int payload_len = strlen(payload); + unsigned int packet_len; + struct ip_udp_hdr *ip; + + packet_len = sizeof(*eth) + IP_UDP_HDR_SIZE + payload_len; + if (priv->recv_packets >= PKTBUFSRX || packet_len > PKTSIZE_ALIGN) + return -ENOSPC; + + eth = (void *)priv->recv_packet_buffer[priv->recv_packets]; + memcpy(eth->dst, pdata->enetaddr, ARP_HLEN); + memcpy(eth->src, priv->fake_host_hwaddr, ARP_HLEN); + eth->type = htons(PROT_IP); + + ip = (void *)(eth + 1); + memset(ip, 0, IP_UDP_HDR_SIZE); + ip->ip_hl_v = 0x45; + ip->ip_len = htons(IP_UDP_HDR_SIZE + payload_len); + ip->ip_off = htons(IP_FLAGS_DFRAG); + ip->ip_ttl = 64; + ip->ip_p = IPPROTO_UDP; + ip->ip_src = src_ip; + ip->ip_dst = string_to_ip(env_get("ipaddr")); + ip->udp_src = htons(src_port); + ip->udp_dst = htons(dest_port); + ip->udp_len = htons(UDP_HDR_SIZE + payload_len); + ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE); + memcpy(ip + 1, payload, payload_len); + + priv->recv_packet_length[priv->recv_packets] = packet_len; + priv->recv_packets++; + + return 0; +} + +#if CONFIG_IS_ENABLED(PROT_DNS_LWIP) +static int lwip_test_dns_cancel(struct unit_test_state *uts) +{ + struct lwip_test_dns_ctx cancelled = {}; + struct lwip_test_dns_ctx active = {}; + ip_addr_t dns_server; + ip_addr_t result; + int ret; + int i; + + ipaddr_aton("1.1.2.2", &dns_server); + dns_setserver(0, &dns_server); + + ret = dns_gethostbyname("cancel.test", &result, + lwip_test_dns_found, &cancelled); + ut_asserteq(ERR_INPROGRESS, ret); + + /* Start the query so a second request can share it. */ + dns_tmr(); + ut_assertok(net_lwip_poll()); + dns_cancel(lwip_test_dns_found, &cancelled); + + ret = dns_gethostbyname("cancel.test", &result, + lwip_test_dns_found, &active); + ut_asserteq(ERR_INPROGRESS, ret); + + for (i = 0; i < 16; i++) + dns_tmr(); + + ut_asserteq(0, cancelled.callbacks); + ut_asserteq(1, active.callbacks); + ut_assert(active.address_missing); + + return 0; +} +#endif + +#if CONFIG_IS_ENABLED(WGET) +static int lwip_test_http_abort(struct unit_test_state *uts) +{ + struct lwip_test_http_ctx ctx = {}; + httpc_connection_t settings = { + .result_fn = lwip_test_http_result, + }; + httpc_state_t *state = NULL; + ip_addr_t server; + err_t err; +#if CONFIG_IS_ENABLED(PROT_DNS_LWIP) + int i; + + err = httpc_get_file_dns("abort-http.test", HTTP_DEFAULT_PORT, "/", + &settings, lwip_test_http_recv, &ctx, &state); + ut_asserteq(ERR_OK, err); + ut_assertnonnull(state); + ut_asserteq(ERR_OK, httpc_abort(state)); + ut_asserteq(1, ctx.callbacks); + ut_asserteq(HTTPC_RESULT_LOCAL_ABORT, ctx.result); + + /* A later DNS timeout must not call into the freed HTTP state. */ + for (i = 0; i < 16; i++) + dns_tmr(); + ut_asserteq(1, ctx.callbacks); + + ctx = (struct lwip_test_http_ctx){}; + state = NULL; +#endif + ipaddr_aton("1.1.2.2", &server); + err = httpc_get_file(&server, HTTP_DEFAULT_PORT, "/", &settings, + lwip_test_http_recv, &ctx, &state); + ut_asserteq(ERR_OK, err); + ut_assertnonnull(state); + ut_assertnonnull(tcp_active_pcbs); + ut_asserteq(SYN_SENT, tcp_active_pcbs->state); + ut_assertnull(tcp_active_pcbs->next); + + /* An established connection must be removed, not left closing. */ + tcp_active_pcbs->state = ESTABLISHED; + ut_asserteq(ERR_OK, httpc_abort(state)); + ut_asserteq(1, ctx.callbacks); + ut_asserteq(HTTPC_RESULT_LOCAL_ABORT, ctx.result); + ut_assertnull(tcp_active_pcbs); + + return 0; +} +#endif + +static int _dm_test_lwip_runtime(struct unit_test_state *uts, + struct net_lwip_ctx *client_a, + struct net_lwip_ctx *client_b, + struct net_lwip_ctx *no_addr_client, + struct udp_pcb **pcb_a, + struct udp_pcb **pcb_b) +{ + struct lwip_test_recv_ctx recv_a = {}; + struct lwip_test_recv_ctx recv_b = {}; + struct in_addr host = string_to_ip("1.1.2.2"); + ip4_addr_t expected; + + ut_assertok(env_set("ethact", "eth@10002000")); + ut_assertok(env_set("ipaddr", "1.1.2.1")); + ut_assertok(env_set("netmask", "255.255.255.0")); + ut_assertok(env_set("gatewayip", "1.1.2.254")); + + ut_assertok(net_lwip_start(client_a, NET_LWIP_ADDR_ENV_STRICT)); + ut_assertnonnull(client_a->dev); + ut_assertnonnull(client_a->netif); + ut_assert(eth_is_active(client_a->dev)); + ip4addr_aton("1.1.2.1", &expected); + ut_assert(ip4_addr_cmp(netif_ip4_addr(client_a->netif), &expected)); + + ut_assertok(net_lwip_start(client_b, NET_LWIP_ADDR_ENV_FLEXIBLE)); + ut_asserteq_ptr(client_a->dev, client_b->dev); + ut_asserteq_ptr(client_a->netif, client_b->netif); + + /* Strict clients prevent every change to the shared IPv4 address. */ + ut_assertok(env_set("ipaddr", "1.1.2.3")); + ut_asserteq(-EBUSY, net_lwip_refresh(client_b)); + ut_asserteq(-EBUSY, + net_lwip_start(no_addr_client, NET_LWIP_ADDR_NONE)); + ut_assertnull(no_addr_client->dev); + ut_assertnull(no_addr_client->netif); + ip4addr_aton("1.1.2.1", &expected); + ut_assert(ip4_addr_cmp(netif_ip4_addr(client_a->netif), &expected)); + + net_lwip_stop(client_a); + ut_assertok(net_lwip_refresh(client_b)); + ip4addr_aton("1.1.2.3", &expected); + ut_assert(ip4_addr_cmp(netif_ip4_addr(client_b->netif), &expected)); + + ut_assertok(net_lwip_start(no_addr_client, NET_LWIP_ADDR_NONE)); + ut_assert(ip4_addr_isany_val(*netif_ip4_addr(client_b->netif))); + ut_asserteq(-EBUSY, + net_lwip_start(client_a, NET_LWIP_ADDR_NONE)); + ut_assertnull(client_a->dev); + ut_assertnull(client_a->netif); + ut_asserteq(-EBUSY, + net_lwip_start(client_a, NET_LWIP_ADDR_ENV_STRICT)); + ut_assertnull(client_a->dev); + ut_assertnull(client_a->netif); + ut_assertok(env_set("ipaddr", "1.1.2.4")); + ut_assertok(net_lwip_refresh(client_b)); + ut_assert(ip4_addr_isany_val(*netif_ip4_addr(client_b->netif))); +#if CONFIG_IS_ENABLED(PROT_DHCP_LWIP) + ut_assertok(lwip_test_dhcp_stop(uts, no_addr_client->netif)); +#endif + net_lwip_stop(no_addr_client); + ip4addr_aton("1.1.2.4", &expected); + ut_assert(ip4_addr_cmp(netif_ip4_addr(client_b->netif), &expected)); + + ut_assertok(net_lwip_start(client_a, NET_LWIP_ADDR_ENV_STRICT)); + ut_asserteq_ptr(client_a->dev, client_b->dev); + ut_asserteq_ptr(client_a->netif, client_b->netif); +#if CONFIG_IS_ENABLED(PROT_DNS_LWIP) + ut_assertok(lwip_test_dns_cancel(uts)); +#endif +#if CONFIG_IS_ENABLED(WGET) + ut_assertok(lwip_test_http_abort(uts)); +#endif + + *pcb_a = udp_new(); + ut_assertnonnull(*pcb_a); + ut_asserteq(ERR_OK, udp_bind(*pcb_a, IP_ADDR_ANY, 10000)); + udp_recv(*pcb_a, lwip_test_udp_recv, &recv_a); + *pcb_b = udp_new(); + ut_assertnonnull(*pcb_b); + ut_asserteq(ERR_OK, udp_bind(*pcb_b, IP_ADDR_ANY, 10001)); + udp_recv(*pcb_b, lwip_test_udp_recv, &recv_b); + + ut_assertok(lwip_test_inject_udp(client_a->dev, "one", host, + 20000, 10000)); + ut_assertok(net_lwip_poll()); + ut_assertok(lwip_test_inject_udp(client_a->dev, "two", host, + 20001, 10001)); + ut_assertok(net_lwip_poll()); + ut_asserteq(1, recv_a.packets); + ut_asserteq(1, recv_b.packets); + ut_asserteq(-EBUSY, recv_a.nested_poll_ret); + ut_asserteq(-EBUSY, recv_b.nested_poll_ret); + + net_lwip_stop(client_a); + ut_assertnonnull(client_b->netif); + ut_assert(eth_is_active(client_b->dev)); + + return 0; +} + +static int dm_test_lwip_runtime(struct unit_test_state *uts) +{ + struct net_lwip_ctx no_addr_client = {}; + struct net_lwip_ctx client_a = {}; + struct net_lwip_ctx client_b = {}; + struct udp_pcb *pcb_a = NULL; + struct udp_pcb *pcb_b = NULL; + struct udevice *dev; + int ret; + + ret = _dm_test_lwip_runtime(uts, &client_a, &client_b, + &no_addr_client, &pcb_a, &pcb_b); + + if (pcb_b) + udp_remove(pcb_b); + if (pcb_a) + udp_remove(pcb_a); + net_lwip_stop(&no_addr_client); + net_lwip_stop(&client_a); + dev = client_b.dev; + net_lwip_stop(&client_b); + + if (!ret) { + ut_assert(!eth_is_active(dev)); + ut_asserteq(-ENODEV, net_lwip_poll()); + } + + return ret; +} + +DM_TEST(dm_test_lwip_runtime, UTF_SCAN_FDT); From patchwork Tue Sep 1 17:09:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 2296158 X-Patchwork-Delegate: jerome.forissier@linaro.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.u-boot-project.org header.i=@lists.u-boot-project.org header.a=rsa-sha256 header.s=default header.b=l6R/mSBl; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=dX1tWcbr; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.u-boot-project.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZC616WrGz1xwZ for ; Wed, 02 Sep 2026 03:10:01 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 8662580E7E; Tue, 1 Sep 2026 17:10:00 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id uDEKJzzae-FW; Tue, 1 Sep 2026 17:09:58 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1788282598; bh=sGzskRBcBXKOP8B9dY7vQ/tcZRkL+zo46tCLK8FcI6A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=l6R/mSBl1bwDp4mpz48ScbiQ2aNaC1x6Z1rpsDewulpQB4axZGbV30+WImc3og0fd zROGsbhtst5JW/hE+RCU60cfVmmnTwFUQTV+rzq5QMJUpirSYn2FJlMrr8x3G7m7Q9 ONphDl5dxVWy+w4rvQRkdVj8zHB/iuR6b5O5pNU1RYI5hOLpVkgdxQ3ZYDBg7B6OIf oKS3XotXDagqtGhYcWSMJFeq5xpHCU6emO6XLrDi5n1a8H4E3tiFK+AJKNxdOWLK6s STePzzatbB0wpdJBHB75jvb0JT9ALWQv4Hwc3l7GV9plysPlCbdCKvot9Hrl4vRruc FmYmBZPuPGRAQ== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp1.osuosl.org (Postfix) with ESMTP id 83E4580E80; Tue, 1 Sep 2026 17:09:58 +0000 (UTC) X-Original-To: u-boot@lists.u-boot-project.org Delivered-To: u-boot@lists.u-boot-project.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists1.osuosl.org (Postfix) with ESMTP id C5536265 for ; Tue, 1 Sep 2026 17:09:53 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id B7726606F6 for ; Tue, 1 Sep 2026 17:09:53 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id OxtVqbLxr07N for ; Tue, 1 Sep 2026 17:09:52 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::32e; helo=mail-ot1-x32e.google.com; envelope-from=james.hilliard1@gmail.com; receiver= Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp3.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=dX1tWcbr Received: from mail-ot1-x32e.google.com (mail-ot1-x32e.google.com [IPv6:2607:f8b0:4864:20::32e]) by smtp3.osuosl.org (Postfix) with ESMTPS id 4FC1360633 for ; Tue, 1 Sep 2026 17:09:51 +0000 (UTC) Received: by mail-ot1-x32e.google.com with SMTP id 46e09a7af769-7f4df360cc9so59078a34.1 for ; Tue, 01 Sep 2026 10:09:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788282590; x=1788887390; darn=lists.u-boot-project.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=sGzskRBcBXKOP8B9dY7vQ/tcZRkL+zo46tCLK8FcI6A=; b=dX1tWcbrCdenG+byUlLMfHFrUhAO/l+Rpn9Cb7efp6WeWqHlIyfGFeKvExOzCFffd+ P9PL7Z7FBrjDzZzgBrX9ctWMlcFZorAIcAq0OVlhpLgHKdh499+QiP2vGupa06sCPbvP +LS3egBKrQgWE4vxG9QZRrJOAQ6IR5NIAn4xdfDqDBS2KhmcaG0afTF73j1aeg7qbPyJ 3ND8kb35GhobbpsDP1N//pWWclqiglZzZ8ZWbgU+cqLcRb7OxIXfmo2TIyWZE8gkZvgd sboWMzBgJI19t5yFN/lbWT+c8DFiQgozatXTL8euL/Z+ncbqi9ca8LxJkkKzLrGKTtBw 4uVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788282590; x=1788887390; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=sGzskRBcBXKOP8B9dY7vQ/tcZRkL+zo46tCLK8FcI6A=; b=TeICgKl1lL+W6c6vBI/HpCyuAZ15B9OfL89nA0B+MMROQwSDQuGuOq/3WAnBQNZV7R MCKE4VEMwWktzWiagCvcdKFzX8x8/fKKZ2COwl8vyJuqbZrUcF4L7kGerFSXoaNCBHZl sI7jX/wNz5TQ/bWTOtxlX4g84ubsPbU0aSEgZsPYfuYlHKuh1FPYMOQY0cndpComvOkk awDYgcGQvxphAkpCKw1b9kJMP0TnTyDXt8B/CIPpQ7QTgfJk25ToQXCUSB4lZdaVAQeH /p1E3Ig80Ie5bzZB4hMDE2z2t86747JD2oLrR3G6fkvRVdgmZM7emGr9QulDQMvr/zVQ m8gg== X-Gm-Message-State: AFuF++l8K4e5yj2LtOYc63NDY3SKNjC7b13Ryp2BFJN2DQWfUttLkH1e uRs4WMIjjrqM9HaYO+I6hvUEq5uESWsrF4/pl9ra4yI45+S+nPr2xsKF X-Gm-Gg: AR+sD13QIIlDciTzRA5fNYbV9kCfhOIH5DkiVU/mnRbGPdRHtLQx7I1LpkYi2WZ2Z20 PLw8F9mdW3u9Hh4Gf7yB59BCMHjXXdtkoT6qykdR/zV+eCH9wD17eLyzAY3W8WslJ+EbnDadvzV TIinpFSLdRxDMAYv4t1Ca1WXunlNb3LskSa8/9mRPwBUIi1ythUUuIj9OTVDGfVzW4c+zKSEtdQ XhNuwo/KEuFQaDrOqrioFocROKYaV6seWGQHcXgQYutFCBgVToRY/HBzCvw5Pg7S9CxLSE/zZOX fVWhj+kwQILgzP2c2+bCLVoR++pE5RyUq/HcZAFCwwzSXF3OxglZSGkJ8unyCJW3aip2fXTBHGh M9j2+MZ1plWIAlO7MQivrwlp8oNglaMOD5fiyzIzDzG0PD3COx+dUsloO2cZ3GgP4BdhmO9u1h0 oYyXlELKqOuLigcd7xtXZtfeu1yYD/HM6JJRej8FULjpVQ46dIQWZsTaUJukzB16akU3WjZQZ+x zz59OezeMuS/8C6z0TXTf9QlXfdzPUgQTRMlWobkU447gZAV7Ii9oA+JRYAXJwH9rPJj/hy4G9k Dp7NSOsFSyUXfDyBR8uPf4VgTQyoZfQhCh65z/OvUmwG95j3joCigv9edhd6PUW31AXnHeE8fEA IbRcwkrGB4QdLzk4hw/4wJWfn4tdyfg== X-Received: by 2002:a05:6830:83a1:b0:7dc:e78b:158 with SMTP id 46e09a7af769-7f68f60b62bmr6386186a34.4.1788282590435; Tue, 01 Sep 2026 10:09:50 -0700 (PDT) Received: from [127.0.1.1] (184-96-151-165.hlrn.qwest.net. [184.96.151.165]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4fa99d927sm10892218a34.19.2026.09.01.10.09.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2026 10:09:50 -0700 (PDT) From: James Hilliard Date: Tue, 01 Sep 2026 11:09:04 -0600 Subject: [PATCH v2 10/10] net: netconsole: add an lwIP transport MIME-Version: 1.0 Message-Id: <20260901-submit-lwip-runtime-netconsole-v1-v2-10-3e3d95627cf9@gmail.com> References: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> In-Reply-To: <20260901-submit-lwip-runtime-netconsole-v1-v2-0-3e3d95627cf9@gmail.com> To: u-boot@lists.u-boot-project.org, Jerome Forissier , Sughosh Ganu Cc: James Hilliard , Tom Rini , Heinrich Schuchardt , David Lechner , Julien Stephan , Naveen Kumar Chaudhary , Luca Jones , Weijie Gao , Pranav Tilak , Simon Glass , Vincent Jardin , Quentin Schulz , "Lucien.Jheng" , Mateusz Furdyna X-Mailer: b4 0.15.2 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org Register netconsole as a UDP client of the shared lwIP runtime. This keeps its PCB active while foreground network commands run, so their polling also services console input and output. Refresh addressing and port settings when the environment changes, and wait for ARP resolution when output is sent outside an active poll. A nested send from a protocol callback leaves the packet queued for the outer poll instead of recursing. Add sandbox coverage for input, output, runtime sharing, nested callback output and setting changes. Signed-off-by: James Hilliard --- drivers/net/Makefile | 1 + drivers/net/netconsole-lwip.c | 200 ++++++++++++++++++++++++ drivers/net/netconsole.c | 3 +- net/Kconfig | 13 +- test/dm/Makefile | 3 + test/dm/netconsole.c | 344 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 557 insertions(+), 7 deletions(-) diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 32bf86e14ae..96ec6fb187a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_MVPP2) += mvpp2.o ifdef CONFIG_NETCONSOLE obj-y += netconsole.o obj-$(CONFIG_NET_LEGACY) += netconsole-legacy.o +obj-$(CONFIG_NET_LWIP) += netconsole-lwip.o endif obj-$(CONFIG_NET_NPCM750) += npcm750_eth.o obj-$(CONFIG_NET_OCTEON) += octeon/ diff --git a/drivers/net/netconsole-lwip.c b/drivers/net/netconsole-lwip.c new file mode 100644 index 00000000000..af2d591610e --- /dev/null +++ b/drivers/net/netconsole-lwip.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright 2026 James Hilliard */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "netconsole.h" + +#define NC_ARP_TIMEOUT_MS 5000 + +static struct net_lwip_ctx nc_net; +static struct udp_pcb *nc_pcb; +static unsigned int nc_users; +static int nc_env_id = -1; + +static void nc_lwip_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, + const ip_addr_t *addr, u16_t port) +{ + struct in_addr src_ip = { + .s_addr = ip_addr_get_ip4_u32(addr), + }; + struct pbuf *q; + + for (q = p; q; q = q->next) + nc_input_packet(q->payload, src_ip, pcb->local_port, port, + q->len); + + pbuf_free(p); +} + +static int nc_lwip_refresh(void) +{ + struct udp_pcb *pcb; + int env_id; + err_t err; + int ret; + + env_id = env_get_id(); + ret = nc_refresh_settings_from_env(); + if (ret < 0) + return ret; + + if (env_id != nc_env_id) { + ret = net_lwip_refresh(&nc_net); + if (ret) + return ret; + nc_env_id = env_id; + } + + if (nc_pcb && nc_pcb->local_port == nc_settings.in_port) + return 0; + + pcb = udp_new(); + if (!pcb) + return -ENOMEM; + + err = udp_bind(pcb, IP_ADDR_ANY, nc_settings.in_port); + if (err != ERR_OK) { + udp_remove(pcb); + return err; + } + + ip_set_option(pcb, SOF_BROADCAST); + udp_recv(pcb, nc_lwip_recv, NULL); + if (nc_pcb) + udp_remove(nc_pcb); + nc_pcb = pcb; + + return 0; +} + +static bool nc_lwip_arp_target(const ip4_addr_t *dest, ip4_addr_t *target) +{ + struct netif *netif = nc_net.netif; + + if (ip4_addr_isbroadcast(dest, netif) || ip4_addr_ismulticast(dest)) + return false; + + ip4_addr_copy(*target, *dest); + if (ip4_addr_net_eq(dest, netif_ip4_addr(netif), + netif_ip4_netmask(netif)) || + ip4_addr_islinklocal(dest)) + return true; + + if (ip4_addr_isany_val(*netif_ip4_gw(netif))) + return false; + ip4_addr_copy(*target, *netif_ip4_gw(netif)); + + return true; +} + +static void nc_lwip_wait_for_arp(const ip4_addr_t *target) +{ + const ip4_addr_t *ip_ret; + struct eth_addr *eth_ret; + ulong start; + + if (etharp_find_addr(nc_net.netif, target, ð_ret, &ip_ret) >= 0) + return; + + start = get_timer(0); + while (get_timer(start) < NC_ARP_TIMEOUT_MS) { + if (net_lwip_poll() < 0) + return; + if (etharp_find_addr(nc_net.netif, target, ð_ret, + &ip_ret) >= 0) + return; + } +} + +int nc_transport_start(void) +{ + int ret; + + if (nc_users) { + ret = nc_lwip_refresh(); + if (!ret) + nc_users++; + + return ret; + } + + ret = net_lwip_start(&nc_net, NET_LWIP_ADDR_ENV_FLEXIBLE); + if (ret) + return ret; + + ret = nc_lwip_refresh(); + if (ret) { + net_lwip_stop(&nc_net); + return ret; + } + + nc_users = 1; + + return 0; +} + +int nc_transport_stop(void) +{ + if (!nc_users) + return 0; + if (--nc_users) + return 0; + + if (nc_pcb) { + udp_remove(nc_pcb); + nc_pcb = NULL; + } + + net_lwip_stop(&nc_net); + nc_env_id = -1; + + return 0; +} + +void nc_transport_send(const char *buf, int len) +{ + ip4_addr_t arp_target; + ip_addr_t dest; + struct pbuf *p; + err_t err; + + if (!nc_users || nc_lwip_refresh()) + return; + + p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (!p) + return; + + err = pbuf_take(p, buf, len); + if (err != ERR_OK) + goto out; + + ip_addr_set_ip4_u32(&dest, nc_settings.ip.s_addr); + err = udp_sendto_if(nc_pcb, p, &dest, nc_settings.out_port, + nc_net.netif); + if (err == ERR_OK && + nc_lwip_arp_target(ip_2_ip4(&dest), &arp_target)) + nc_lwip_wait_for_arp(&arp_target); + +out: + pbuf_free(p); +} + +void nc_transport_poll(bool block) +{ + if (!nc_users || nc_lwip_refresh()) + return; + + do { + if (net_lwip_poll() < 0) + return; + } while (block && !nc_has_input()); +} diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 63b92e12bf4..0a9ca1400a6 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -113,7 +113,8 @@ int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, !nc_is_broadcast(nc_settings.ip)) return 0; /* not from our client */ - debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); + debug_cond(DEBUG_NET_PKT_TRACE, "input: \"%*.*s\"\n", len, len, + pkt); if (input_size == sizeof(input_buffer)) return 1; /* no space */ diff --git a/net/Kconfig b/net/Kconfig index 386376ce884..02b6e0de21e 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -39,6 +39,13 @@ config NET_LWIP endchoice +config NETCONSOLE + bool "NetConsole support" + select PROT_UDP_LWIP if NET_LWIP + help + Support the 'nc' input/output device for networked console. + See doc/usage/netconsole.rst for details. + if NET_LEGACY config ARP_TIMEOUT @@ -68,12 +75,6 @@ config BOOTP_SEND_HOSTNAME of the "hostname" environment variable is passed as option 12 to the DHCP server. -config NETCONSOLE - bool "NetConsole support" - help - Support the 'nc' input/output device for networked console. - See doc/usage/netconsole.rst for details. - config IP_DEFRAG bool "Support IP datagram reassembly" help diff --git a/test/dm/Makefile b/test/dm/Makefile index a3e8bb4bc7e..6e7b8173260 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -52,6 +52,9 @@ obj-$(CONFIG_DM_ETH) += eth.o ifeq ($(CONFIG_NET_LWIP)$(CONFIG_PROT_UDP_LWIP),yy) obj-y += lwip.o endif +ifeq ($(CONFIG_NET_LWIP)$(CONFIG_NETCONSOLE),yy) +obj-y += netconsole.o +endif obj-$(CONFIG_EXTCON) += extcon.o ifneq ($(CONFIG_EFI_PARTITION),) obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o diff --git a/test/dm/netconsole.c b/test/dm/netconsole.c new file mode 100644 index 00000000000..447965ac912 --- /dev/null +++ b/test/dm/netconsole.c @@ -0,0 +1,344 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright 2026 James Hilliard */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NC_TEST_MAX_OUTPUTS 8 +#define NC_TEST_MAX_PAYLOAD 32 +#define NC_TEST_SERVICE_PORT 12000 + +struct nc_test_eth_hdr { + u8 dst[ARP_HLEN]; + u8 src[ARP_HLEN]; + __be16 type; +} __packed; + +struct nc_test_output { + struct in_addr src_ip; + struct in_addr dest_ip; + u16 src_port; + u16 dest_port; + char payload[NC_TEST_MAX_PAYLOAD]; + unsigned int len; +}; + +struct nc_test_context { + struct nc_test_output output[NC_TEST_MAX_OUTPUTS]; + unsigned int output_count; + int error; +}; + +struct nc_test_service_context { + struct stdio_dev *nc; + const char *message; + unsigned int packets; + int nested_poll_ret; +}; + +static int nc_test_tx_handler(struct udevice *dev, void *packet, + unsigned int len) +{ + struct eth_sandbox_priv *priv = dev_get_priv(dev); + struct nc_test_context *context = priv->priv; + struct nc_test_eth_hdr *eth = packet; + struct nc_test_output *output; + struct ip_udp_hdr *ip; + unsigned int payload_len; + + if (!sandbox_eth_arp_req_to_reply(dev, packet, len)) + return 0; + if (!sandbox_eth_ping_req_to_reply(dev, packet, len)) + return 0; + + if (len < sizeof(*eth) || ntohs(eth->type) != PROT_IP) + return 0; + if (len < sizeof(*eth) + IP_UDP_HDR_SIZE) { + context->error = -EINVAL; + return 0; + } + + ip = (void *)(eth + 1); + if (ip->ip_p != IPPROTO_UDP) + return 0; + if (ntohs(ip->udp_len) < UDP_HDR_SIZE || + ntohs(ip->udp_len) > len - sizeof(*eth) - IP_HDR_SIZE) { + context->error = -EINVAL; + return 0; + } + + payload_len = ntohs(ip->udp_len) - UDP_HDR_SIZE; + if (context->output_count == NC_TEST_MAX_OUTPUTS || + payload_len > NC_TEST_MAX_PAYLOAD) { + context->error = -ENOSPC; + return 0; + } + + output = &context->output[context->output_count++]; + output->src_ip = ip->ip_src; + output->dest_ip = ip->ip_dst; + output->src_port = ntohs(ip->udp_src); + output->dest_port = ntohs(ip->udp_dst); + output->len = payload_len; + memcpy(output->payload, ip + 1, payload_len); + + return 0; +} + +static int nc_test_inject(struct udevice *dev, const char *payload, + struct in_addr src_ip, struct in_addr dest_ip, + u16 src_port, u16 dest_port) +{ + struct eth_sandbox_priv *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_plat(dev); + struct nc_test_eth_hdr *eth; + struct ip_udp_hdr *ip; + unsigned int payload_len = strlen(payload); + unsigned int packet_len; + + packet_len = sizeof(*eth) + IP_UDP_HDR_SIZE + payload_len; + if (priv->recv_packets >= PKTBUFSRX || packet_len > PKTSIZE_ALIGN) + return -ENOSPC; + + eth = (void *)priv->recv_packet_buffer[priv->recv_packets]; + if (dest_ip.s_addr == (u32)~0) + memset(eth->dst, 0xff, ARP_HLEN); + else + memcpy(eth->dst, pdata->enetaddr, ARP_HLEN); + memcpy(eth->src, priv->fake_host_hwaddr, ARP_HLEN); + eth->type = htons(PROT_IP); + + ip = (void *)(eth + 1); + memset(ip, 0, IP_UDP_HDR_SIZE); + ip->ip_hl_v = 0x45; + ip->ip_len = htons(IP_UDP_HDR_SIZE + payload_len); + ip->ip_off = htons(IP_FLAGS_DFRAG); + ip->ip_ttl = 64; + ip->ip_p = IPPROTO_UDP; + ip->ip_src = src_ip; + ip->ip_dst = dest_ip; + ip->udp_src = htons(src_port); + ip->udp_dst = htons(dest_port); + ip->udp_len = htons(UDP_HDR_SIZE + payload_len); + ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE); + memcpy(ip + 1, payload, payload_len); + + priv->recv_packet_length[priv->recv_packets] = packet_len; + priv->recv_packets++; + + return 0; +} + +static void nc_test_service_recv(void *arg, struct udp_pcb *pcb, + struct pbuf *p, const ip_addr_t *addr, + u16_t port) +{ + struct nc_test_service_context *context = arg; + + context->packets++; + context->nc->puts(context->nc, context->message); + context->nested_poll_ret = net_lwip_poll(); + pbuf_free(p); +} + +static int nc_test_check_output(struct unit_test_state *uts, + struct nc_test_context *context, + unsigned int index, const char *payload, + const char *dest_ip, u16 src_port, + u16 dest_port) +{ + struct nc_test_output *output; + + ut_asserteq(0, context->error); + ut_assert(index < context->output_count); + output = &context->output[index]; + ut_asserteq(strlen(payload), output->len); + ut_asserteq_mem(payload, output->payload, output->len); + ut_asserteq(string_to_ip("1.1.2.1").s_addr, + output->src_ip.s_addr); + ut_asserteq(string_to_ip(dest_ip).s_addr, output->dest_ip.s_addr); + ut_asserteq(src_port, output->src_port); + ut_asserteq(dest_port, output->dest_port); + + return 0; +} + +static int nc_test_read_input(struct unit_test_state *uts, + struct stdio_dev *nc, const char *expected) +{ + unsigned int i; + + ut_assert(nc->tstc(nc)); + for (i = 0; expected[i]; i++) + ut_asserteq(expected[i], nc->getc(nc)); + ut_assert(!nc->tstc(nc)); + + return 0; +} + +static int _dm_test_lwip_netconsole(struct unit_test_state *uts, + struct stdio_dev *nc, + struct udevice *dev, + struct nc_test_context *context, + struct net_lwip_ctx *service_net, + struct udp_pcb **service_pcb) +{ + static const char output[] = "netconsole output"; + static const char input[] = "netconsole input"; + static const char broadcast_output[] = "broadcast output"; + static const char broadcast_input[] = "broadcast input"; + static const char after_ping[] = "after ping"; + static const char from_service[] = "from service"; + static const char after_service[] = "after service"; + static const char changed_input[] = "changed input"; + static const char default_output[] = "default output"; + static const char default_input[] = "default input"; + struct nc_test_service_context service = { + .nc = nc, + .message = from_service, + }; + struct in_addr host = string_to_ip("1.1.2.2"); + unsigned int outputs; + + ut_assertok(env_set("ethact", "eth@10002000")); + ut_assertok(env_set("ipaddr", "1.1.2.1")); + ut_assertok(env_set("netmask", "255.255.255.0")); + ut_assertok(env_set("ncinport", "40000")); + ut_assertok(env_set("ncoutport", "40001")); + + ut_assertok(nc->start(nc)); + ut_assertok(nc->start(nc)); + nc->stop(nc); + nc->puts(nc, broadcast_output); + ut_asserteq(1, context->output_count); + ut_assertok(nc_test_check_output(uts, context, 0, broadcast_output, + "255.255.255.255", 40000, 40001)); + ut_assertok(nc_test_inject(dev, broadcast_input, host, + string_to_ip("255.255.255.255"), 40001, + 40000)); + ut_assertok(nc_test_read_input(uts, nc, broadcast_input)); + outputs = 1; + + ut_assertok(env_set("ncip", "1.1.2.2")); + nc->puts(nc, output); + ut_asserteq(++outputs, context->output_count); + ut_assertok(nc_test_check_output(uts, context, outputs - 1, output, + "1.1.2.2", 40000, 40001)); + + ut_assertok(nc_test_inject(dev, input, host, + string_to_ip("1.1.2.1"), 40001, 40000)); + ut_assertok(nc_test_read_input(uts, nc, input)); + + if (IS_ENABLED(CONFIG_CMD_PING)) { + static char *const ping_argv[] = { "ping", "1.1.2.2" }; + + /* A foreground command shares the netif with netconsole. */ + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(ping_argv), ping_argv)); + nc->puts(nc, after_ping); + ut_asserteq(++outputs, context->output_count); + ut_assertok(nc_test_check_output(uts, context, outputs - 1, + after_ping, + "1.1.2.2", 40000, 40001)); + } + + /* Model an independent server protocol attached to the same runtime. */ + ut_assertok(net_lwip_start(service_net, + NET_LWIP_ADDR_ENV_STRICT)); + *service_pcb = udp_new(); + ut_assertnonnull(*service_pcb); + ut_asserteq(ERR_OK, udp_bind(*service_pcb, IP_ADDR_ANY, + NC_TEST_SERVICE_PORT)); + udp_recv(*service_pcb, nc_test_service_recv, &service); + + /* + * Change to an uncached peer before entering the service callback. The + * callback's netconsole output starts ARP resolution. The outer runtime + * poll must receive the reply and flush the queued datagram without a + * recursive poll. + */ + ut_assertok(env_set("ncip", "1.1.2.3")); + ut_assertok(env_set("ncinport", "50000")); + ut_assertok(env_set("ncoutport", "50001")); + ut_assertok(nc_test_inject(dev, "request", host, + string_to_ip("1.1.2.1"), 13000, + NC_TEST_SERVICE_PORT)); + ut_assertok(net_lwip_poll()); + ut_asserteq(1, service.packets); + ut_asserteq(-EBUSY, service.nested_poll_ret); + ut_asserteq(++outputs, context->output_count); + ut_assertok(nc_test_check_output(uts, context, outputs - 1, + from_service, + "1.1.2.3", 50000, 50001)); + + nc->puts(nc, after_service); + ut_asserteq(++outputs, context->output_count); + ut_assertok(nc_test_check_output(uts, context, outputs - 1, + after_service, + "1.1.2.3", 50000, 50001)); + + ut_assertok(nc_test_inject(dev, changed_input, + string_to_ip("1.1.2.3"), + string_to_ip("1.1.2.1"), 50001, 50000)); + ut_assertok(nc_test_read_input(uts, nc, changed_input)); + + ut_assertok(env_set("ncip", NULL)); + ut_assertok(env_set("ncinport", NULL)); + ut_assertok(env_set("ncoutport", NULL)); + nc->puts(nc, default_output); + ut_asserteq(++outputs, context->output_count); + ut_assertok(nc_test_check_output(uts, context, outputs - 1, + default_output, "255.255.255.255", + 6666, 6666)); + ut_assertok(nc_test_inject(dev, default_input, host, + string_to_ip("255.255.255.255"), 6666, + 6666)); + ut_assertok(nc_test_read_input(uts, nc, default_input)); + + return 0; +} + +static int dm_test_lwip_netconsole(struct unit_test_state *uts) +{ + struct nc_test_context context = {}; + struct net_lwip_ctx service_net = {}; + struct udp_pcb *service_pcb = NULL; + struct stdio_dev *nc; + struct udevice *dev; + int ret; + + nc = stdio_get_by_name("nc"); + ut_assertnonnull(nc); + ut_assertnonnull(nc->stop); + ut_assertok(uclass_get_device_by_name(UCLASS_ETH, "eth@10002000", + &dev)); + + sandbox_eth_set_tx_handler(0, nc_test_tx_handler); + sandbox_eth_set_priv(0, &context); + ret = _dm_test_lwip_netconsole(uts, nc, dev, &context, &service_net, + &service_pcb); + if (service_pcb) + udp_remove(service_pcb); + net_lwip_stop(&service_net); + nc->stop(nc); + sandbox_eth_set_tx_handler(0, NULL); + sandbox_eth_set_priv(0, NULL); + + env_set("ethact", NULL); + env_set("ipaddr", "192.0.2.1"); + env_set("netmask", NULL); + env_set("ncip", NULL); + env_set("ncinport", NULL); + env_set("ncoutport", NULL); + + return ret; +} + +DM_TEST(dm_test_lwip_netconsole, UTF_SCAN_FDT);