From patchwork Wed Apr 12 18:49:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1768515 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=QW2eVxFR; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Py2jD26Zwz1yZZ for ; Fri, 14 Apr 2023 00:56:46 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B37E480B98; Thu, 13 Apr 2023 16:56:37 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="QW2eVxFR"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id ABBAA85FB2; Wed, 12 Apr 2023 20:49:43 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CF5CE83741 for ; Wed, 12 Apr 2023 20:49:39 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=3Qv02ZAkKBkEglprulqq1jrrjoh.frpx-errwolvwv.ghq0.gh@flex--dimorinny.bounces.google.com Received: by mail-yb1-xb4a.google.com with SMTP id y4-20020a253204000000b00b392ae70300so13380849yby.21 for ; Wed, 12 Apr 2023 11:49:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1681325378; x=1683917378; h=content-transfer-encoding:cc:to:from:subject:message-id :mime-version:date:from:to:cc:subject:date:message-id:reply-to; bh=NkUzlB5Zm93GokjYxZCbpxtI1RAfFzitZtHqYrwx6c4=; b=QW2eVxFRzSUSgl35vwe7n0YR+2Z9V3kg24tauyURP1eLrSzK5KWwJiY2O0dFtmrLVm Yae0Fb/xIUpvE/IRorIn40jutyDePuJVLP+tCDwC+zkiEAZBXLRD6O3aWgFEbRBfkV30 U7SiK+MO54ruh8S/ETWJnyaVVj8qXmjGt+uh+bXRSxAq0WFncsdJUPst3x12kLEm00Lz QO3Hc0U9bdOOZYd4IvCFjjxbljSUfKPvA4z+As0T3X/csV3qoKy6OpaIzwYcshRD2dmz wZMBAy65AUVaeFxdAvKLaKwTzoQU49s13/JFTLOf6DODmQce78UyfpBUZqOv2TJfdvw3 bDrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681325378; x=1683917378; h=content-transfer-encoding:cc:to:from:subject:message-id :mime-version:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=NkUzlB5Zm93GokjYxZCbpxtI1RAfFzitZtHqYrwx6c4=; b=WT4PFLOF9Efcl9d6lk2Y1mYFGaq3w98AgfHCcyTO27PJx/a1uoyJpDVBnhskzHOjFU dKYAUTD1Dwhyu4aM3P+2Hdg3jVMs12vlp7iazYWUcxVugU66PY1omOlaoOT3aKirh7LT fZj2U5JjyeLB94MubcPFZ/IDn9d2qeLmbhzuKJpzczMvlyrSK1L1DAStx4g+/rUkmQy+ tzGiqGMe0Bngn74Rsvb9D1MvdzDqjkJP3uP18Eaz31AwnpTSQoufxHfePCtTAO6mhRYU Qr+BSZpSFBV5gDHQozVJkRtkV4L+oUQC2mv9jPUROWQG4z6zu07PQrIQ140Sa6C9zYSk I7Gw== X-Gm-Message-State: AAQBX9fkDgkfOvUDJdcrLqMXhw3yFLSt7mZ/0Pgr5DMt5kE6ggcPr7Yq m/i85NAroLl1N7OyRujNk/+5orfXQcLe4rmeb4+S9GB0ZoE0JO+cLu0YONmFJVUuji+jnOyc/IF yGa90SX4RspnfZwVhKdv5Pba76/qXqwK0LDtPOFsxxivb0rD5A5RDmHPajQ1SAeJXqSg= X-Google-Smtp-Source: AKy350a0KdhMtlyHXBsHiUNxwaZwnhMNQwkSeMuOgYmDnflfVaS+QylbW3XnHer9Kqe3bNQe5R+rdis3DgRwxys= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:7766:76f9:f832:5b94]) (user=dimorinny job=sendgmr) by 2002:a05:690c:730:b0:54f:899f:890f with SMTP id bt16-20020a05690c073000b0054f899f890fmr2626652ywb.9.1681325378484; Wed, 12 Apr 2023 11:49:38 -0700 (PDT) Date: Wed, 12 Apr 2023 19:49:29 +0100 Mime-Version: 1.0 X-Mailer: git-send-email 2.40.0.634.g4ca3ef3211-goog Message-ID: <20230412184931.1422789-1-dimorinny@google.com> Subject: [PATCH v2 1/3] net: support being a TCP server to unblock TCP fastboot From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: Dmitrii Merkurev , Ying-Chun Liu , Simon Glass , Ramon Fried X-Mailman-Approved-At: Thu, 13 Apr 2023 16:56:35 +0200 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Make following changes to unblock TCP fastboot support: 1. Implement being a TCP server support 2. Introduce dedicated TCP traffic handler (get rid of UDP signature) 3. Ensure seq_num and ack_num are respected in net_send_tcp_packet function (make sure existing wget_cmd code is reflected with the fix) Signed-off-by: Dmitrii Merkurev Cc: Ying-Chun Liu (PaulLiu) Cc: Simon Glass Сс: Joe Hershberger Сс: Ramon Fried Reviewed-by: Ying-Chun Liu (PaulLiu) Reviewed-by: Simon Glass Reviewed-by: Ramon Fried --- include/net/tcp.h | 16 +++++-- net/tcp.c | 115 +++++++++++++++++++++++----------------------- net/wget.c | 43 ++++++++--------- 3 files changed, 90 insertions(+), 84 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 322551694f..c29d4ce24a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -259,6 +259,7 @@ union tcp_build_pkt { * enum tcp_state - TCP State machine states for connection * @TCP_CLOSED: Need to send SYN to connect * @TCP_SYN_SENT: Trying to connect, waiting for SYN ACK + * @TCP_SYN_RECEIVED: Initial SYN received, waiting for ACK * @TCP_ESTABLISHED: both server & client have a connection * @TCP_CLOSE_WAIT: Rec FIN, passed to app for FIN, ACK rsp * @TCP_CLOSING: Rec FIN, sent FIN, ACK waiting for ACK @@ -268,6 +269,7 @@ union tcp_build_pkt { enum tcp_state { TCP_CLOSED, TCP_SYN_SENT, + TCP_SYN_RECEIVED, TCP_ESTABLISHED, TCP_CLOSE_WAIT, TCP_CLOSING, @@ -283,14 +285,18 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, /** * rxhand_tcp() - An incoming packet handler. * @pkt: pointer to the application packet - * @dport: destination UDP port + * @dport: destination TCP port * @sip: source IP address - * @sport: source UDP port + * @sport: source TCP port + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * @action: TCP action (SYN, ACK, FIN, etc) * @len: packet length */ -typedef void rxhand_tcp(uchar *pkt, unsigned int dport, - struct in_addr sip, unsigned int sport, - unsigned int len); +typedef void rxhand_tcp(uchar *pkt, u16 dport, + struct in_addr sip, u16 sport, + u32 tcp_seq_num, u32 tcp_ack_num, + u8 action, unsigned int len); void tcp_set_tcp_handler(rxhand_tcp *f); void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int len); diff --git a/net/tcp.c b/net/tcp.c index 8d338c72e8..a713e1dd60 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -36,7 +36,6 @@ static u32 rmt_timestamp; static u32 tcp_seq_init; static u32 tcp_ack_edge; -static u32 tcp_seq_max; static int tcp_activity_count; @@ -90,9 +89,10 @@ void tcp_set_tcp_state(enum tcp_state new_state) current_tcp_state = new_state; } -static void dummy_handler(uchar *pkt, unsigned int dport, - struct in_addr sip, unsigned int sport, - unsigned int len) +static void dummy_handler(uchar *pkt, u16 dport, + struct in_addr sip, u16 sport, + u32 tcp_seq_num, u32 tcp_ack_num, + u8 action, unsigned int len) { } @@ -256,7 +256,7 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, switch (action) { case TCP_SYN: debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:SYN (%pI4, %pI4, sq=%d, ak=%d)\n", + "TCP Hdr:SYN (%pI4, %pI4, sq=%u, ak=%u)\n", &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); tcp_activity_count = 0; @@ -271,41 +271,46 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, current_tcp_state = TCP_SYN_SENT; } break; + case TCP_SYN | TCP_ACK: case TCP_ACK: pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); b->ip.hdr.tcp_flags = action; debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:ACK (%pI4, %pI4, s=%d, a=%d, A=%x)\n", + "TCP Hdr:ACK (%pI4, %pI4, s=%u, a=%u, A=%x)\n", &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num, action); break; case TCP_FIN: debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:FIN (%pI4, %pI4, s=%d, a=%d)\n", + "TCP Hdr:FIN (%pI4, %pI4, s=%u, a=%u)\n", &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); payload_len = 0; pkt_hdr_len = IP_TCP_HDR_SIZE; current_tcp_state = TCP_FIN_WAIT_1; break; - + case TCP_RST | TCP_ACK: + case TCP_RST: + debug_cond(DEBUG_DEV_PKT, + "TCP Hdr:RST (%pI4, %pI4, s=%u, a=%u)\n", + &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); + current_tcp_state = TCP_CLOSED; + break; /* Notify connection closing */ - case (TCP_FIN | TCP_ACK): case (TCP_FIN | TCP_ACK | TCP_PUSH): if (current_tcp_state == TCP_CLOSE_WAIT) current_tcp_state = TCP_CLOSING; - tcp_ack_edge++; debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%d, a=%d, A=%x)\n", + "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", &net_server_ip, &net_ip, - tcp_seq_num, tcp_ack_edge, action); + tcp_seq_num, tcp_ack_num, action); fallthrough; default: pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); b->ip.hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:dft (%pI4, %pI4, s=%d, a=%d, A=%x)\n", + "TCP Hdr:dft (%pI4, %pI4, s=%u, a=%u, A=%x)\n", &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num, action); } @@ -313,12 +318,12 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, pkt_len = pkt_hdr_len + payload_len; tcp_len = pkt_len - IP_HDR_SIZE; + tcp_ack_edge = tcp_ack_num; /* TCP Header */ b->ip.hdr.tcp_ack = htonl(tcp_ack_edge); b->ip.hdr.tcp_src = htons(sport); b->ip.hdr.tcp_dst = htons(dport); b->ip.hdr.tcp_seq = htonl(tcp_seq_num); - tcp_seq_num = tcp_seq_num + payload_len; /* * TCP window size - TCP header variable tcp_win. @@ -353,9 +358,8 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, * tcp_hole() - Selective Acknowledgment (Essential for fast stream transfer) * @tcp_seq_num: TCP sequence start number * @len: the length of sequence numbers - * @tcp_seq_max: maximum of sequence numbers */ -void tcp_hole(u32 tcp_seq_num, u32 len, u32 tcp_seq_max) +void tcp_hole(u32 tcp_seq_num, u32 len) { u32 idx_sack, sack_in; u32 sack_end = TCP_SACK - 1; @@ -496,7 +500,7 @@ void tcp_parse_options(uchar *o, int o_len) } } -static u8 tcp_state_machine(u8 tcp_flags, u32 *tcp_seq_num, int payload_len) +static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) { u8 tcp_fin = tcp_flags & TCP_FIN; u8 tcp_syn = tcp_flags & TCP_SYN; @@ -527,46 +531,44 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 *tcp_seq_num, int payload_len) switch (current_tcp_state) { case TCP_CLOSED: debug_cond(DEBUG_INT_STATE, "TCP CLOSED %x\n", tcp_flags); - if (tcp_ack) - action = TCP_DATA; - else if (tcp_syn) - action = TCP_RST; - else if (tcp_fin) + if (tcp_syn) { + action = TCP_SYN | TCP_ACK; + tcp_seq_init = tcp_seq_num; + tcp_ack_edge = tcp_seq_num + 1; + current_tcp_state = TCP_SYN_RECEIVED; + } else if (tcp_ack || tcp_fin) { action = TCP_DATA; + } break; + case TCP_SYN_RECEIVED: case TCP_SYN_SENT: - debug_cond(DEBUG_INT_STATE, "TCP_SYN_SENT %x, %d\n", - tcp_flags, *tcp_seq_num); + debug_cond(DEBUG_INT_STATE, "TCP_SYN_SENT | TCP_SYN_RECEIVED %x, %u\n", + tcp_flags, tcp_seq_num); if (tcp_fin) { action = action | TCP_PUSH; current_tcp_state = TCP_CLOSE_WAIT; - } - if (tcp_syn) { - action = action | TCP_ACK | TCP_PUSH; - if (tcp_ack) { - tcp_seq_init = *tcp_seq_num; - *tcp_seq_num = *tcp_seq_num + 1; - tcp_seq_max = *tcp_seq_num; - tcp_ack_edge = *tcp_seq_num; - sack_idx = 0; - edge_a[sack_idx].se.l = *tcp_seq_num; - edge_a[sack_idx].se.r = *tcp_seq_num; - prev_len = 0; - current_tcp_state = TCP_ESTABLISHED; - for (i = 0; i < TCP_SACK; i++) - edge_a[i].st = NOPKT; - } - } else if (tcp_ack) { + } else if (tcp_ack || (tcp_syn && tcp_ack)) { + action |= TCP_ACK; + tcp_seq_init = tcp_seq_num; + tcp_ack_edge = tcp_seq_num + 1; + sack_idx = 0; + edge_a[sack_idx].se.l = tcp_ack_edge; + edge_a[sack_idx].se.r = tcp_ack_edge; + prev_len = 0; + current_tcp_state = TCP_ESTABLISHED; + for (i = 0; i < TCP_SACK; i++) + edge_a[i].st = NOPKT; + + if (tcp_syn && tcp_ack) + action |= TCP_PUSH; + } else { action = TCP_DATA; } - break; case TCP_ESTABLISHED: debug_cond(DEBUG_INT_STATE, "TCP_ESTABLISHED %x\n", tcp_flags); - if (*tcp_seq_num > tcp_seq_max) - tcp_seq_max = *tcp_seq_num; if (payload_len > 0) { - tcp_hole(*tcp_seq_num, payload_len, tcp_seq_max); + tcp_hole(tcp_seq_num, payload_len); tcp_fin = TCP_DATA; /* cause standalone FIN */ } @@ -603,15 +605,14 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 *tcp_seq_num, int payload_len) case TCP_FIN_WAIT_1: debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_1 (%x)\n", tcp_flags); if (tcp_fin) { + tcp_ack_edge++; action = TCP_ACK | TCP_FIN; current_tcp_state = TCP_FIN_WAIT_2; } if (tcp_syn) action = TCP_RST; - if (tcp_ack) { + if (tcp_ack) current_tcp_state = TCP_CLOSED; - tcp_seq_num = tcp_seq_num + 1; - } break; case TCP_CLOSING: debug_cond(DEBUG_INT_STATE, "TCP_CLOSING (%x)\n", tcp_flags); @@ -640,7 +641,6 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) u16 tcp_rx_xsum = b->ip.hdr.ip_sum; u8 tcp_action = TCP_DATA; u32 tcp_seq_num, tcp_ack_num; - struct in_addr action_and_state; int tcp_hdr_len, payload_len; /* Verify IP header */ @@ -685,7 +685,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) /* Packets are not ordered. Send to app as received. */ tcp_action = tcp_state_machine(b->ip.hdr.tcp_flags, - &tcp_seq_num, payload_len); + tcp_seq_num, payload_len); tcp_activity_count++; if (tcp_activity_count > TCP_ACTIVITY) { @@ -695,18 +695,17 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) if ((tcp_action & TCP_PUSH) || payload_len > 0) { debug_cond(DEBUG_DEV_PKT, - "TCP Notify (action=%x, Seq=%d,Ack=%d,Pay%d)\n", + "TCP Notify (action=%x, Seq=%u,Ack=%u,Pay%d)\n", tcp_action, tcp_seq_num, tcp_ack_num, payload_len); - action_and_state.s_addr = tcp_action; - (*tcp_packet_handler) ((uchar *)b + pkt_len - payload_len, - tcp_seq_num, action_and_state, - tcp_ack_num, payload_len); + (*tcp_packet_handler) ((uchar *)b + pkt_len - payload_len, b->ip.hdr.tcp_dst, + b->ip.hdr.ip_src, b->ip.hdr.tcp_src, tcp_seq_num, + tcp_ack_num, tcp_action, payload_len); } else if (tcp_action != TCP_DATA) { debug_cond(DEBUG_DEV_PKT, - "TCP Action (action=%x,Seq=%d,Ack=%d,Pay=%d)\n", - tcp_action, tcp_seq_num, tcp_ack_num, payload_len); + "TCP Action (action=%x,Seq=%u,Ack=%u,Pay=%d)\n", + tcp_action, tcp_ack_num, tcp_ack_edge, payload_len); /* * Warning: Incoming Ack & Seq sequence numbers are transposed @@ -715,6 +714,6 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) net_send_tcp_packet(0, ntohs(b->ip.hdr.tcp_src), ntohs(b->ip.hdr.tcp_dst), (tcp_action & (~TCP_PUSH)), - tcp_seq_num, tcp_ack_num); + tcp_ack_num, tcp_ack_edge); } } diff --git a/net/wget.c b/net/wget.c index eebdf80eb5..2dbfeb1a1d 100644 --- a/net/wget.c +++ b/net/wget.c @@ -88,8 +88,8 @@ static void wget_send_stored(void) { u8 action = retry_action; int len = retry_len; - unsigned int tcp_ack_num = retry_tcp_ack_num + len; - unsigned int tcp_seq_num = retry_tcp_seq_num; + unsigned int tcp_ack_num = retry_tcp_seq_num + (len == 0 ? 1 : len); + unsigned int tcp_seq_num = retry_tcp_ack_num; uchar *ptr, *offset; switch (current_wget_state) { @@ -130,8 +130,8 @@ static void wget_send_stored(void) } } -static void wget_send(u8 action, unsigned int tcp_ack_num, - unsigned int tcp_seq_num, int len) +static void wget_send(u8 action, unsigned int tcp_seq_num, + unsigned int tcp_ack_num, int len) { retry_action = action; retry_tcp_ack_num = tcp_ack_num; @@ -178,10 +178,8 @@ static void wget_timeout_handler(void) #define PKT_QUEUE_PACKET_SIZE 0x800 static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, - struct in_addr action_and_state, - unsigned int tcp_ack_num, unsigned int len) + u8 action, unsigned int tcp_ack_num, unsigned int len) { - u8 action = action_and_state.s_addr; uchar *pkt_in_q; char *pos; int hlen, i; @@ -268,22 +266,25 @@ static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, } /** - * wget_handler() - handler of wget - * @pkt: the pointer to the payload - * @tcp_seq_num: tcp sequence number - * @action_and_state: TCP state - * @tcp_ack_num: tcp acknowledge number - * @len: length of the payload + * wget_handler() - TCP handler of wget + * @pkt: pointer to the application packet + * @dport: destination TCP port + * @sip: source IP address + * @sport: source TCP port + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * @action: TCP action (SYN, ACK, FIN, etc) + * @len: packet length * * In the "application push" invocation, the TCP header with all * its information is pointed to by the packet pointer. */ -static void wget_handler(uchar *pkt, unsigned int tcp_seq_num, - struct in_addr action_and_state, - unsigned int tcp_ack_num, unsigned int len) +static void wget_handler(uchar *pkt, u16 dport, + struct in_addr sip, u16 sport, + u32 tcp_seq_num, u32 tcp_ack_num, + u8 action, unsigned int len) { enum tcp_state wget_tcp_state = tcp_get_tcp_state(); - u8 action = action_and_state.s_addr; net_set_timeout_handler(wget_timeout, wget_timeout_handler); packets++; @@ -294,7 +295,7 @@ static void wget_handler(uchar *pkt, unsigned int tcp_seq_num, break; case WGET_CONNECTING: debug_cond(DEBUG_WGET, - "wget: Connecting In len=%x, Seq=%x, Ack=%x\n", + "wget: Connecting In len=%x, Seq=%u, Ack=%u\n", len, tcp_seq_num, tcp_ack_num); if (!len) { if (wget_tcp_state == TCP_ESTABLISHED) { @@ -310,14 +311,13 @@ static void wget_handler(uchar *pkt, unsigned int tcp_seq_num, } break; case WGET_CONNECTED: - debug_cond(DEBUG_WGET, "wget: Connected seq=%x, len=%x\n", + debug_cond(DEBUG_WGET, "wget: Connected seq=%u, len=%x\n", tcp_seq_num, len); if (!len) { wget_fail("Image not found, no data returned\n", tcp_seq_num, tcp_ack_num, action); } else { - wget_connected(pkt, tcp_seq_num, action_and_state, - tcp_ack_num, len); + wget_connected(pkt, tcp_seq_num, action, tcp_ack_num, len); } break; case WGET_TRANSFERRING: @@ -338,6 +338,7 @@ static void wget_handler(uchar *pkt, unsigned int tcp_seq_num, wget_send(TCP_ACK, tcp_seq_num, tcp_ack_num, len); fallthrough; case TCP_SYN_SENT: + case TCP_SYN_RECEIVED: case TCP_CLOSING: case TCP_FIN_WAIT_1: case TCP_CLOSED: From patchwork Wed Apr 12 18:49:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1768516 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=rzCNffoI; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Py2jQ3NZ6z1yZZ for ; Fri, 14 Apr 2023 00:56:58 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B3DA785BB5; Thu, 13 Apr 2023 16:56:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="rzCNffoI"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D4D3285FDD; Wed, 12 Apr 2023 20:49:49 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 502D783741 for ; Wed, 12 Apr 2023 20:49:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=3SP02ZAkKBkcmrvx0rww7pxxpun.lxv3-kxx2ur121.mnw6.mn@flex--dimorinny.bounces.google.com Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-54f9df9ebc5so23431957b3.13 for ; Wed, 12 Apr 2023 11:49:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1681325384; x=1683917384; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=Bvl6dEmVELIMFPh99U1L4tk9j1R+YBAV5RVNEsDEOVk=; b=rzCNffoIjV57iTd7su5LluQ6WmYd2p7ltzWNnlCj9x7NfZoaeDMnQSRBe8fC7QTPmO nXtjKlVpBhpzCI5A403BjABdBjNXyT8UKDROE2/uul23Bh2v38oFUdhqOWXFDENisqQo hputyVML+/wQWpYnUH/e8kGhE9ZAJNq08jFQBnLnXF4Ufini6Nkr1SP6l1xTS36UoOMv gej2b9rWovgF26k9haxgodg9PYDcw3Gww3YCtmYWgTYKOR+axRwc/P5/v2aKdd3QjcUR xjjUibk1osPCxy9D8hM1zIMA1ITAq85Vevs43qx3/qEH6GcG/IL5mXJ/KG2ZFzFCIhQk oGuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681325384; x=1683917384; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=Bvl6dEmVELIMFPh99U1L4tk9j1R+YBAV5RVNEsDEOVk=; b=i/Q7vY75BS7QcIVPP34b+tjleA7tUrL+KbV3zvEGbsTR/cyvOyox9s5L4BcFmQaMiB p4KQl7CKmzdNMgvNNH5kxqJM1D9SqK5fBWhhaYf4jARt86Fah4CVgavpW5Ks0hIghlPo QlPrB/mzAX6P0G0qeg/GATM0U8HFH9OB0kYw5xcaJWRj1lYHiSwbX/kjdZlIRNI8J958 8Xgc6L0pJvq5rjznmeQ+7BTsqC5tskZY9fvZK8/E9Yt+qrpcp7qU5vQHiMY5oFkH9c2Y VQ5E7YNC1A7vt3FWnDteMzOurWk2mVo159MsQKxRah0M4PyrUDpZcLkok/LayKcKAj8w 4tjw== X-Gm-Message-State: AAQBX9d94cjTEuBc5t5+iuqHL4tfcK1nHV5O7HFrS3h4FsgR87Kt55tg 8oE6Ni+7ezQ8sEcDzQBAn4EiQzlkZ0Co71xoTczNxd/lIue/Y5SHg6HTtHiWgAL2KGhovlun2BC b0IkTqzd4IRq6rw9Pif7S01e2Th8u1ESXyDAicyLaWvBCqFauvbcEvqjMRr3rHUnO0bw= X-Google-Smtp-Source: AKy350ZBWxj4c474WwLajxwue7+nTlQW2Dg5lumBKYtQ1kst0+XF41Xa1Fzpb2gQcQOzEpae3B9pt98zWEu29Zo= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:7766:76f9:f832:5b94]) (user=dimorinny job=sendgmr) by 2002:a5b:647:0:b0:b8f:5474:2f33 with SMTP id o7-20020a5b0647000000b00b8f54742f33mr317416ybq.5.1681325384059; Wed, 12 Apr 2023 11:49:44 -0700 (PDT) Date: Wed, 12 Apr 2023 19:49:30 +0100 In-Reply-To: <20230412184931.1422789-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230412184931.1422789-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.0.634.g4ca3ef3211-goog Message-ID: <20230412184931.1422789-2-dimorinny@google.com> Subject: [PATCH v2 2/3] net: add fastboot TCP support From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: Dmitrii Merkurev , Ying-Chun Liu , Simon Glass X-Mailman-Approved-At: Thu, 13 Apr 2023 16:56:35 +0200 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Known limitations are 1. fastboot reboot doesn't work (answering OK but not rebooting) 2. flashing isn't supported (TCP transport only limitation) The command syntax is fastboot tcp Signed-off-by: Dmitrii Merkurev Cc: Ying-Chun Liu (PaulLiu) Cc: Simon Glass Сс: Joe Hershberger Сс: Ramon Fried Reviewed-by: Simon Glass --- MAINTAINERS | 6 +- cmd/fastboot.c | 25 ++++- drivers/fastboot/Kconfig | 14 +++ drivers/fastboot/fb_common.c | 1 - include/net.h | 3 +- include/net/fastboot.h | 21 ----- include/net/fastboot_tcp.h | 14 +++ include/net/fastboot_udp.h | 14 +++ net/Makefile | 3 +- net/fastboot_tcp.c | 143 +++++++++++++++++++++++++++++ net/{fastboot.c => fastboot_udp.c} | 4 +- net/net.c | 17 +++- 12 files changed, 230 insertions(+), 35 deletions(-) delete mode 100644 include/net/fastboot.h create mode 100644 include/net/fastboot_tcp.h create mode 100644 include/net/fastboot_udp.h create mode 100644 net/fastboot_tcp.c rename net/{fastboot.c => fastboot_udp.c} (99%) diff --git a/MAINTAINERS b/MAINTAINERS index 4c17c6cb9f..e28d1f7ae0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -987,10 +987,12 @@ F: cmd/fastboot.c F: doc/android/fastboot*.rst F: include/fastboot.h F: include/fastboot-internal.h -F: include/net/fastboot.h +F: include/net/fastboot_tcp.h +F: include/net/fastboot_udp.h F: drivers/fastboot/ F: drivers/usb/gadget/f_fastboot.c -F: net/fastboot.c +F: net/fastboot_tcp.c +F: net/fastboot_udp.c F: test/dm/fastboot.c FPGA diff --git a/cmd/fastboot.c b/cmd/fastboot.c index 97dc02ce74..3d5ff951eb 100644 --- a/cmd/fastboot.c +++ b/cmd/fastboot.c @@ -26,7 +26,7 @@ static int do_fastboot_udp(int argc, char *const argv[], return CMD_RET_FAILURE; } - err = net_loop(FASTBOOT); + err = net_loop(FASTBOOT_UDP); if (err < 0) { printf("fastboot udp error: %d\n", err); @@ -36,6 +36,26 @@ static int do_fastboot_udp(int argc, char *const argv[], return CMD_RET_SUCCESS; } +static int do_fastboot_tcp(int argc, char *const argv[], + uintptr_t buf_addr, size_t buf_size) +{ + int err; + + if (!IS_ENABLED(CONFIG_TCP_FUNCTION_FASTBOOT)) { + pr_err("Fastboot TCP not enabled\n"); + return CMD_RET_FAILURE; + } + + err = net_loop(FASTBOOT_TCP); + + if (err < 0) { + printf("fastboot tcp error: %d\n", err); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + static int do_fastboot_usb(int argc, char *const argv[], uintptr_t buf_addr, size_t buf_size) { @@ -141,7 +161,8 @@ NXTARG: if (!strcmp(argv[1], "udp")) return do_fastboot_udp(argc, argv, buf_addr, buf_size); - + if (!strcmp(argv[1], "tcp")) + return do_fastboot_tcp(argc, argv, buf_addr, buf_size); if (!strcmp(argv[1], "usb")) { argv++; argc--; diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index eefa34779c..a3df9aa3d0 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -4,6 +4,13 @@ config FASTBOOT bool imply ANDROID_BOOT_IMAGE imply CMD_FASTBOOT + help + Fastboot is a protocol used in Android devices for + communicating between the device and a computer during + the bootloader stage. It allows the user to flash the + device firmware and unlock the bootloader. + More information about the protocol and usecases: + https://android.googlesource.com/platform/system/core/+/refs/heads/master/fastboot/ config USB_FUNCTION_FASTBOOT bool "Enable USB fastboot gadget" @@ -28,6 +35,13 @@ config UDP_FUNCTION_FASTBOOT_PORT help The fastboot protocol requires a UDP port number. +config TCP_FUNCTION_FASTBOOT + depends on NET + select FASTBOOT + bool "Enable fastboot protocol over TCP" + help + This enables the fastboot protocol over TCP. + if FASTBOOT config FASTBOOT_BUF_ADDR diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c index 57b6182c46..dde3cda78f 100644 --- a/drivers/fastboot/fb_common.c +++ b/drivers/fastboot/fb_common.c @@ -15,7 +15,6 @@ #include #include #include -#include /** * fastboot_buf_addr - base address of the fastboot download buffer diff --git a/include/net.h b/include/net.h index 399af5e064..63daab3731 100644 --- a/include/net.h +++ b/include/net.h @@ -505,7 +505,8 @@ extern int net_restart_wrap; /* Tried all network devices */ enum proto_t { BOOTP, RARP, ARP, TFTPGET, DHCP, PING, PING6, DNS, NFS, CDP, NETCONS, - SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI, WGET + SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT_UDP, FASTBOOT_TCP, WOL, + UDP, NCSI, WGET }; extern char net_boot_file_name[1024];/* Boot File name */ diff --git a/include/net/fastboot.h b/include/net/fastboot.h deleted file mode 100644 index 68602095d2..0000000000 --- a/include/net/fastboot.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (C) 2016 The Android Open Source Project - */ - -#ifndef __NET_FASTBOOT_H__ -#define __NET_FASTBOOT_H__ - -/**********************************************************************/ -/* - * Global functions and variables. - */ - -/** - * Wait for incoming fastboot comands. - */ -void fastboot_start_server(void); - -/**********************************************************************/ - -#endif /* __NET_FASTBOOT_H__ */ diff --git a/include/net/fastboot_tcp.h b/include/net/fastboot_tcp.h new file mode 100644 index 0000000000..6cf29d52e9 --- /dev/null +++ b/include/net/fastboot_tcp.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2023 The Android Open Source Project + */ + +#ifndef __NET_FASTBOOT_TCP_H__ +#define __NET_FASTBOOT_TCP_H__ + +/** + * Wait for incoming tcp fastboot comands. + */ +void fastboot_tcp_start_server(void); + +#endif /* __NET_FASTBOOT_TCP_H__ */ diff --git a/include/net/fastboot_udp.h b/include/net/fastboot_udp.h new file mode 100644 index 0000000000..d4382c0a0e --- /dev/null +++ b/include/net/fastboot_udp.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2016 The Android Open Source Project + */ + +#ifndef __NET_FASTBOOT_H__ +#define __NET_FASTBOOT_H__ + +/** + * Wait for incoming UDP fastboot comands. + */ +void fastboot_udp_start_server(void); + +#endif /* __NET_FASTBOOT_H__ */ diff --git a/net/Makefile b/net/Makefile index bea000b206..67fc77257d 100644 --- a/net/Makefile +++ b/net/Makefile @@ -26,7 +26,8 @@ obj-$(CONFIG_CMD_PCAP) += pcap.o obj-$(CONFIG_CMD_RARP) += rarp.o obj-$(CONFIG_CMD_SNTP) += sntp.o obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o -obj-$(CONFIG_UDP_FUNCTION_FASTBOOT) += fastboot.o +obj-$(CONFIG_UDP_FUNCTION_FASTBOOT) += fastboot_udp.o +obj-$(CONFIG_TCP_FUNCTION_FASTBOOT) += fastboot_tcp.o obj-$(CONFIG_CMD_WOL) += wol.o obj-$(CONFIG_PROT_UDP) += udp.o obj-$(CONFIG_PROT_TCP) += tcp.o diff --git a/net/fastboot_tcp.c b/net/fastboot_tcp.c new file mode 100644 index 0000000000..b5613b6aa2 --- /dev/null +++ b/net/fastboot_tcp.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (C) 2023 The Android Open Source Project + */ + +#include +#include +#include +#include +#include + +static char command[FASTBOOT_COMMAND_LEN] = {0}; +static char response[FASTBOOT_RESPONSE_LEN] = {0}; + +static const unsigned short handshake_length = 4; +static const uchar *handshake = "FB01"; + +static u16 curr_sport; +static u16 curr_dport; +static u32 curr_tcp_seq_num; +static u32 curr_tcp_ack_num; +static unsigned int curr_request_len; +static enum fastboot_tcp_state { + FASTBOOT_CLOSED, + FASTBOOT_CONNECTED, + FASTBOOT_DISCONNECTING +} state = FASTBOOT_CLOSED; + +static void fastboot_tcp_answer(u8 action, unsigned int len) +{ + const u32 response_seq_num = curr_tcp_ack_num; + const u32 response_ack_num = curr_tcp_seq_num + + (curr_request_len > 0 ? curr_request_len : 1); + + net_send_tcp_packet(len, htons(curr_sport), htons(curr_dport), + action, response_seq_num, response_ack_num); +} + +static void fastboot_tcp_reset(void) +{ + fastboot_tcp_answer(TCP_RST, 0); + state = FASTBOOT_CLOSED; +} + +static void fastboot_tcp_send_packet(u8 action, const uchar *data, unsigned int len) +{ + uchar *pkt = net_get_async_tx_pkt_buf(); + + memset(pkt, '\0', PKTSIZE); + pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; + memcpy(pkt, data, len); + fastboot_tcp_answer(action, len); + memset(pkt, '\0', PKTSIZE); +} + +static void fastboot_tcp_send_message(const char *message, unsigned int len) +{ + __be64 len_be = __cpu_to_be64(len); + uchar *pkt = net_get_async_tx_pkt_buf(); + + memset(pkt, '\0', PKTSIZE); + pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; + // Put first 8 bytes as a big endian message length + memcpy(pkt, &len_be, 8); + pkt += 8; + memcpy(pkt, message, len); + fastboot_tcp_answer(TCP_ACK | TCP_PUSH, len + 8); + memset(pkt, '\0', PKTSIZE); +} + +static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, + struct in_addr sip, u16 sport, + u32 tcp_seq_num, u32 tcp_ack_num, + u8 action, unsigned int len) +{ + u64 command_size; + u8 tcp_fin = action & TCP_FIN; + u8 tcp_push = action & TCP_PUSH; + + curr_sport = sport; + curr_dport = dport; + curr_tcp_seq_num = tcp_seq_num; + curr_tcp_ack_num = tcp_ack_num; + curr_request_len = len; + + switch (state) { + case FASTBOOT_CLOSED: + if (tcp_push) { + if (len != handshake_length || + strlen(pkt) != handshake_length || + memcmp(pkt, handshake, handshake_length) != 0) { + fastboot_tcp_reset(); + break; + } + fastboot_tcp_send_packet(TCP_ACK | TCP_PUSH, + handshake, handshake_length); + state = FASTBOOT_CONNECTED; + } + break; + case FASTBOOT_CONNECTED: + if (tcp_fin) { + fastboot_tcp_answer(TCP_FIN | TCP_ACK, 0); + state = FASTBOOT_DISCONNECTING; + break; + } + if (tcp_push) { + // First 8 bytes is big endian message length + command_size = __be64_to_cpu(*(u64 *)pkt); + len -= 8; + pkt += 8; + + // Only single packet messages are supported ATM + if (strlen(pkt) != command_size) { + fastboot_tcp_reset(); + break; + } + strlcpy(command, pkt, len + 1); + fastboot_handle_command(command, response); + fastboot_tcp_send_message(response, strlen(response)); + } + break; + case FASTBOOT_DISCONNECTING: + if (tcp_push) + state = FASTBOOT_CLOSED; + break; + } + + memset(command, 0, FASTBOOT_COMMAND_LEN); + memset(response, 0, FASTBOOT_RESPONSE_LEN); + curr_sport = 0; + curr_dport = 0; + curr_tcp_seq_num = 0; + curr_tcp_ack_num = 0; + curr_request_len = 0; +} + +void fastboot_tcp_start_server(void) +{ + printf("Using %s device\n", eth_get_name()); + printf("Listening for fastboot command on tcp %pI4\n", &net_ip); + + tcp_set_tcp_handler(fastboot_tcp_handler_ipv4); +} diff --git a/net/fastboot.c b/net/fastboot_udp.c similarity index 99% rename from net/fastboot.c rename to net/fastboot_udp.c index e9569d88d2..27e779d8e0 100644 --- a/net/fastboot.c +++ b/net/fastboot_udp.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include enum { FASTBOOT_ERROR = 0, @@ -300,7 +300,7 @@ static void fastboot_handler(uchar *packet, unsigned int dport, } } -void fastboot_start_server(void) +void fastboot_udp_start_server(void) { printf("Using %s device\n", eth_get_name()); printf("Listening for fastboot command on %pI4\n", &net_ip); diff --git a/net/net.c b/net/net.c index c9a749f6cc..41c3cac26e 100644 --- a/net/net.c +++ b/net/net.c @@ -93,7 +93,8 @@ #include #include #include -#include +#include +#include #include #include #if defined(CONFIG_CMD_PCAP) @@ -498,9 +499,14 @@ restart: tftp_start_server(); break; #endif -#ifdef CONFIG_UDP_FUNCTION_FASTBOOT - case FASTBOOT: - fastboot_start_server(); +#if defined(CONFIG_UDP_FUNCTION_FASTBOOT) + case FASTBOOT_UDP: + fastboot_udp_start_server(); + break; +#endif +#if defined(CONFIG_TCP_FUNCTION_FASTBOOT) + case FASTBOOT_TCP: + fastboot_tcp_start_server(); break; #endif #if defined(CONFIG_CMD_DHCP) @@ -1491,7 +1497,8 @@ common: /* Fall through */ case NETCONS: - case FASTBOOT: + case FASTBOOT_UDP: + case FASTBOOT_TCP: case TFTPSRV: if (IS_ENABLED(CONFIG_IPV6) && use_ip6) { if (!memcmp(&net_link_local_ip6, &net_null_addr_ip6, From patchwork Wed Apr 12 18:49:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1768517 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=p6YQjcrC; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Py2jg1Mbcz1yZZ for ; Fri, 14 Apr 2023 00:57:11 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B22CB85C52; Thu, 13 Apr 2023 16:56:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="p6YQjcrC"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1CCAF83741; Wed, 12 Apr 2023 20:49:51 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ej1-x64a.google.com (mail-ej1-x64a.google.com [IPv6:2a00:1450:4864:20::64a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id BBED185FBB for ; Wed, 12 Apr 2023 20:49:47 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=3S_02ZAkKBkopuy03uzzAs00sxq.o0y6-n005xu454.pqz9.pq@flex--dimorinny.bounces.google.com Received: by mail-ej1-x64a.google.com with SMTP id vo2-20020a170907a80200b00949175b0b70so6381389ejc.9 for ; Wed, 12 Apr 2023 11:49:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1681325387; x=1683917387; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=ROWg/pZbxbBKGoEuTpFW2PVq9vqk4qvwp90wYVI2bJs=; b=p6YQjcrC9kfDFKh4InalREwVDLtX13OGDI2mIer0IHywHUDdKZB82gIA6ZdKBUwQph ERzVg8AwW/1TyiPc2VjquBQ64sv2xD7TUnWfaLE+suc5UVG1uDWA+ChBTvcUUG8jI0cP D4722MLrQ5+svC/VNG6GJDt9SjCrfXvBMEGb8zr2mjVwWh5rZSZ2CE6pWxfo7qhi8WU3 kSpw5n4Bg1FlnHdbkf0enmleOZIYWkckGMbjcXbe4pfWYB2g9Lkk+Bsk9UfZ4byGbVSH FSLceXmuXQ0BlaYG8gJkVJkdg8PKAxrekD9LcB3vHjykOQXIY2zFAEQBEiQGbOllqT92 gAfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681325387; x=1683917387; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=ROWg/pZbxbBKGoEuTpFW2PVq9vqk4qvwp90wYVI2bJs=; b=TwqyyW+ttuql+0o3/7GeFR2jq9F7l2nVgoAuwwdgzCW2Cpr5FHrhV8NSnJP1B9QUUh mSX5C2WYoFkTgcFeSCSisSpHFN2xiCe0PJYPTocAHa/YMo+BRGZ4jmlhIV/+KOwy6A7v UvjRZVk7q5ctZTs3Aeqke2s3fuPkMjX2DGi82sbJ4d+bzvCwq7ZngOjpXnYlxitaOxvk qT/Sd6quTQ+brt+r/6XroikRVt1SdBe3PBtkSrVXtpcSwPKvGqlpPdOKxBZ1g9yOyw1Q rJCtQacEn5q+PWoaq4nVMO+PRTmW9f9SQWzOMuFiJlXsaF6cInEDl+083oZTB6Emhbla y/dw== X-Gm-Message-State: AAQBX9cOj9mNz4Pj2ILrtGk2PKmXSL9C550RRH/KSrQlVwa81Ic2xqPx o46KrV9u/GH72kbGhwZ6yvoll5dj3lDE6rqqeSqWQmjjF0rs0VEjLiXzT8SC3nrKY38uqTUs03U Yhu/sFCllKS+kBSKtAQvrkeHdxvQq/lGem1U/J7/m+SzClHp1scDacu9MnxL/y7hcpwQ= X-Google-Smtp-Source: AKy350YhuCREbIsf2pJtFuIeCtGZkqqD0kC4GOtQqcN5q+2S90Zis3rwKSxlFewjgR/FDCiSac2wqOBQtFUoXMo= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:7766:76f9:f832:5b94]) (user=dimorinny job=sendgmr) by 2002:a17:906:f2ce:b0:94e:2d:e94f with SMTP id gz14-20020a170906f2ce00b0094e002de94fmr1840894ejb.8.1681325387269; Wed, 12 Apr 2023 11:49:47 -0700 (PDT) Date: Wed, 12 Apr 2023 19:49:31 +0100 In-Reply-To: <20230412184931.1422789-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230412184931.1422789-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.0.634.g4ca3ef3211-goog Message-ID: <20230412184931.1422789-3-dimorinny@google.com> Subject: [PATCH v2 3/3] net: share fastboot boot handle logic between transports From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: Dmitrii Merkurev , Ying-Chun Liu , Simon Glass , Ramon Fried X-Mailman-Approved-At: Thu, 13 Apr 2023 16:56:35 +0200 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Introduce reboot, boot and continue commands support to TCP fastboot by moving existing UDP logic into the common module. Signed-off-by: Dmitrii Merkurev Cc: Ying-Chun Liu (PaulLiu) Cc: Simon Glass Сс: Joe Hershberger Сс: Ramon Fried Reviewed-by: Simon Glass Reviewed-by: Ramon Fried Reviewed-by: Simon Glass --- drivers/fastboot/fb_common.c | 32 ++++++++++++++++++++++++++++++++ include/fastboot.h | 9 +++++++++ net/fastboot_tcp.c | 5 ++++- net/fastboot_udp.c | 29 +---------------------------- 4 files changed, 46 insertions(+), 29 deletions(-) diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c index dde3cda78f..621146bc6b 100644 --- a/drivers/fastboot/fb_common.c +++ b/drivers/fastboot/fb_common.c @@ -15,6 +15,7 @@ #include #include #include +#include /** * fastboot_buf_addr - base address of the fastboot download buffer @@ -155,6 +156,37 @@ void fastboot_boot(void) } } +/** + * fastboot_handle_boot() - Shared implementation of system reaction to + * fastboot commands + * + * Making desceisions about device boot state (stay in fastboot, reboot + * to bootloader, reboot to OS, etc). + */ +void fastboot_handle_boot(int command, bool success) +{ + if (!success) + return; + + switch (command) { + case FASTBOOT_COMMAND_BOOT: + fastboot_boot(); + net_set_state(NETLOOP_SUCCESS); + break; + + case FASTBOOT_COMMAND_CONTINUE: + net_set_state(NETLOOP_SUCCESS); + break; + + case FASTBOOT_COMMAND_REBOOT: + case FASTBOOT_COMMAND_REBOOT_BOOTLOADER: + case FASTBOOT_COMMAND_REBOOT_FASTBOOTD: + case FASTBOOT_COMMAND_REBOOT_RECOVERY: + do_reset(NULL, 0, 0, NULL); + break; + } +} + /** * fastboot_set_progress_callback() - set progress callback * diff --git a/include/fastboot.h b/include/fastboot.h index 07f4c8fa71..296451f89d 100644 --- a/include/fastboot.h +++ b/include/fastboot.h @@ -123,6 +123,15 @@ void fastboot_init(void *buf_addr, u32 buf_size); */ void fastboot_boot(void); +/** + * fastboot_handle_boot() - Shared implementation of system reaction to + * fastboot commands + * + * Making desceisions about device boot state (stay in fastboot, reboot + * to bootloader, reboot to OS, etc). + */ +void fastboot_handle_boot(int command, bool success); + /** * fastboot_handle_command() - Handle fastboot command * diff --git a/net/fastboot_tcp.c b/net/fastboot_tcp.c index b5613b6aa2..2eb52ea256 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -73,6 +73,7 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { + int fastboot_command_id; u64 command_size; u8 tcp_fin = action & TCP_FIN; u8 tcp_push = action & TCP_PUSH; @@ -115,8 +116,10 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, break; } strlcpy(command, pkt, len + 1); - fastboot_handle_command(command, response); + fastboot_command_id = fastboot_handle_command(command, response); fastboot_tcp_send_message(response, strlen(response)); + fastboot_handle_boot(fastboot_command_id, + strncmp("OKAY", response, 4) == 0); } break; case FASTBOOT_DISCONNECTING: diff --git a/net/fastboot_udp.c b/net/fastboot_udp.c index 27e779d8e0..389a5b45f5 100644 --- a/net/fastboot_udp.c +++ b/net/fastboot_udp.c @@ -209,39 +209,12 @@ static void fastboot_send(struct fastboot_header header, char *fastboot_data, net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip, fastboot_remote_port, fastboot_our_port, len); - /* Continue boot process after sending response */ - if (!strncmp("OKAY", response, 4)) { - switch (cmd) { - case FASTBOOT_COMMAND_BOOT: - boot_downloaded_image(); - break; - - case FASTBOOT_COMMAND_CONTINUE: - net_set_state(NETLOOP_SUCCESS); - break; - - case FASTBOOT_COMMAND_REBOOT: - case FASTBOOT_COMMAND_REBOOT_BOOTLOADER: - case FASTBOOT_COMMAND_REBOOT_FASTBOOTD: - case FASTBOOT_COMMAND_REBOOT_RECOVERY: - do_reset(NULL, 0, 0, NULL); - break; - } - } + fastboot_handle_boot(cmd, strncmp("OKAY", response, 4) == 0); if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4)) cmd = -1; } -/** - * boot_downloaded_image() - Boots into downloaded image. - */ -static void boot_downloaded_image(void) -{ - fastboot_boot(); - net_set_state(NETLOOP_SUCCESS); -} - /** * fastboot_handler() - Incoming UDP packet handler. *