From patchwork Wed May 10 16:59:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1779639 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=ccWQq9ap; 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 4QGh9T462Tz214S for ; Thu, 11 May 2023 03:00:27 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 892B886071; Wed, 10 May 2023 19:00:19 +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="ccWQq9ap"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7EF8186071; Wed, 10 May 2023 19:00:13 +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,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x549.google.com (mail-ed1-x549.google.com [IPv6:2a00:1450:4864:20::549]) (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 2239A84765 for ; Wed, 10 May 2023 19:00:04 +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=3k81bZAkKBsYpuy03uzzAs00sxq.o0y6-n005xu454.pqz9.pq@flex--dimorinny.bounces.google.com Received: by mail-ed1-x549.google.com with SMTP id 4fb4d7f45d1cf-50bc57d7967so8573987a12.2 for ; Wed, 10 May 2023 10:00:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683738003; x=1686330003; h=content-transfer-encoding:cc:to:from:subject:message-id :mime-version:date:from:to:cc:subject:date:message-id:reply-to; bh=dnPHIj6j602kpBAdVD0TnhPpyegh7EU7l0rGL+yeYmw=; b=ccWQq9aplxfpdZJQtaLD4xzP4GBjHUTF/6rRIA5KxX/CZ1jQ1x//8ymO4KO0UXzKDD 21yholz2WpZH1tHX82kG9885REei5BcMOdY+6TXRCW4OAUpY+Ju8DxwiBche4UxphBFC X5sPhB9Po4XodHS6mzVKYDKvEe0Rh3W6+HtlV0DVbey9V6RTuJATWjHEbiqqnQLFqyIC nbEhcikijuFVU8kAiJq3pMLsiDnDwGveeQqBNF9+JjMNyFkWsldwOwBYoKnBdVp/Xbix EFqj1ps0GU0Vyh/+MyEhy98su1Noo02PH7nks6YakWRTvmp+7UBa8gCEtEDs3WYga+Zl x6yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683738003; x=1686330003; 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=dnPHIj6j602kpBAdVD0TnhPpyegh7EU7l0rGL+yeYmw=; b=FNXgJKobRmO+5rT4Mq3dIhkm1MqLXRCJ2D5FouVxsn6MEoMcdP/cAvGVVklFlCKkL8 u0civT5o0hVWZNES+qy+mgcp07drynMZTaZkJW/RiWRFwwevgh0/wJkE51objGFzu1k4 g2H+GrHCtKXQrTvd8qYkyndNvk+OFEOqUnsXipsrgYdTNU+H4Y/9d2N6kfwlzRvEq+Oi RXj4T5OZa0U/kIlUwOwC84Z9B3COgVntNMp4Oo6RFpLWlxJu8l3h7O+A0OzkBT/HFbbS M0rR2NLbM9AqjM9tL45h+r/uQb/PYBVr31/HoNdJSPPOfNYJrHLjtRw27CUEKT/zDKln iBUg== X-Gm-Message-State: AC+VfDyi1Q/AIzlGX6PWtQtrid5elrz//EhVHJc0Tg2dZbH+CdmJuVDf Hnp5qrZ8ev7Og8oXYGWHkbo/vZD6QYFrcnpQWXah2cvvJ5/fC9BWE1EMptxuttPa4gWft8I97wd 76Jff2y3NdasX5LqdkxS04wMVTMfZ3s/Cy6vAOCVekHlc9V4vhb/0x2h11N9uP/5obsA= X-Google-Smtp-Source: ACHHUZ7bSs9/iTUnJSuwqHOmaStB/Cp0nn3nNktbbuxf3WcGz86nyw6lLtOW03ioIcVQNSPYK871RXp5K5y0k2Y= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:8054:7d60:263c:94b9]) (user=dimorinny job=sendgmr) by 2002:a50:ab4a:0:b0:4bb:e549:a2ad with SMTP id t10-20020a50ab4a000000b004bbe549a2admr6593533edc.4.1683738003525; Wed, 10 May 2023 10:00:03 -0700 (PDT) Date: Wed, 10 May 2023 17:59:54 +0100 Mime-Version: 1.0 X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230510165959.2228978-1-dimorinny@google.com> Subject: [PATCH v2 1/6] net: split IP_TCP header into separate IP/IP6 and TCP headers From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.com, rfried.dev@gmail.com, Dmitrii Merkurev , Ying-Chun Liu , Simon Glass X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean This allows us to reuse TCP logic between IP and IP6 stack. 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 --- include/net/tcp.h | 54 ++++++++++++++++-------------------- net/tcp.c | 70 +++++++++++++++++++++++------------------------ test/cmd/wget.c | 48 ++++++++++++++++++-------------- 3 files changed, 85 insertions(+), 87 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index c29d4ce24a..93ed728dfe 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -5,20 +5,16 @@ * Copyright 2017 Duncan Hare, All rights reserved. */ +#ifndef __TCP_H__ +#define __TCP_H__ + #define TCP_ACTIVITY 127 /* Number of packets received */ /* before console progress mark */ + +#define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2) + /** - * struct ip_tcp_hdr - IP and TCP header - * @ip_hl_v: header length and version - * @ip_tos: type of service - * @ip_len: total length - * @ip_id: identification - * @ip_off: fragment offset field - * @ip_ttl: time to live - * @ip_p: protocol - * @ip_sum: checksum - * @ip_src: Source IP address - * @ip_dst: Destination IP address + * struct tcp_hdr - TCP header * @tcp_src: TCP source port * @tcp_dst: TCP destination port * @tcp_seq: TCP sequence number @@ -28,18 +24,8 @@ * @tcp_win: TCP windows size * @tcp_xsum: Checksum * @tcp_ugr: Pointer to urgent data - */ -struct ip_tcp_hdr { - u8 ip_hl_v; - u8 ip_tos; - u16 ip_len; - u16 ip_id; - u16 ip_off; - u8 ip_ttl; - u8 ip_p; - u16 ip_sum; - struct in_addr ip_src; - struct in_addr ip_dst; +*/ +struct tcp_hdr { u16 tcp_src; u16 tcp_dst; u32 tcp_seq; @@ -51,8 +37,8 @@ struct ip_tcp_hdr { u16 tcp_ugr; } __packed; -#define IP_TCP_HDR_SIZE (sizeof(struct ip_tcp_hdr)) -#define TCP_HDR_SIZE (IP_TCP_HDR_SIZE - IP_HDR_SIZE) +#define TCP_HDR_SIZE (sizeof(struct tcp_hdr)) +#define IP_TCP_HDR_SIZE (IP_HDR_SIZE + TCP_HDR_SIZE) #define TCP_DATA 0x00 /* Data Packet - internal use only */ #define TCP_FIN 0x01 /* Finish flag */ @@ -178,7 +164,8 @@ struct tcp_t_opt { /** * struct ip_tcp_hdr_o - IP + TCP header + TCP options - * @hdr: IP + TCP header + * @ip_hdr: IP + TCP header + * @tcp_hdr: TCP header * @mss: TCP MSS Option * @scale: TCP Windows Scale Option * @sack_p: TCP Sack-Permitted Option @@ -186,7 +173,8 @@ struct tcp_t_opt { * @end: end of options */ struct ip_tcp_hdr_o { - struct ip_tcp_hdr hdr; + struct ip_hdr ip_hdr; + struct tcp_hdr tcp_hdr; struct tcp_mss mss; struct tcp_scale scale; struct tcp_sack_p sack_p; @@ -198,15 +186,17 @@ struct ip_tcp_hdr_o { /** * struct ip_tcp_hdr_s - IP + TCP header + TCP options - * @hdr: IP + TCP header + * @ip_hdr: IP + TCP header + * @tcp_hdr: TCP header * @t_opt: TCP Timestamp Option * @sack_v: TCP SACK Option * @end: end of options */ struct ip_tcp_hdr_s { - struct ip_tcp_hdr hdr; - struct tcp_t_opt t_opt; - struct tcp_sack_v sack_v; + struct ip_hdr ip_hdr; + struct tcp_hdr tcp_hdr; + struct tcp_t_opt t_opt; + struct tcp_sack_v sack_v; u8 end; } __packed; @@ -303,3 +293,5 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int len); u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest, int tcp_len, int pkt_len); + +#endif // __TCP_H__ diff --git a/net/tcp.c b/net/tcp.c index a713e1dd60..10ce799814 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -155,7 +155,7 @@ u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest, */ int net_set_ack_options(union tcp_build_pkt *b) { - b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); + b->sack.tcp_hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); b->sack.t_opt.kind = TCP_O_TS; b->sack.t_opt.len = TCP_OPT_LEN_A; @@ -187,12 +187,12 @@ int net_set_ack_options(union tcp_build_pkt *b) b->sack.sack_v.hill[3].r = TCP_O_NOP; } - b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + + b->sack.tcp_hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + TCP_TSOPT_SIZE + tcp_lost.len)); } else { b->sack.sack_v.kind = 0; - b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + + b->sack.tcp_hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + TCP_TSOPT_SIZE)); } @@ -201,7 +201,7 @@ int net_set_ack_options(union tcp_build_pkt *b) * TCP header to add to the total packet length */ - return GET_TCP_HDR_LEN_IN_BYTES(b->sack.hdr.tcp_hlen); + return GET_TCP_HDR_LEN_IN_BYTES(b->sack.tcp_hdr.tcp_hlen); } /** @@ -213,7 +213,7 @@ void net_set_syn_options(union tcp_build_pkt *b) if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) tcp_lost.len = 0; - b->ip.hdr.tcp_hlen = 0xa0; + b->ip.tcp_hdr.tcp_hlen = 0xa0; b->ip.mss.kind = TCP_O_MSS; b->ip.mss.len = TCP_OPT_LEN_4; @@ -249,9 +249,9 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, * Header: 5 32 bit words. 4 bits TCP header Length, * 4 bits reserved options */ - b->ip.hdr.tcp_flags = action; + b->ip.tcp_hdr.tcp_flags = action; pkt_hdr_len = IP_TCP_HDR_SIZE; - b->ip.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); + b->ip.tcp_hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); switch (action) { case TCP_SYN: @@ -274,7 +274,7 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, 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; + b->ip.tcp_hdr.tcp_flags = action; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:ACK (%pI4, %pI4, s=%u, a=%u, A=%x)\n", &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num, @@ -308,7 +308,7 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, fallthrough; default: pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); - b->ip.hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; + b->ip.tcp_hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:dft (%pI4, %pI4, s=%u, a=%u, A=%x)\n", &net_server_ip, &net_ip, @@ -320,10 +320,10 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, 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); + b->ip.tcp_hdr.tcp_ack = htonl(tcp_ack_edge); + b->ip.tcp_hdr.tcp_src = htons(sport); + b->ip.tcp_hdr.tcp_dst = htons(dport); + b->ip.tcp_hdr.tcp_seq = htonl(tcp_seq_num); /* * TCP window size - TCP header variable tcp_win. @@ -340,13 +340,13 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, * it is, then the u-boot tftp or nfs kernel netboot should be * considered. */ - b->ip.hdr.tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE); + b->ip.tcp_hdr.tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE); - b->ip.hdr.tcp_xsum = 0; - b->ip.hdr.tcp_ugr = 0; + b->ip.tcp_hdr.tcp_xsum = 0; + b->ip.tcp_hdr.tcp_ugr = 0; - b->ip.hdr.tcp_xsum = tcp_set_pseudo_header(pkt, net_ip, net_server_ip, - tcp_len, pkt_len); + b->ip.tcp_hdr.tcp_xsum = tcp_set_pseudo_header(pkt, net_ip, net_server_ip, + tcp_len, pkt_len); net_set_ip_header((uchar *)&b->ip, net_server_ip, net_ip, pkt_len, IPPROTO_TCP); @@ -638,7 +638,7 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) { int tcp_len = pkt_len - IP_HDR_SIZE; - u16 tcp_rx_xsum = b->ip.hdr.ip_sum; + u16 tcp_rx_xsum = b->ip.ip_hdr.ip_sum; u8 tcp_action = TCP_DATA; u32 tcp_seq_num, tcp_ack_num; int tcp_hdr_len, payload_len; @@ -646,11 +646,11 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) /* Verify IP header */ debug_cond(DEBUG_DEV_PKT, "TCP RX in RX Sum (to=%pI4, from=%pI4, len=%d)\n", - &b->ip.hdr.ip_src, &b->ip.hdr.ip_dst, pkt_len); + &b->ip.ip_hdr.ip_src, &b->ip.ip_hdr.ip_dst, pkt_len); - b->ip.hdr.ip_src = net_server_ip; - b->ip.hdr.ip_dst = net_ip; - b->ip.hdr.ip_sum = 0; + b->ip.ip_hdr.ip_src = net_server_ip; + b->ip.ip_hdr.ip_dst = net_ip; + b->ip.ip_hdr.ip_sum = 0; if (tcp_rx_xsum != compute_ip_checksum(b, IP_HDR_SIZE)) { debug_cond(DEBUG_DEV_PKT, "TCP RX IP xSum Error (%pI4, =%pI4, len=%d)\n", @@ -659,10 +659,10 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) } /* Build pseudo header and verify TCP header */ - tcp_rx_xsum = b->ip.hdr.tcp_xsum; - b->ip.hdr.tcp_xsum = 0; - if (tcp_rx_xsum != tcp_set_pseudo_header((uchar *)b, b->ip.hdr.ip_src, - b->ip.hdr.ip_dst, tcp_len, + tcp_rx_xsum = b->ip.tcp_hdr.tcp_xsum; + b->ip.tcp_hdr.tcp_xsum = 0; + if (tcp_rx_xsum != tcp_set_pseudo_header((uchar *)b, b->ip.ip_hdr.ip_src, + b->ip.ip_hdr.ip_dst, tcp_len, pkt_len)) { debug_cond(DEBUG_DEV_PKT, "TCP RX TCP xSum Error (%pI4, %pI4, len=%d)\n", @@ -670,7 +670,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) return; } - tcp_hdr_len = GET_TCP_HDR_LEN_IN_BYTES(b->ip.hdr.tcp_hlen); + tcp_hdr_len = GET_TCP_HDR_LEN_IN_BYTES(b->ip.tcp_hdr.tcp_hlen); payload_len = tcp_len - tcp_hdr_len; if (tcp_hdr_len > TCP_HDR_SIZE) @@ -680,11 +680,11 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) * Incoming sequence and ack numbers are server's view of the numbers. * The app must swap the numbers when responding. */ - tcp_seq_num = ntohl(b->ip.hdr.tcp_seq); - tcp_ack_num = ntohl(b->ip.hdr.tcp_ack); + tcp_seq_num = ntohl(b->ip.tcp_hdr.tcp_seq); + tcp_ack_num = ntohl(b->ip.tcp_hdr.tcp_ack); /* Packets are not ordered. Send to app as received. */ - tcp_action = tcp_state_machine(b->ip.hdr.tcp_flags, + tcp_action = tcp_state_machine(b->ip.tcp_hdr.tcp_flags, tcp_seq_num, payload_len); tcp_activity_count++; @@ -698,8 +698,8 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) "TCP Notify (action=%x, Seq=%u,Ack=%u,Pay%d)\n", tcp_action, tcp_seq_num, 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_packet_handler) ((uchar *)b + pkt_len - payload_len, b->ip.tcp_hdr.tcp_dst, + b->ip.ip_hdr.ip_src, b->ip.tcp_hdr.tcp_src, tcp_seq_num, tcp_ack_num, tcp_action, payload_len); } else if (tcp_action != TCP_DATA) { @@ -711,8 +711,8 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) * Warning: Incoming Ack & Seq sequence numbers are transposed * here to outgoing Seq & Ack sequence numbers */ - net_send_tcp_packet(0, ntohs(b->ip.hdr.tcp_src), - ntohs(b->ip.hdr.tcp_dst), + net_send_tcp_packet(0, ntohs(b->ip.tcp_hdr.tcp_src), + ntohs(b->ip.tcp_hdr.tcp_dst), (tcp_action & (~TCP_PUSH)), tcp_ack_num, tcp_ack_edge); } diff --git a/test/cmd/wget.c b/test/cmd/wget.c index ed83fc94a5..e2c11d3e76 100644 --- a/test/cmd/wget.c +++ b/test/cmd/wget.c @@ -52,9 +52,11 @@ static int sb_syn_handler(struct udevice *dev, void *packet, { struct eth_sandbox_priv *priv = dev_get_priv(dev); struct ethernet_hdr *eth = packet; - struct ip_tcp_hdr *tcp = packet + ETHER_HDR_SIZE; + struct ip_hdr *ip = packet + ETHER_HDR_SIZE; + struct tcp_hdr *tcp = (void *)ip + IP_HDR_SIZE; struct ethernet_hdr *eth_send; - struct ip_tcp_hdr *tcp_send; + struct ip_hdr *ip_send; + struct tcp_hdr *tcp_send; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -64,7 +66,8 @@ static int sb_syn_handler(struct udevice *dev, void *packet, memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN); memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN); eth_send->et_protlen = htons(PROT_IP); - tcp_send = (void *)eth_send + ETHER_HDR_SIZE; + ip_send = (void *)eth_send + ETHER_HDR_SIZE; + tcp_send = (void *)ip_send + IP_HDR_SIZE; tcp_send->tcp_src = tcp->tcp_dst; tcp_send->tcp_dst = tcp->tcp_src; tcp_send->tcp_seq = htonl(0); @@ -74,14 +77,14 @@ static int sb_syn_handler(struct udevice *dev, void *packet, tcp_send->tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE); tcp_send->tcp_xsum = 0; tcp_send->tcp_ugr = 0; - tcp_send->tcp_xsum = tcp_set_pseudo_header((uchar *)tcp_send, - tcp->ip_src, - tcp->ip_dst, + tcp_send->tcp_xsum = tcp_set_pseudo_header((uchar *)ip_send, + ip->ip_src, + ip->ip_dst, TCP_HDR_SIZE, IP_TCP_HDR_SIZE); - net_set_ip_header((uchar *)tcp_send, - tcp->ip_src, - tcp->ip_dst, + net_set_ip_header((uchar *)ip_send, + ip->ip_src, + ip->ip_dst, IP_TCP_HDR_SIZE, IPPROTO_TCP); @@ -97,9 +100,11 @@ static int sb_ack_handler(struct udevice *dev, void *packet, { struct eth_sandbox_priv *priv = dev_get_priv(dev); struct ethernet_hdr *eth = packet; - struct ip_tcp_hdr *tcp = packet + ETHER_HDR_SIZE; + struct ip_hdr *ip = packet + ETHER_HDR_SIZE; + struct tcp_hdr *tcp = (void *)ip + IP_HDR_SIZE; struct ethernet_hdr *eth_send; - struct ip_tcp_hdr *tcp_send; + struct ip_hdr *ip_send; + struct tcp_hdr *tcp_send; void *data; int pkt_len; int payload_len = 0; @@ -115,10 +120,11 @@ static int sb_ack_handler(struct udevice *dev, void *packet, memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN); memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN); eth_send->et_protlen = htons(PROT_IP); - tcp_send = (void *)eth_send + ETHER_HDR_SIZE; + ip_send = (void *)eth_send + ETHER_HDR_SIZE; + tcp_send = (void *)ip_send + IP_HDR_SIZE; + data = (void *)tcp_send + TCP_HDR_SIZE; tcp_send->tcp_src = tcp->tcp_dst; tcp_send->tcp_dst = tcp->tcp_src; - data = (void *)tcp_send + IP_TCP_HDR_SIZE; if (ntohl(tcp->tcp_seq) == 1 && ntohl(tcp->tcp_ack) == 1) { tcp_send->tcp_seq = htonl(ntohl(tcp->tcp_ack)); @@ -138,14 +144,14 @@ static int sb_ack_handler(struct udevice *dev, void *packet, tcp_send->tcp_xsum = 0; tcp_send->tcp_ugr = 0; pkt_len = IP_TCP_HDR_SIZE + payload_len; - tcp_send->tcp_xsum = tcp_set_pseudo_header((uchar *)tcp_send, - tcp->ip_src, - tcp->ip_dst, + tcp_send->tcp_xsum = tcp_set_pseudo_header((uchar *)ip_send, + ip->ip_src, + ip->ip_dst, pkt_len - IP_HDR_SIZE, pkt_len); - net_set_ip_header((uchar *)tcp_send, - tcp->ip_src, - tcp->ip_dst, + net_set_ip_header((uchar *)ip_send, + ip->ip_src, + ip->ip_dst, pkt_len, IPPROTO_TCP); @@ -163,14 +169,14 @@ static int sb_http_handler(struct udevice *dev, void *packet, { struct ethernet_hdr *eth = packet; struct ip_hdr *ip; - struct ip_tcp_hdr *tcp; + struct tcp_hdr *tcp; if (ntohs(eth->et_protlen) == PROT_ARP) { return sb_arp_handler(dev, packet, len); } else if (ntohs(eth->et_protlen) == PROT_IP) { ip = packet + ETHER_HDR_SIZE; if (ip->ip_p == IPPROTO_TCP) { - tcp = packet + ETHER_HDR_SIZE; + tcp = packet + ETHER_HDR_SIZE + IP_HDR_SIZE; if (tcp->tcp_flags == TCP_SYN) return sb_syn_handler(dev, packet, len); else if (tcp->tcp_flags & TCP_ACK && !(tcp->tcp_flags & TCP_SYN)) From patchwork Wed May 10 16:59:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1779642 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=FgduXALT; 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 4QGhBM0WXsz214S for ; Thu, 11 May 2023 03:01:15 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A2CDD8609B; Wed, 10 May 2023 19:00:28 +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="FgduXALT"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id CF97184765; Wed, 10 May 2023 19:00:19 +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,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x54a.google.com (mail-ed1-x54a.google.com [IPv6:2a00:1450:4864:20::54a]) (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 6982D86043 for ; Wed, 10 May 2023 19:00:06 +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=3ls1bZAkKBsksx136x22Dv33v0t.r319-q3380x787.st2C.st@flex--dimorinny.bounces.google.com Received: by mail-ed1-x54a.google.com with SMTP id 4fb4d7f45d1cf-50d89279d95so14763938a12.1 for ; Wed, 10 May 2023 10:00:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683738006; x=1686330006; 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=0H39IO2mTyE+m4qijN/I1eu3IcebeZ+fe3EoH6wzhag=; b=FgduXALTjK7CAUcSexUfVfUBzJwY3+rYdC36nJOKSd2wT2APUHeSOFNJrj0/Da34aN gnldf/qSbKxP1aKxaME7D5jHpiiqOvPi2ULDyVHPUQQhijBWouQ5SJ7zfCmnzHy88ZcJ ecJ2U+yYs82tTTItYfJ7kGLkQQgUj03+S1njqpGiam/QAHwPsl9xkmBZJZD0v806QbBM MRqjP/ieSRZ8jGYipwuy47DrZlrIlQh2tTmnTWELt5S7uV/dsMnyphSt0qkidvArrx77 R33cqye0vhEadfvIVVrM4IeGkLEiRjtC3BohTSaHIyi7I67U8DnfkoQqXP3Rl+Me3HwA OuEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683738006; x=1686330006; 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=0H39IO2mTyE+m4qijN/I1eu3IcebeZ+fe3EoH6wzhag=; b=gewwEULV6KcfI5Q8hhk76+VJ7xdyD82mATsOB7vcGrvlTj/VknuKfKudD+uQdD6bS/ 3i/W8fc8qlsvgaE9Jhq4ajNaL7pSY+eOazWUaMd6JSR/fvRsqWvq/Ov6RQo2/YUMXPM5 Yptjp4QsD//xrzqHyyCpx+PiMAKwKDLV2plObiAKWCxxo8DlfDc7OUXzMSWsVlmY5NZc sezDC5TyzB57KDWf4VYPBi9eY8ffXybABj2TZ6InzlkVjlbRFnwzCqAcEtQVWgRW63de 3O1GdIVxOrhuQCOzVW28UuwTsCApqKKuF4wpDtaVhMdWmC6DCSFxD7ATFPeKPMa2aiq2 lXAw== X-Gm-Message-State: AC+VfDx8ilNUZxQyrGnIIVlFdy+HWpYbtQ8XhOslhEKxlloyg07h/tuq F1ZOX3qz8NcSUl3xPCOPah4EQ78eg5UNlo0N7FViOWGRzRh2cSjEbDN+m/VE6Z7QMvvM9mtSf0C Ryy7rASjGDh5r69KxNKzAAUrnqD8D6+XgxWXw54m1mnGQUhh5rSe3G2LMgxg8kv6Ocuo= X-Google-Smtp-Source: ACHHUZ4DyGT4E60zt49n6gmg/CQyJhOGVF+eaLcjS1pQPO1XfvupLYMkZpQOXevZhnxhd8HBkAt5YPKxvxmcax8= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:8054:7d60:263c:94b9]) (user=dimorinny job=sendgmr) by 2002:a05:6402:400f:b0:506:beb3:e866 with SMTP id d15-20020a056402400f00b00506beb3e866mr9382347eda.0.1683738006030; Wed, 10 May 2023 10:00:06 -0700 (PDT) Date: Wed, 10 May 2023 17:59:55 +0100 In-Reply-To: <20230510165959.2228978-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230510165959.2228978-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230510165959.2228978-2-dimorinny@google.com> Subject: [PATCH v2 2/6] net: prepare existing TCP stack to be reused by IP6 From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.com, rfried.dev@gmail.com, Dmitrii Merkurev , Ying-Chun Liu , Simon Glass 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 Changes: 1. Separate reusable part from net_set_tcp_header to net_set_tcp_header_common 2. Make TCP signatures reusable by receiving particular IP agnostic TCP headers 3. Extract net_send_ip_packet6 from net_send_udp_packet6 to reuse the code 4. Expose TCP state machine related functions This allows us to reuse TCP logic between IP and IP6 stack. 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 --- include/net/tcp.h | 109 +++++++++++++-- net/net.c | 18 ++- net/net6.c | 78 ++++++++--- net/tcp.c | 337 ++++++++++++++++++++++++++++------------------ 4 files changed, 372 insertions(+), 170 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 93ed728dfe..344b4be2a4 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -8,10 +8,20 @@ #ifndef __TCP_H__ #define __TCP_H__ +#include + #define TCP_ACTIVITY 127 /* Number of packets received */ /* before console progress mark */ +/* + * TCP lengths are stored as a rounded up number of 32 bit words. + * Add 3 to length round up, rounded, then divided into the + * length in 32 bit words. + */ +#define LEN_B_TO_DW(x) ((x) >> 2) +#define ROUND_TCPHDR_LEN(x) (LEN_B_TO_DW((x) + 3)) #define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2) +#define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4) /** * struct tcp_hdr - TCP header @@ -24,7 +34,7 @@ * @tcp_win: TCP windows size * @tcp_xsum: Checksum * @tcp_ugr: Pointer to urgent data -*/ + */ struct tcp_hdr { u16 tcp_src; u16 tcp_dst; @@ -163,18 +173,14 @@ struct tcp_t_opt { */ /** - * struct ip_tcp_hdr_o - IP + TCP header + TCP options - * @ip_hdr: IP + TCP header - * @tcp_hdr: TCP header + * struct tcp_hdr_o - TCP options * @mss: TCP MSS Option * @scale: TCP Windows Scale Option * @sack_p: TCP Sack-Permitted Option * @t_opt: TCP Timestamp Option * @end: end of options */ -struct ip_tcp_hdr_o { - struct ip_hdr ip_hdr; - struct tcp_hdr tcp_hdr; +struct tcp_hdr_o { struct tcp_mss mss; struct tcp_scale scale; struct tcp_sack_p sack_p; @@ -182,6 +188,22 @@ struct ip_tcp_hdr_o { u8 end; } __packed; +#define TCP_O_SIZE (sizeof(struct tcp_hdr_o)) + +/** + * struct ip_tcp_hdr_o - IP + TCP header + TCP options + * @ip_hdr: IP + TCP header + * @tcp_hdr: TCP header + * @tcp_o: TCP options + * @end: end of IP/TCP header + */ +struct ip_tcp_hdr_o { + struct ip_hdr ip_hdr; + struct tcp_hdr tcp_hdr; + struct tcp_hdr_o tcp_o; + u8 end; +} __packed; + #define IP_TCP_O_SIZE (sizeof(struct ip_tcp_hdr_o)) /** @@ -209,7 +231,7 @@ struct ip_tcp_hdr_s { /** * struct pseudo_hdr - Pseudo Header - * @padding: pseudo hdr size = ip_tcp hdr size + * @padding: pseudo hdr size = ip hdr size * @p_src: Source IP address * @p_dst: Destination IP address * @rsvd: reserved @@ -236,7 +258,6 @@ struct pseudo_hdr { * * Build Pseudo header in packed buffer * first, calculate TCP checksum, then build IP header in packed buffer. - * */ union tcp_build_pkt { struct pseudo_hdr ph; @@ -269,9 +290,77 @@ enum tcp_state { enum tcp_state tcp_get_tcp_state(void); void tcp_set_tcp_state(enum tcp_state new_state); -int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, + +/** + * net_set_tcp_header_common() - IP version agnostic TCP header building implementation + * + * @tcp_hdr: pointer to TCP header struct + * @tcp_o: pointer to TCP options header struct + * @sack_t_opt: pointer to TCP sack options header struct + * @sack_v: pointer to TCP sack header struct + * @dport: destination TCP port + * @sport: source TCP port + * @payload_len: TCP payload len + * @action: TCP action (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * + * returns TCP header + */ +int net_set_tcp_header_common(struct tcp_hdr *tcp_hdr, struct tcp_hdr_o *tcp_o, + struct tcp_t_opt *sack_t_opt, struct tcp_sack_v *sack_v, + u16 dport, u16 sport, int payload_len, u8 action, + u32 tcp_seq_num, u32 tcp_ack_num); + +/** + * net_set_tcp_header() - IPv4 TCP header bulding implementation + * + * @pkt: pointer to the IP header + * @dport: destination TCP port + * @sport: source TCP port + * @payload_len: TCP payload len + * @action: TCP action (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * + * returns TCP header + */ +int net_set_tcp_header(uchar *pkt, u16 dport, u16 sport, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num); +/** + * tcp_parse_options() - parsing TCP options + * + * @o: pointer to the option field. + * @o_len: length of the option field. + */ +void tcp_parse_options(uchar *o, int o_len); + +/** + * tcp_state_machine() - update TCP state in a reaction to incoming packet + * + * @tcp_flags: TCP action (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_seq_num_out: TCP sequential number we expect to answer with + * @tcp_ack_num_out: TCP acknowledgment number we expect to answer with + * @payload_len: TCP payload len + * + * returns TCP action we expect to answer with + */ +u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, u32 *tcp_seq_num_out, + u32 *tcp_ack_num_out, int payload_len); + +/** + * tcp_sent_state_machine() - update TCP state in a reaction to outcoming packet + * + * @action: TCP action (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * + * returns TCP action we expect to answer with + */ +u8 tcp_sent_state_machine(u8 action, u32 *tcp_seq_num, u32 *tcp_ack_num); + /** * rxhand_tcp() - An incoming packet handler. * @pkt: pointer to the application packet diff --git a/net/net.c b/net/net.c index 43abbac7c3..0b68bf7b13 100644 --- a/net/net.c +++ b/net/net.c @@ -916,6 +916,7 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, { uchar *pkt; int eth_hdr_size; + int ip_tcp_hdr_size; int pkt_hdr_size; /* make sure the net_tx_packet is initialized (net_init() was called) */ @@ -934,19 +935,24 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, pkt = (uchar *)net_tx_packet; eth_hdr_size = net_set_ether(pkt, ether, PROT_IP); + pkt_hdr_size = eth_hdr_size; + pkt += eth_hdr_size; switch (proto) { case IPPROTO_UDP: - net_set_udp_header(pkt + eth_hdr_size, dest, dport, sport, + net_set_udp_header(pkt, dest, dport, sport, payload_len); - pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE; + pkt_hdr_size += IP_UDP_HDR_SIZE; break; #if defined(CONFIG_PROT_TCP) case IPPROTO_TCP: - pkt_hdr_size = eth_hdr_size - + tcp_set_tcp_header(pkt + eth_hdr_size, dport, sport, - payload_len, action, tcp_seq_num, - tcp_ack_num); + ip_tcp_hdr_size = IP_HDR_SIZE; + ip_tcp_hdr_size += net_set_tcp_header(pkt, dport, sport, + payload_len, action, tcp_seq_num, + tcp_ack_num); + net_set_ip_header(pkt, net_server_ip, net_ip, + ip_tcp_hdr_size + payload_len, IPPROTO_TCP); + pkt_hdr_size += ip_tcp_hdr_size; break; #endif default: diff --git a/net/net6.c b/net/net6.c index 2dd64c0e16..e395b930b0 100644 --- a/net/net6.c +++ b/net/net6.c @@ -324,15 +324,13 @@ int ip6_add_hdr(uchar *xip, struct in6_addr *src, struct in6_addr *dest, return sizeof(struct ip6_hdr); } -int net_send_udp_packet6(uchar *ether, struct in6_addr *dest, int dport, - int sport, int len) +int udp6_add_hdr(uchar *xip, struct in6_addr *dest, int dport, int sport, + int len) { - uchar *pkt; struct udp_hdr *udp; u16 csum_p; - udp = (struct udp_hdr *)((uchar *)net_tx_packet + net_eth_hdr_size() + - IP6_HDR_SIZE); + udp = (struct udp_hdr *)xip; udp->udp_dst = htons(dport); udp->udp_src = htons(sport); @@ -344,39 +342,75 @@ int net_send_udp_packet6(uchar *ether, struct in6_addr *dest, int dport, udp->udp_xsum = csum_ipv6_magic(&net_ip6, dest, len + UDP_HDR_SIZE, IPPROTO_UDP, csum_p); + return sizeof(struct udp_hdr); +} + +int net_send_ip_packet6(uchar *ether, struct in6_addr *dest, int dport, int sport, + int payload_len, int proto, u8 action, u32 tcp_seq_num, + u32 tcp_ack_num) +{ + uchar *pkt; + int eth_hdr_size; + int ip_hdr_size; + int udp_hdr_size; + int tcp_hdr_size; + int pkt_hdr_size; + + if (!net_tx_packet) + return -1; + + pkt = (uchar *)net_tx_packet; + + eth_hdr_size = net_set_ether(pkt, ether, PROT_IP6); + pkt_hdr_size += eth_hdr_size; + pkt = eth_hdr_size; + + switch (proto) { +#if defined(CONFIG_PROT_UDP) + case IPPROTO_UDP: + ip_hdr_size = ip6_add_hdr(pkt, &net_ip6, dest, IPPROTO_UDP, 64, + payload_len + UDP_HDR_SIZE); + pkt_hdr_size += ip_hdr_size; + pkt += ip_hdr_size; + + udp_hdr_size = udp6_add_hdr(pkt, dest, dport, sport, payload_len); + pkt_hdr_size += udp_hdr_size; + pkt += udp_hdr_size; + break; +#endif + default: + return -EINVAL; + } + /* if MAC address was not discovered yet, save the packet and do * neighbour discovery */ - if (!memcmp(ether, net_null_ethaddr, 6)) { + if (memcmp(ether, net_null_ethaddr, 6) == 0) { + memcpy((uchar *)net_nd_tx_packet, + (uchar *)net_tx_packet, pkt_hdr_size + payload_len); + memset((uchar *)net_tx_packet, 0, pkt_hdr_size + payload_len); + net_copy_ip6(&net_nd_sol_packet_ip6, dest); net_nd_packet_mac = ether; - - pkt = net_nd_tx_packet; - pkt += net_set_ether(pkt, net_nd_packet_mac, PROT_IP6); - pkt += ip6_add_hdr(pkt, &net_ip6, dest, IPPROTO_UDP, 64, - len + UDP_HDR_SIZE); - memcpy(pkt, (uchar *)udp, len + UDP_HDR_SIZE); - /* size of the waiting packet */ - net_nd_tx_packet_size = (pkt - net_nd_tx_packet) + - UDP_HDR_SIZE + len; - - /* and do the neighbor solicitation */ + net_nd_tx_packet_size = pkt_hdr_size + payload_len; net_nd_try = 1; net_nd_timer_start = get_timer(0); ndisc_request(); return 1; /* waiting */ } - pkt = (uchar *)net_tx_packet; - pkt += net_set_ether(pkt, ether, PROT_IP6); - pkt += ip6_add_hdr(pkt, &net_ip6, dest, IPPROTO_UDP, 64, - len + UDP_HDR_SIZE); - (void)eth_send(net_tx_packet, pkt - net_tx_packet + UDP_HDR_SIZE + len); + (void)eth_send(net_tx_packet, pkt_hdr_size + payload_len); return 0; /* transmitted */ } +int net_send_udp_packet6(uchar *ether, struct in6_addr *dest, int dport, + int sport, int len) +{ + return net_send_ip_packet6(ether, dest, dport, sport, len, IPPROTO_UDP, 0, 0, 0); +} + int net_ip6_handler(struct ethernet_hdr *et, struct ip6_hdr *ip6, int len) { struct in_addr zero_ip = {.s_addr = 0 }; diff --git a/net/tcp.c b/net/tcp.c index 10ce799814..483c03a595 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -54,16 +54,6 @@ static struct sack_r edge_a[TCP_SACK]; static unsigned int sack_idx; static unsigned int prev_len; -/* - * TCP lengths are stored as a rounded up number of 32 bit words. - * Add 3 to length round up, rounded, then divided into the - * length in 32 bit words. - */ -#define LEN_B_TO_DW(x) ((x) >> 2) -#define ROUND_TCPHDR_LEN(x) (LEN_B_TO_DW((x) + 3)) -#define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4) -#define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2) - /* TCP connection state */ static enum tcp_state current_tcp_state; @@ -149,29 +139,32 @@ u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest, /** * net_set_ack_options() - set TCP options in acknowledge packets - * @b: the packet + * @tcp_hdr: pointer to TCP header struct + * @t_opt: pointer to TCP t opt header struct + * @sack_v: pointer to TCP sack header struct * * Return: TCP header length */ -int net_set_ack_options(union tcp_build_pkt *b) +int net_set_ack_options(struct tcp_hdr *tcp_hdr, struct tcp_t_opt *t_opt, + struct tcp_sack_v *sack_v) { - b->sack.tcp_hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); + tcp_hdr->tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); - b->sack.t_opt.kind = TCP_O_TS; - b->sack.t_opt.len = TCP_OPT_LEN_A; - b->sack.t_opt.t_snd = htons(loc_timestamp); - b->sack.t_opt.t_rcv = rmt_timestamp; - b->sack.sack_v.kind = TCP_1_NOP; - b->sack.sack_v.len = 0; + t_opt->kind = TCP_O_TS; + t_opt->len = TCP_OPT_LEN_A; + t_opt->t_snd = htons(loc_timestamp); + t_opt->t_rcv = rmt_timestamp; + sack_v->kind = TCP_1_NOP; + sack_v->len = 0; if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) { if (tcp_lost.len > TCP_OPT_LEN_2) { debug_cond(DEBUG_DEV_PKT, "TCP ack opt lost.len %x\n", tcp_lost.len); - b->sack.sack_v.len = tcp_lost.len; - b->sack.sack_v.kind = TCP_V_SACK; - b->sack.sack_v.hill[0].l = htonl(tcp_lost.hill[0].l); - b->sack.sack_v.hill[0].r = htonl(tcp_lost.hill[0].r); + sack_v->len = tcp_lost.len; + sack_v->kind = TCP_V_SACK; + sack_v->hill[0].l = htonl(tcp_lost.hill[0].l); + sack_v->hill[0].r = htonl(tcp_lost.hill[0].r); /* * These SACK structures are initialized with NOPs to @@ -179,21 +172,21 @@ int net_set_ack_options(union tcp_build_pkt *b) * SACK structures used for both header padding and * internally. */ - b->sack.sack_v.hill[1].l = htonl(tcp_lost.hill[1].l); - b->sack.sack_v.hill[1].r = htonl(tcp_lost.hill[1].r); - b->sack.sack_v.hill[2].l = htonl(tcp_lost.hill[2].l); - b->sack.sack_v.hill[2].r = htonl(tcp_lost.hill[2].r); - b->sack.sack_v.hill[3].l = TCP_O_NOP; - b->sack.sack_v.hill[3].r = TCP_O_NOP; + sack_v->hill[1].l = htonl(tcp_lost.hill[1].l); + sack_v->hill[1].r = htonl(tcp_lost.hill[1].r); + sack_v->hill[2].l = htonl(tcp_lost.hill[2].l); + sack_v->hill[2].r = htonl(tcp_lost.hill[2].r); + sack_v->hill[3].l = TCP_O_NOP; + sack_v->hill[3].r = TCP_O_NOP; } - b->sack.tcp_hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + - TCP_TSOPT_SIZE + - tcp_lost.len)); + tcp_hdr->tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + + TCP_TSOPT_SIZE + + tcp_lost.len)); } else { - b->sack.sack_v.kind = 0; - b->sack.tcp_hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + - TCP_TSOPT_SIZE)); + sack_v->kind = 0; + tcp_hdr->tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + + TCP_TSOPT_SIZE)); } /* @@ -201,69 +194,61 @@ int net_set_ack_options(union tcp_build_pkt *b) * TCP header to add to the total packet length */ - return GET_TCP_HDR_LEN_IN_BYTES(b->sack.tcp_hdr.tcp_hlen); + return GET_TCP_HDR_LEN_IN_BYTES(tcp_hdr->tcp_hlen); } /** * net_set_ack_options() - set TCP options in SYN packets - * @b: the packet + * @tcp_hdr: pointer to TCP header struct + * @options: pointer to TCP header options struct */ -void net_set_syn_options(union tcp_build_pkt *b) +void net_set_syn_options(struct tcp_hdr *tcp_hdr, struct tcp_hdr_o *options) { if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) tcp_lost.len = 0; - b->ip.tcp_hdr.tcp_hlen = 0xa0; + tcp_hdr->tcp_hlen = 0xa0; - b->ip.mss.kind = TCP_O_MSS; - b->ip.mss.len = TCP_OPT_LEN_4; - b->ip.mss.mss = htons(TCP_MSS); - b->ip.scale.kind = TCP_O_SCL; - b->ip.scale.scale = TCP_SCALE; - b->ip.scale.len = TCP_OPT_LEN_3; + options->mss.kind = TCP_O_MSS; + options->mss.len = TCP_OPT_LEN_4; + options->mss.mss = htons(TCP_MSS); + options->scale.kind = TCP_O_SCL; + options->scale.scale = TCP_SCALE; + options->scale.len = TCP_OPT_LEN_3; if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) { - b->ip.sack_p.kind = TCP_P_SACK; - b->ip.sack_p.len = TCP_OPT_LEN_2; + options->sack_p.kind = TCP_P_SACK; + options->sack_p.len = TCP_OPT_LEN_2; } else { - b->ip.sack_p.kind = TCP_1_NOP; - b->ip.sack_p.len = TCP_1_NOP; + options->sack_p.kind = TCP_1_NOP; + options->sack_p.len = TCP_1_NOP; } - b->ip.t_opt.kind = TCP_O_TS; - b->ip.t_opt.len = TCP_OPT_LEN_A; + options->t_opt.kind = TCP_O_TS; + options->t_opt.len = TCP_OPT_LEN_A; loc_timestamp = get_ticks(); rmt_timestamp = 0; - b->ip.t_opt.t_snd = 0; - b->ip.t_opt.t_rcv = 0; - b->ip.end = TCP_O_END; + + options->t_opt.t_snd = 0; + options->t_opt.t_rcv = 0; } -int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, - u8 action, u32 tcp_seq_num, u32 tcp_ack_num) +/** + * tcp_sent_state_machine() - update TCP state in a reaction to outcoming packet + * + * @action: TCP action (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * + * returns TCP action we expect to answer with + */ +u8 tcp_sent_state_machine(u8 action, u32 *tcp_seq_num, u32 *tcp_ack_num) { - union tcp_build_pkt *b = (union tcp_build_pkt *)pkt; - int pkt_hdr_len; - int pkt_len; - int tcp_len; - - /* - * Header: 5 32 bit words. 4 bits TCP header Length, - * 4 bits reserved options - */ - b->ip.tcp_hdr.tcp_flags = action; - pkt_hdr_len = IP_TCP_HDR_SIZE; - b->ip.tcp_hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); - switch (action) { case TCP_SYN: debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:SYN (%pI4, %pI4, sq=%u, ak=%u)\n", - &net_server_ip, &net_ip, - tcp_seq_num, tcp_ack_num); + "TCP Hdr:SYN (sq=%u, ak=%u)\n", *tcp_seq_num, *tcp_ack_num); tcp_activity_count = 0; - net_set_syn_options(b); - tcp_seq_num = 0; - tcp_ack_num = 0; - pkt_hdr_len = IP_TCP_O_SIZE; + *tcp_seq_num = 0; + *tcp_ack_num = 0; if (current_tcp_state == TCP_SYN_SENT) { /* Too many SYNs */ action = TCP_FIN; current_tcp_state = TCP_FIN_WAIT_1; @@ -273,57 +258,93 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, break; case TCP_SYN | TCP_ACK: case TCP_ACK: - pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); - b->ip.tcp_hdr.tcp_flags = action; debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:ACK (%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num, - action); + "TCP Hdr:ACK (s=%u, a=%u, A=%x)\n", + *tcp_seq_num, *tcp_ack_num, action); break; case TCP_FIN: debug_cond(DEBUG_DEV_PKT, - "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; + "TCP Hdr:FIN (s=%u, a=%u)\n", *tcp_seq_num, *tcp_ack_num); 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); + "TCP Hdr:RST (s=%u, a=%u)\n", *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): + debug_cond(DEBUG_DEV_PKT, + "TCP Hdr:FIN ACK PSH(s=%u, a=%u, A=%x)\n", + *tcp_seq_num, *tcp_ack_num, action); if (current_tcp_state == TCP_CLOSE_WAIT) current_tcp_state = TCP_CLOSING; - - debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, - tcp_seq_num, tcp_ack_num, action); fallthrough; default: - pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); - b->ip.tcp_hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; + action = action | TCP_PUSH | TCP_ACK; debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:dft (%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, - tcp_seq_num, tcp_ack_num, action); + "TCP Hdr:dft (s=%u, a=%u, A=%x)\n", + *tcp_seq_num, *tcp_ack_num, action); } - pkt_len = pkt_hdr_len + payload_len; - tcp_len = pkt_len - IP_HDR_SIZE; + return action; +} + +/** + * net_set_tcp_header_common() - IP version agnostic TCP header building implementation + * + * @tcp_hdr: pointer to TCP header struct + * @tcp_o: pointer to TCP options header struct + * @sack_t_opt: pointer to TCP sack options header struct + * @sack_v: pointer to TCP sack header struct + * @dport: destination TCP port + * @sport: source TCP port + * @payload_len: TCP payload len + * @action: TCP action (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * + * returns TCP header size + */ +int net_set_tcp_header_common(struct tcp_hdr *tcp_hdr, struct tcp_hdr_o *tcp_o, + struct tcp_t_opt *sack_t_opt, struct tcp_sack_v *sack_v, + u16 dport, u16 sport, int payload_len, u8 action, + u32 tcp_seq_num, u32 tcp_ack_num) +{ + u8 tcp_action = TCP_DATA; + int tcp_hdr_len; + + /* + * Header: 5 32 bit words. 4 bits TCP header Length, + * 4 bits reserved options + */ + tcp_hdr_len = TCP_HDR_SIZE; + tcp_hdr->tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); + + switch (action) { + case TCP_SYN: + net_set_syn_options(tcp_hdr, tcp_o); + tcp_hdr_len = TCP_HDR_SIZE + TCP_O_SIZE; + break; + case TCP_RST | TCP_ACK: + case TCP_RST: + case TCP_FIN: + payload_len = 0; + break; + default: + tcp_hdr_len = net_set_ack_options(tcp_hdr, sack_t_opt, sack_v); + } + + tcp_action = tcp_sent_state_machine(action, &tcp_seq_num, &tcp_ack_num); + tcp_hdr->tcp_flags = tcp_action; tcp_ack_edge = tcp_ack_num; - /* TCP Header */ - b->ip.tcp_hdr.tcp_ack = htonl(tcp_ack_edge); - b->ip.tcp_hdr.tcp_src = htons(sport); - b->ip.tcp_hdr.tcp_dst = htons(dport); - b->ip.tcp_hdr.tcp_seq = htonl(tcp_seq_num); + tcp_hdr->tcp_ack = htonl(tcp_ack_edge); + tcp_hdr->tcp_seq = htonl(tcp_seq_num); + tcp_hdr->tcp_src = htons(sport); + tcp_hdr->tcp_dst = htons(dport); /* * TCP window size - TCP header variable tcp_win. @@ -340,18 +361,46 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, * it is, then the u-boot tftp or nfs kernel netboot should be * considered. */ - b->ip.tcp_hdr.tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE); + tcp_hdr->tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE); - b->ip.tcp_hdr.tcp_xsum = 0; - b->ip.tcp_hdr.tcp_ugr = 0; + tcp_hdr->tcp_xsum = 0; + tcp_hdr->tcp_ugr = 0; - b->ip.tcp_hdr.tcp_xsum = tcp_set_pseudo_header(pkt, net_ip, net_server_ip, - tcp_len, pkt_len); + return tcp_hdr_len; +} - net_set_ip_header((uchar *)&b->ip, net_server_ip, net_ip, - pkt_len, IPPROTO_TCP); +/** + * net_set_tcp_header() - IPv4 TCP header bulding implementation + * + * @pkt: pointer to the IP header + * @dport: destination TCP port + * @sport: source TCP port + * @payload_len: TCP payload len + * @action: TCP action (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * + * returns TCP header + payload size + */ +int net_set_tcp_header(uchar *pkt, u16 dport, u16 sport, int payload_len, + u8 action, u32 tcp_seq_num, u32 tcp_ack_num) +{ + union tcp_build_pkt *b = (union tcp_build_pkt *)pkt; + int tcp_hdr_len; + int pkt_len; - return pkt_hdr_len; + pkt_len = IP_HDR_SIZE; + tcp_hdr_len = net_set_tcp_header_common(&b->ip.tcp_hdr, &b->ip.tcp_o, + &b->sack.t_opt, &b->sack.sack_v, + dport, sport, payload_len, action, + tcp_seq_num, tcp_ack_num); + pkt_len += tcp_hdr_len; + pkt_len += payload_len; + + b->ip.tcp_hdr.tcp_xsum = tcp_set_pseudo_header(pkt, net_ip, net_server_ip, + tcp_hdr_len + payload_len, pkt_len); + + return tcp_hdr_len; } /** @@ -500,7 +549,31 @@ 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 void init_sack_options(u32 tcp_seq_num, u32 tcp_ack_num) +{ + tcp_seq_init = tcp_seq_num; + tcp_ack_edge = tcp_ack_num; + sack_idx = 0; + edge_a[sack_idx].se.l = tcp_ack_edge; + edge_a[sack_idx].se.r = tcp_ack_edge; + prev_len = 0; + for (int i = 0; i < TCP_SACK; i++) + edge_a[i].st = NOPKT; +} + +/** + * tcp_state_machine() - update TCP state in a reaction to incoming request + * + * @tcp_flags: TCP action (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_seq_num_out: TCP sequential number we expect to answer with + * @tcp_ack_num_out: TCP acknowledgment number we expect to answer with + * @payload_len: TCP payload len + * + * returns TCP action we expect to answer with + */ +u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, u32 *tcp_seq_num_out, + u32 *tcp_ack_num_out, int payload_len) { u8 tcp_fin = tcp_flags & TCP_FIN; u8 tcp_syn = tcp_flags & TCP_SYN; @@ -508,7 +581,6 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) u8 tcp_push = tcp_flags & TCP_PUSH; u8 tcp_ack = tcp_flags & TCP_ACK; u8 action = TCP_DATA; - int i; /* * tcp_flags are examined to determine TX action in a given state @@ -533,34 +605,29 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) debug_cond(DEBUG_INT_STATE, "TCP CLOSED %x\n", tcp_flags); if (tcp_syn) { action = TCP_SYN | TCP_ACK; - tcp_seq_init = tcp_seq_num; - tcp_ack_edge = tcp_seq_num + 1; + init_sack_options(tcp_seq_num, tcp_seq_num + 1); current_tcp_state = TCP_SYN_RECEIVED; } else if (tcp_ack || tcp_fin) { action = TCP_DATA; } break; case TCP_SYN_RECEIVED: + if (tcp_ack) { + action = TCP_DATA; + init_sack_options(tcp_seq_num, tcp_seq_num + 1); + current_tcp_state = TCP_ESTABLISHED; + } + break; case TCP_SYN_SENT: 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; - } 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; + } else if (tcp_syn && tcp_ack) { + action |= TCP_ACK | TCP_PUSH; + init_sack_options(tcp_seq_num, tcp_seq_num + 1); 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; } @@ -627,6 +694,10 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) } break; } + + *tcp_seq_num_out = tcp_seq_num; + *tcp_ack_num_out = tcp_ack_edge; + return action; } @@ -641,6 +712,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) u16 tcp_rx_xsum = b->ip.ip_hdr.ip_sum; u8 tcp_action = TCP_DATA; u32 tcp_seq_num, tcp_ack_num; + u32 res_tcp_seq_num, res_tcp_ack_num; int tcp_hdr_len, payload_len; /* Verify IP header */ @@ -685,7 +757,8 @@ 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.tcp_hdr.tcp_flags, - tcp_seq_num, payload_len); + tcp_seq_num, &res_tcp_seq_num, + &res_tcp_ack_num, payload_len); tcp_activity_count++; if (tcp_activity_count > TCP_ACTIVITY) { @@ -705,7 +778,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) } else if (tcp_action != TCP_DATA) { debug_cond(DEBUG_DEV_PKT, "TCP Action (action=%x,Seq=%u,Ack=%u,Pay=%d)\n", - tcp_action, tcp_ack_num, tcp_ack_edge, payload_len); + tcp_action, res_tcp_seq_num, res_tcp_ack_num, payload_len); /* * Warning: Incoming Ack & Seq sequence numbers are transposed @@ -714,6 +787,6 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) net_send_tcp_packet(0, ntohs(b->ip.tcp_hdr.tcp_src), ntohs(b->ip.tcp_hdr.tcp_dst), (tcp_action & (~TCP_PUSH)), - tcp_ack_num, tcp_ack_edge); + res_tcp_seq_num, res_tcp_ack_num); } } From patchwork Wed May 10 16:59:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1779640 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=XnacunAC; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QGh9q50jFz214S for ; Thu, 11 May 2023 03:00:47 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id DA5A286068; Wed, 10 May 2023 19:00:24 +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="XnacunAC"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id AFCF086071; Wed, 10 May 2023 19:00:17 +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,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x549.google.com (mail-ed1-x549.google.com [IPv6:2a00:1450:4864:20::549]) (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 B877486068 for ; Wed, 10 May 2023 19:00:08 +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=3mM1bZAkKBssuz358z44Fx55x2v.t53B-s55A2z9A9.uv4E.uv@flex--dimorinny.bounces.google.com Received: by mail-ed1-x549.google.com with SMTP id 4fb4d7f45d1cf-50bcaaeaec0so8473192a12.2 for ; Wed, 10 May 2023 10:00:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683738008; x=1686330008; 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=tT6rU2PvL+GqitTJje5tJCn9KutDJRMSb56Vqq2G3A0=; b=XnacunACQQlraIqGHBjmpyV1bjuuoeuKBxHMFBhjlQiv1Jd6ueW/6PZylJnTXj6ncG 1mXXjrqQHLFJ1NCQ5sMyReSm5wHm2ydK4MuEVk4JawuMDweYPfgqdHVOeWWl548h5xdV 0VA9Iw2Z+dWaNn7KGIuHq94ZNtAdNO0MXWu/osDEMvANpR+92i3Z51v/erJNiLXbTnwt ijmDkJqJCB9TEDsRh39K8rwPg5XxQ7YwLIiESsC1QGYpusCiDQH2yjEzMJLf1oIj5ARE V8pbP/0A89x+UXj6oB3+R50+nAM4OxEp2WwQP/fr0eO3cWjA8G7ocR3XdrnieQxsi8Kx iwHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683738008; x=1686330008; 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=tT6rU2PvL+GqitTJje5tJCn9KutDJRMSb56Vqq2G3A0=; b=lr0N0QbKJHumFtvImRpLB3XyGJrxGs7iqysJVRwCy9CnlgZBz9kewZ0RaPgSvV8gS5 BXtYQG+ZiPUN9L7FICA+/aNI5thOrU0zebUm+vDkxWM1bhBtKpZEprDdwQqR7TgQR3Gz wQ9c4RBnByBOuq9tKF0dJyr4LLsONoSQvC0ZUI6o0Jd+9tStSrfZCW+XXZ+jGq93Z2Zn ycfEjjAu0ZGhgTDWZZ4O7yasnRBVdyheyl/UK+llb1HPl3YtwukTnvOGrMk+LNvOzljN wjNl5fbsSiB3DFFcFIT1Vh212jqE4XyoRp9MzkQSmHX105ExXexFkBwhZGOz8esVbnSL PS6g== X-Gm-Message-State: AC+VfDwHnd6nO43VGwhKd6pYB3eTTtao9Shz442YTK+6eoagw1G9Zkop xNIHLpAd5ezICHk11oepEHDVgKEiBy1kpnbNW0N0B6Px2AW8pmagZkigBgWMaxcgu90Y+B7yMOZ +cRFSStC+Uy51fT6G3Od+mNdSmVmrGRtXCHL/Dq8Aum6RBpJKplL+EMFV3KKZGaSxfDU= X-Google-Smtp-Source: ACHHUZ7dqmGU96T4vs1e2z2tPxniWx5L1RM8dGu8dU+dB/ApmgS66qqj4ksI8lzUV3xjS0virknMGUcDeYnGz2c= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:8054:7d60:263c:94b9]) (user=dimorinny job=sendgmr) by 2002:a50:c341:0:b0:504:8b5c:d90d with SMTP id q1-20020a50c341000000b005048b5cd90dmr6722379edb.1.1683738008214; Wed, 10 May 2023 10:00:08 -0700 (PDT) Date: Wed, 10 May 2023 17:59:56 +0100 In-Reply-To: <20230510165959.2228978-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230510165959.2228978-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230510165959.2228978-3-dimorinny@google.com> Subject: [PATCH v2 3/6] net: introduce TCP/IP6 support From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.com, rfried.dev@gmail.com, Dmitrii Merkurev , Ying-Chun Liu , Simon Glass 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 Add TCP/IP6 related headers and reuse refactored TCP/IP implementation 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 --- include/net/tcp6.h | 106 +++++++++++++++++++++++++++++++++++++++++++++ include/net6.h | 14 ++++++ net/Makefile | 1 + net/net.c | 6 +++ net/net6.c | 72 +++++++++++++++++++++++++----- net/tcp6.c | 99 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 288 insertions(+), 10 deletions(-) create mode 100644 include/net/tcp6.h create mode 100644 net/tcp6.c diff --git a/include/net/tcp6.h b/include/net/tcp6.h new file mode 100644 index 0000000000..3db125ecc5 --- /dev/null +++ b/include/net/tcp6.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2022 The Android Open Source Project + */ + +#ifndef __TCP6_H__ +#define __TCP6_H__ + +#if defined(CONFIG_PROT_TCP) + +#include +#include + +/** + * typedef rxhand_tcp6_f() - An incoming TCP IPv6 packet handler. + * @pkt: pointer to the application packet + * @dport: destination TCP port + * @sip: source IP6 address + * @sport: source TCP port + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * @action: TCP packet type (SYN, ACK, FIN, etc) + */ +typedef void rxhand_tcp6_f(uchar *pkt, u16 dport, + struct in6_addr sip, u16 sport, + u32 tcp_seq_num, u32 tcp_ack_num, + u8 action, unsigned int len); + +/** + * struct ip6_tcp_hdr_o - IP6 + TCP header + TCP options + * @ip_hdr: IP6 + TCP header + * @tcp_hdr: TCP header + * @tcp_o: TCP options + * @end: end of IP6/TCP header + */ +struct ip6_tcp_hdr_o { + struct ip6_hdr ip_hdr; + struct tcp_hdr tcp_hdr; + struct tcp_hdr_o tcp_o; + u8 end; +} __packed; + +#define IP6_TCP_O_SIZE (sizeof(struct ip6_tcp_hdr_o)) + +/** + * struct ip6_tcp_hdr_s - IP6 + TCP header + TCP options + * @ip_hdr: IP6 + TCP header + * @tcp_hdr: TCP header + * @t_opt: TCP Timestamp Option + * @sack_v: TCP SACK Option + * @end: end of options + */ +struct ip6_tcp_hdr_s { + struct ip6_hdr ip_hdr; + struct tcp_hdr tcp_hdr; + struct tcp_t_opt t_opt; + struct tcp_sack_v sack_v; + u8 end; +} __packed; + +#define IP6_TCP_SACK_SIZE (sizeof(struct ip6_tcp_hdr_s)) + +/** + * union tcp6_build_pkt - union for building TCP/IP6 packet. + * @ip: IP6 and TCP header plus TCP options + * @sack: IP6 and TCP header plus SACK options + * @raw: buffer + */ +union tcp6_build_pkt { + struct ip6_tcp_hdr_o ip; + struct ip6_tcp_hdr_s sack; + uchar raw[1600]; +} __packed; + +/** + * net_set_tcp6_handler6() - set application TCP6 packet handler + * @param f pointer to callback function + */ +void net_set_tcp_handler6(rxhand_tcp6_f *f); + +/** + * net_set_tcp_header6() - set + * @pkt: pointer to IP6/TCP headers + * @dport: destination TCP port + * @sport: source TCP port + * @payload_len: payload length + * @action: TCP packet type (SYN, ACK, FIN, etc) + * @tcp_seq_num: TCP sequential number + * @tcp_ack_num: TCP acknowledgment number + * + * returns TCP header size + */ +int net_set_tcp_header6(uchar *pkt, u16 dport, u16 sport, int payload_len, + u8 action, u32 tcp_seq_num, u32 tcp_ack_num); + +void net_set_tcp_handler6(rxhand_tcp6_f *f); + +/** + * rxhand_tcp6() - handle incoming IP6 TCP packet + * @param b pointer to IP6/TCP packet builder struct + * @param len full packet length + */ +void rxhand_tcp6(union tcp6_build_pkt *b, unsigned int len); + +#endif // CONFIG_PROT_TCP +#endif // __TCP6_H__ diff --git a/include/net6.h b/include/net6.h index beafc05338..fa926f07ac 100644 --- a/include/net6.h +++ b/include/net6.h @@ -344,6 +344,20 @@ int ip6_add_hdr(uchar *xip, struct in6_addr *src, struct in6_addr *dest, int net_send_udp_packet6(uchar *ether, struct in6_addr *dest, int dport, int sport, int len); +/** + * net_send_tcp_packet6() - Make up TCP packet and send it + * + * @payload_len: TCP payload length + * @dport: destination port + * @sport: source port + * @action: TCP flag (SYN, ACL, PUSH, etc) + * @tcp_seq_num: TCP sequence number + * @tcp_ack_num: TCP ackno + * Return: 0 if send successfully, -1 otherwise + */ +int net_send_tcp_packet6(int payload_len, int dport, int sport, u8 action, + u32 tcp_seq_num, u32 tcp_ack_num); + /** * net_ip6_handler() - Handle IPv6 packet * diff --git a/net/Makefile b/net/Makefile index 3e2d061338..002b0f68a2 100644 --- a/net/Makefile +++ b/net/Makefile @@ -32,6 +32,7 @@ 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 +obj-$(CONFIG_IPV6) += tcp6.o obj-$(CONFIG_CMD_WGET) += wget.o # Disable this warning as it is triggered by: diff --git a/net/net.c b/net/net.c index 0b68bf7b13..9ef290dc41 100644 --- a/net/net.c +++ b/net/net.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include #include @@ -386,6 +387,9 @@ static void net_clear_handlers(void) net_set_udp_handler(NULL); net_set_arp_handler(NULL); net_set_timeout_handler(0, NULL); +#if defined(CONFIG_IPV6) && defined(CONFIG_PROT_TCP) + net_set_tcp_handler6(NULL); +#endif } static void net_cleanup_loop(void) @@ -916,7 +920,9 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, { uchar *pkt; int eth_hdr_size; +#if defined(CONFIG_PROT_TCP) int ip_tcp_hdr_size; +#endif int pkt_hdr_size; /* make sure the net_tx_packet is initialized (net_init() was called) */ diff --git a/net/net6.c b/net/net6.c index e395b930b0..575726766e 100644 --- a/net/net6.c +++ b/net/net6.c @@ -14,6 +14,7 @@ #include #include #include +#include #include /* NULL IPv6 address */ @@ -350,11 +351,17 @@ int net_send_ip_packet6(uchar *ether, struct in6_addr *dest, int dport, int spor u32 tcp_ack_num) { uchar *pkt; + int pkt_hdr_size; int eth_hdr_size; +#if defined(CONFIG_PROT_UDP) || defined(CONFIG_PROT_TCP) int ip_hdr_size; +#endif +#if defined(CONFIG_PROT_UDP) int udp_hdr_size; +#endif +#if defined(CONFIG_PROT_TCP) int tcp_hdr_size; - int pkt_hdr_size; +#endif if (!net_tx_packet) return -1; @@ -362,8 +369,8 @@ int net_send_ip_packet6(uchar *ether, struct in6_addr *dest, int dport, int spor pkt = (uchar *)net_tx_packet; eth_hdr_size = net_set_ether(pkt, ether, PROT_IP6); - pkt_hdr_size += eth_hdr_size; - pkt = eth_hdr_size; + pkt_hdr_size = eth_hdr_size; + pkt += eth_hdr_size; switch (proto) { #if defined(CONFIG_PROT_UDP) @@ -377,6 +384,18 @@ int net_send_ip_packet6(uchar *ether, struct in6_addr *dest, int dport, int spor pkt_hdr_size += udp_hdr_size; pkt += udp_hdr_size; break; +#endif +#if defined(CONFIG_PROT_TCP) + case IPPROTO_TCP: + tcp_hdr_size = net_set_tcp_header6(pkt, dport, sport, + payload_len, action, tcp_seq_num, + tcp_ack_num); + ip_hdr_size = ip6_add_hdr(pkt, &net_ip6, dest, IPPROTO_TCP, 64, + tcp_hdr_size + payload_len); + + pkt_hdr_size += ip_hdr_size + tcp_hdr_size; + pkt += ip_hdr_size + tcp_hdr_size; + break; #endif default: return -EINVAL; @@ -411,11 +430,25 @@ int net_send_udp_packet6(uchar *ether, struct in6_addr *dest, int dport, return net_send_ip_packet6(ether, dest, dport, sport, len, IPPROTO_UDP, 0, 0, 0); } +int net_send_tcp_packet6(int payload_len, int dport, int sport, u8 action, + u32 tcp_seq_num, u32 tcp_ack_num) +{ + return net_send_ip_packet6(net_server_ethaddr, &net_server_ip6, dport, + sport, payload_len, IPPROTO_TCP, action, + tcp_seq_num, tcp_ack_num); +} + int net_ip6_handler(struct ethernet_hdr *et, struct ip6_hdr *ip6, int len) { - struct in_addr zero_ip = {.s_addr = 0 }; struct icmp6hdr *icmp; +#if defined(CONFIG_PROT_UDP) + struct in_addr zero_ip = {.s_addr = 0 }; struct udp_hdr *udp; +#endif +#if defined(CONFIG_PROT_TCP) + union tcp6_build_pkt *tcp_headers; + struct tcp_hdr *tcp; +#endif u16 csum; u16 csum_p; u16 hlen; @@ -454,6 +487,7 @@ int net_ip6_handler(struct ethernet_hdr *et, struct ip6_hdr *ip6, int len) break; } break; +#if defined(CONFIG_PROT_UDP) case IPPROTO_UDP: udp = (struct udp_hdr *)(((uchar *)ip6) + IP6_HDR_SIZE); csum = udp->udp_xsum; @@ -468,13 +502,31 @@ int net_ip6_handler(struct ethernet_hdr *et, struct ip6_hdr *ip6, int len) return -EINVAL; /* IP header OK. Pass the packet to the current handler. */ - net_get_udp_handler()((uchar *)ip6 + IP6_HDR_SIZE + - UDP_HDR_SIZE, - ntohs(udp->udp_dst), - zero_ip, - ntohs(udp->udp_src), - ntohs(udp->udp_len) - 8); + net_get_udp_handler()((uchar *)ip6 + IP6_HDR_SIZE + UDP_HDR_SIZE, + ntohs(udp->udp_dst), + zero_ip, + ntohs(udp->udp_src), + ntohs(udp->udp_len) - 8); + break; +#endif +#if defined(CONFIG_PROT_TCP) + case IPPROTO_TCP: + tcp = (struct tcp_hdr *)(((uchar *)ip6) + IP6_HDR_SIZE); + csum = tcp->tcp_xsum; + hlen = ntohs(ip6->payload_len); + tcp->tcp_xsum = 0; + /* checksum */ + csum_p = csum_partial((u8 *)tcp, hlen, 0); + tcp->tcp_xsum = csum_ipv6_magic(&ip6->saddr, &ip6->daddr, + hlen, IPPROTO_TCP, csum_p); + + if (csum != tcp->tcp_xsum) + return -EINVAL; + + tcp_headers = (union tcp6_build_pkt *)ip6; + rxhand_tcp6(tcp_headers, len); break; +#endif default: return -EINVAL; } diff --git a/net/tcp6.c b/net/tcp6.c new file mode 100644 index 0000000000..09b2190db7 --- /dev/null +++ b/net/tcp6.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 The Android Open Source Project + */ + +#if defined(CONFIG_PROT_TCP) + +#include +#include +#include +#include + +static rxhand_tcp6_f *tcp6_packet_handler; + +static void dummy_handler(uchar *pkt, u16 dport, + struct in6_addr sip, u16 sport, + u32 tcp_seq_num, u32 tcp_ack_num, + u8 action, unsigned int len) +{ +} + +void net_set_tcp_handler6(rxhand_tcp6_f *f) +{ + if (!f) + tcp6_packet_handler = dummy_handler; + else + tcp6_packet_handler = f; +} + +int net_set_tcp_header6(uchar *pkt, u16 dport, u16 sport, int payload_len, + u8 action, u32 tcp_seq_num, u32 tcp_ack_num) +{ + union tcp6_build_pkt *b = (union tcp6_build_pkt *)pkt; + int tcp_hdr_len; + int pkt_len; + u16 csum; + + pkt_len = IP6_HDR_SIZE; + tcp_hdr_len = net_set_tcp_header_common(&b->ip.tcp_hdr, &b->ip.tcp_o, + &b->sack.t_opt, &b->sack.sack_v, + dport, sport, payload_len, action, + tcp_seq_num, tcp_ack_num); + pkt_len += tcp_hdr_len; + pkt_len += payload_len; + + csum = csum_partial((u8 *)&b->ip.tcp_hdr, tcp_hdr_len + payload_len, 0); + b->ip.tcp_hdr.tcp_xsum = csum_ipv6_magic(&net_ip6, &net_server_ip6, + tcp_hdr_len + payload_len, + IPPROTO_TCP, csum); + + return tcp_hdr_len; +} + +void rxhand_tcp6(union tcp6_build_pkt *b, unsigned int len) +{ + int tcp_len = len - IP6_HDR_SIZE; + u8 tcp_action = TCP_DATA; + u32 tcp_seq_num, tcp_ack_num; + u32 res_tcp_seq_num, res_tcp_ack_num; + int tcp_hdr_len, payload_len; + + net_copy_ip6(&net_server_ip6, &b->ip.ip_hdr.saddr); + + tcp_hdr_len = GET_TCP_HDR_LEN_IN_BYTES(b->ip.tcp_hdr.tcp_hlen); + payload_len = tcp_len - tcp_hdr_len; + + if (tcp_hdr_len > TCP_HDR_SIZE) + tcp_parse_options((uchar *)b + IP6_HDR_SIZE + TCP_HDR_SIZE, + tcp_hdr_len - TCP_HDR_SIZE); + + tcp_seq_num = ntohl(b->ip.tcp_hdr.tcp_seq); + tcp_ack_num = ntohl(b->ip.tcp_hdr.tcp_ack); + + tcp_action = tcp_state_machine(b->ip.tcp_hdr.tcp_flags, + tcp_seq_num, &res_tcp_seq_num, &res_tcp_ack_num, + payload_len); + + if ((tcp_action & TCP_PUSH) || payload_len > 0) { + debug_cond(DEBUG_DEV_PKT, + "TCP Notify (action=%x, Seq=%u,Ack=%u,Pay%d)\n", + tcp_action, tcp_seq_num, tcp_ack_num, payload_len); + + (*tcp6_packet_handler) ((uchar *)b + len - payload_len, b->ip.tcp_hdr.tcp_dst, + b->ip.ip_hdr.saddr, b->ip.tcp_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=%u,Ack=%u,Pay=%d)\n", + tcp_action, res_tcp_seq_num, res_tcp_ack_num, payload_len); + + net_send_tcp_packet6(0, ntohs(b->ip.tcp_hdr.tcp_src), + ntohs(b->ip.tcp_hdr.tcp_dst), + (tcp_action & (~TCP_PUSH)), + res_tcp_seq_num, res_tcp_ack_num); + } +} + +#endif // CONFIG_PROT_TCP From patchwork Wed May 10 16:59:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1779641 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=AcQVCDDV; 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 4QGhB21Kqkz214S for ; Thu, 11 May 2023 03:00:58 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id AECDA86076; Wed, 10 May 2023 19:00:26 +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="AcQVCDDV"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DF5E386068; Wed, 10 May 2023 19:00:18 +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,T_SCC_BODY_TEXT_LINE,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 87C6B86073 for ; Wed, 10 May 2023 19:00:12 +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=3m81bZAkKBs4x268B277I08805y.w86E-v88D52CDC.xy7H.xy@flex--dimorinny.bounces.google.com Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-b9a6f15287eso11417037276.1 for ; Wed, 10 May 2023 10:00:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683738011; x=1686330011; 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=Boef0/kyv44xsg3XWmymCHfksKtwWOUURw9sPooLL+c=; b=AcQVCDDV7MN1fPbR/jyu5P6mHLMAIeq1SOPM38zSKdL3IAY31Kp1u2EiCz2U5kSakq xqShloFL0hA6x13gBkIPYcllOXpPVBNvZa6PzN/cSi8Iasr/lxJCh2dVenETe/evZF2V ShFYYXBcbrdsw+pPKkdkpygolPw9a/Vi0B/nCTxaQr0CJIwicOEY9ydBYEzoX54rTAT+ fWipJ0O3QiEf5M5eBQmeMBnhFYz6wRQy3VUe9sXqFPTvYOxZ13KV+JCS3/XX3SXTo+y2 dOM443xPEsRtTbi9URmnwRwXnVhSAx76zAhlW3pGC4zenJzHPA/Aw/Vvs0XSiT2fkLQ8 9PxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683738011; x=1686330011; 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=Boef0/kyv44xsg3XWmymCHfksKtwWOUURw9sPooLL+c=; b=kfkODIUlskluiNrijFe22kCBgUpkXUhsA+xBOEtnnquCNddqm3eMaJ0vvscBQssbIU W6vy2gD28asMNKfJnuzxYvlUTyE/BIF0mjN9gSfLHWsiPlc2zjAvEHVtwKThcs5r1NUM dOX/5Bfl+sx0BGMbAnFqooLzrvmDhXfV//QN9AzmuDreHdYVJWGJMCXmdc/N/GcOY/hF pZflBJGgYsVHb8G1DQ/qTgtaH9AxdqRBR8pKqtVO6JxGueuF95KQnG+MexMT1338EKaG 3pupGn1NIP9brpiQBWXzwf/l86FD+LCZlIrJ01rAX2huFqgrAkdaSRbZ9pBSb+AJZHq1 9Lyg== X-Gm-Message-State: AC+VfDzyfXgXfVAXUvS7OYnW4RRHAgPSGkmVIpv3pyOENuFdm9vxE9R0 q6UAbi2Q6OKXE+ZMWBCqMPR0pEnSw4a5ib4toYdYDohru0hwdpZIh8k7k0uIa4GvWRvnY1XVAn1 4Lj0zrgcFVkFRSWJAOLeUy7uPWMVUWSNdcn8htHdgdn62XZdmho/SRBe8vm767mNiLa4= X-Google-Smtp-Source: ACHHUZ7fAwCeSxTZjYlLf4uIO5La0uK6mnVq1CRPel6mxlj8O57gTjmK7NVU7GpzlpmI9T7SGgXUSDOQa3rhFQY= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:8054:7d60:263c:94b9]) (user=dimorinny job=sendgmr) by 2002:a25:1283:0:b0:b9a:672d:23c9 with SMTP id 125-20020a251283000000b00b9a672d23c9mr11088810ybs.0.1683738011070; Wed, 10 May 2023 10:00:11 -0700 (PDT) Date: Wed, 10 May 2023 17:59:57 +0100 In-Reply-To: <20230510165959.2228978-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230510165959.2228978-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230510165959.2228978-4-dimorinny@google.com> Subject: [PATCH v2 4/6] net: add fastboot TCP6 support From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.com, rfried.dev@gmail.com, Dmitrii Merkurev , Ying-Chun Liu , Simon Glass 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 fastboot tcp command remains the same, but started listening IP6 in case it's enabled. Signed-off-by: Dmitrii Merkurev Cc: Ying-Chun Liu (PaulLiu) Cc: Simon Glass Сс: Joe Hershberger Сс: Ramon Fried Reviewed-by: Ying-Chun Liu (PaulLiu) --- include/net/fastboot_tcp.h | 2 +- net/fastboot_tcp.c | 72 ++++++++++++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/include/net/fastboot_tcp.h b/include/net/fastboot_tcp.h index 6cf29d52e9..98986fa10a 100644 --- a/include/net/fastboot_tcp.h +++ b/include/net/fastboot_tcp.h @@ -7,7 +7,7 @@ #define __NET_FASTBOOT_TCP_H__ /** - * Wait for incoming tcp fastboot comands. + * Wait for incoming TCP fastboot comands. */ void fastboot_tcp_start_server(void); diff --git a/net/fastboot_tcp.c b/net/fastboot_tcp.c index 2eb52ea256..d93b52ede5 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -6,8 +6,10 @@ #include #include #include +#include #include #include +#include static char command[FASTBOOT_COMMAND_LEN] = {0}; static char response[FASTBOOT_RESPONSE_LEN] = {0}; @@ -20,18 +22,30 @@ static u16 curr_dport; static u32 curr_tcp_seq_num; static u32 curr_tcp_ack_num; static unsigned int curr_request_len; +static bool is_ipv6; +static size_t ip_header_size; static enum fastboot_tcp_state { FASTBOOT_CLOSED, FASTBOOT_CONNECTED, FASTBOOT_DISCONNECTING } state = FASTBOOT_CLOSED; +static int command_handled_id; +static bool command_handled_success; + 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); +#if defined(CONFIG_IPV6) + if (is_ipv6) { + net_send_tcp_packet6(len, htons(curr_sport), htons(curr_dport), + action, response_seq_num, response_ack_num); + return; + } +#endif net_send_tcp_packet(len, htons(curr_sport), htons(curr_dport), action, response_seq_num, response_ack_num); } @@ -47,7 +61,7 @@ static void fastboot_tcp_send_packet(u8 action, const uchar *data, unsigned int 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; + pkt += net_eth_hdr_size() + ip_header_size + TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; memcpy(pkt, data, len); fastboot_tcp_answer(action, len); memset(pkt, '\0', PKTSIZE); @@ -59,7 +73,7 @@ static void fastboot_tcp_send_message(const char *message, 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; + pkt += net_eth_hdr_size() + ip_header_size + TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; // Put first 8 bytes as a big endian message length memcpy(pkt, &len_be, 8); pkt += 8; @@ -68,10 +82,9 @@ static void fastboot_tcp_send_message(const char *message, unsigned int len) 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) +static void fastboot_tcp_handler(uchar *pkt, u16 dport, u16 sport, + u32 tcp_seq_num, u32 tcp_ack_num, + u8 action, unsigned int len) { int fastboot_command_id; u64 command_size; @@ -88,7 +101,6 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, case FASTBOOT_CLOSED: if (tcp_push) { if (len != handshake_length || - strlen(pkt) != handshake_length || memcmp(pkt, handshake, handshake_length) != 0) { fastboot_tcp_reset(); break; @@ -111,18 +123,25 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, pkt += 8; // Only single packet messages are supported ATM - if (strlen(pkt) != command_size) { + if (len != command_size) { fastboot_tcp_reset(); break; } strlcpy(command, pkt, len + 1); 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); + + command_handled_id = fastboot_command_id; + command_handled_success = strncmp("OKAY", response, 4) == 0; } break; case FASTBOOT_DISCONNECTING: + if (command_handled_success) { + fastboot_handle_boot(command_handled_id, command_handled_success); + command_handled_id = 0; + command_handled_success = false; + } + if (tcp_push) state = FASTBOOT_CLOSED; break; @@ -137,10 +156,41 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, curr_request_len = 0; } +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) +{ + is_ipv6 = false; + ip_header_size = IP_HDR_SIZE; + fastboot_tcp_handler(pkt, dport, sport, + tcp_seq_num, tcp_ack_num, + action, len); +} + +#if defined(CONFIG_IPV6) +static void fastboot_tcp_handler_ipv6(uchar *pkt, u16 dport, + struct in6_addr sip, u16 sport, + u32 tcp_seq_num, u32 tcp_ack_num, + u8 action, unsigned int len) +{ + is_ipv6 = true; + ip_header_size = IP6_HDR_SIZE; + fastboot_tcp_handler(pkt, dport, sport, + tcp_seq_num, tcp_ack_num, + action, len); +} +#endif + 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); + printf("Listening for fastboot command on tcp %pI4\n", &net_ip); tcp_set_tcp_handler(fastboot_tcp_handler_ipv4); + +#if defined(CONFIG_IPV6) + printf("Listening for fastboot command on %pI6\n", &net_ip6); + net_set_tcp_handler6(fastboot_tcp_handler_ipv6); +#endif } From patchwork Wed May 10 16:59:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1779644 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=qsP3Zd5i; 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 4QGhBz3zBlz214S for ; Thu, 11 May 2023 03:01:47 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id CA289860A6; Wed, 10 May 2023 19:00:31 +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="qsP3Zd5i"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0609786068; Wed, 10 May 2023 19:00:21 +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,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x54a.google.com (mail-ed1-x54a.google.com [IPv6:2a00:1450:4864:20::54a]) (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 F1C9085D1E for ; Wed, 10 May 2023 19:00:13 +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=3nc1bZAkKBtAz48AD499K2AA270.yA8G-xAAF74EFE.z09J.z0@flex--dimorinny.bounces.google.com Received: by mail-ed1-x54a.google.com with SMTP id 4fb4d7f45d1cf-50bcd245040so8794696a12.0 for ; Wed, 10 May 2023 10:00:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683738013; x=1686330013; 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=1YnWtjAjnpfMPLtYWnZgV9GPKfNowx6lAkaPGSHwf30=; b=qsP3Zd5idCWjQCKwZyZP9yMHMMYpzKi95hpaJ3FjLfYiVyAblL0qgewPUD5PCTTYPt bSVobb+5mivqdGHGEYCY3GzcBrdCvNz7eQc4G4V8zwjcT6/OdkyQZC3p6rdPzUH626Pk CxVhHwpRejqqpLlubhZMb3usQhHx8SZ50yXBxN1d4shWIZkmeFU6sKdELg0hAS35/gh4 AuLLUQrVt1555sgwSJOP77/BrFPc7irpopVAN579qNfDC4f9XJbD3GaqM0gGddKu7wo2 28q/oyVP42L6oc0QloTUzOdfxrPU2xTBmwh4wHNYVSP5b2BMYHM495GRKZdxKzwwsohx PWbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683738013; x=1686330013; 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=1YnWtjAjnpfMPLtYWnZgV9GPKfNowx6lAkaPGSHwf30=; b=IXdb9O0WR8Ujk6x/Md+LdKhaFLZxjJe+AMi+LzA4N0NxIvTcMBXFTztpy0i/zFo90R XGnYfbt3HiZj3BF2bSy71lcTqAuwKoblD4dch8GnCby8v/FitRxxUAk2ttBoA+TaINNA PascukXcNIZhrYoXAYX9G6WrHgmO1hnBYeZpIrIpYWGwimGYD7VYvRmUn6HXpMzVvT7b tOQzPJs4rXrmpId7rig8LPoJGGFBWiuXQJ/5skOayNvtmlUigbkXHzuc0lZMCVwkUAxY HBkUrM1DknLJyeiqqKzaRwb3h+XPTF3pa7YMnhOSUCONusavMG+amG1V6+B+a+Zmq1ER 2zMw== X-Gm-Message-State: AC+VfDzsi0IzziQU8SElwP89E9k+Yr5W53PMeGbbZcTHvxTWowz4TzEh uq4qVCnSBtx1HWhgXAwqzYjWUDMWAKaa6iktS9+8+VDubeCFNZTkhKX9AEQl6EjjllTGptAktIr PZHrQ90YhtEKOTkQbBUrQgxnez6yn4FNilrm8ncn9zC4pfaiYfZuzvyST2V5NgxOEUbI= X-Google-Smtp-Source: ACHHUZ5y4cD1SQ36wO/sHo7HNYub+jW18fD9jGs+7jYQkO3VOsPX3gRrVckfz4sLuL+od7lC1W/lmKVkZGZkoV4= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:8054:7d60:263c:94b9]) (user=dimorinny job=sendgmr) by 2002:a17:907:a057:b0:966:dd2c:500a with SMTP id gz23-20020a170907a05700b00966dd2c500amr4347750ejc.4.1683738013581; Wed, 10 May 2023 10:00:13 -0700 (PDT) Date: Wed, 10 May 2023 17:59:58 +0100 In-Reply-To: <20230510165959.2228978-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230510165959.2228978-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230510165959.2228978-5-dimorinny@google.com> Subject: [PATCH v2 5/6] net: add fastboot TCP documentation and IP6-only mode From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.com, rfried.dev@gmail.com, Dmitrii Merkurev , Ying-Chun Liu , Simon Glass 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 Command to start IP6 only TCP fastboot: fastboot tcp -ipv6 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 --- cmd/fastboot.c | 29 +++++++++++++++++++++++++---- doc/android/fastboot.rst | 8 +++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/cmd/fastboot.c b/cmd/fastboot.c index 3d5ff951eb..36f744ae01 100644 --- a/cmd/fastboot.c +++ b/cmd/fastboot.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -121,10 +122,23 @@ static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc, { uintptr_t buf_addr = (uintptr_t)NULL; size_t buf_size = 0; + bool is_ipv6_only = false; + bool is_usb = false; + bool is_udp = false; + bool is_tcp = false; if (argc < 2) return CMD_RET_USAGE; + if (IS_ENABLED(CONFIG_IPV6)) { + use_ip6 = false; + /* IPv6 parameter has to be always *last* */ + if (!strcmp(argv[argc - 1], USE_IP6_CMD_PARAM)) { + is_ipv6_only = true; + --argc; + } + } + while (argc > 1 && **(argv + 1) == '-') { char *arg = *++argv; @@ -159,11 +173,18 @@ NXTARG: fastboot_init((void *)buf_addr, buf_size); - if (!strcmp(argv[1], "udp")) + is_usb = strcmp(argv[1], "usb") == 0; + is_udp = strcmp(argv[1], "udp") == 0; + is_tcp = strcmp(argv[1], "tcp") == 0; + + if (is_ipv6_only && is_tcp) + use_ip6 = true; + + if (is_udp) return do_fastboot_udp(argc, argv, buf_addr, buf_size); - if (!strcmp(argv[1], "tcp")) + if (is_tcp) return do_fastboot_tcp(argc, argv, buf_addr, buf_size); - if (!strcmp(argv[1], "usb")) { + if (is_usb) { argv++; argc--; } @@ -174,7 +195,7 @@ NXTARG: U_BOOT_CMD( fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot, "run as a fastboot usb or udp device", - "[-l addr] [-s size] usb | udp\n" + "[-l addr] [-s size] usb | udp [-ipv6] | tcp [-ipv6]\n" "\taddr - address of buffer used during data transfers (" __stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n" "\tsize - size of buffer used during data transfers (" diff --git a/doc/android/fastboot.rst b/doc/android/fastboot.rst index 1ad8a897c8..aa6e9e5a9e 100644 --- a/doc/android/fastboot.rst +++ b/doc/android/fastboot.rst @@ -181,13 +181,19 @@ Enter into fastboot by executing the fastboot command in U-Boot for either USB:: => fastboot usb 0 -or UDP:: +UDP:: => fastboot udp link up on port 0, speed 100, full duplex Using ethernet@4a100000 device Listening for fastboot command on 192.168.0.102 +or TCP:: + + => fastboot tcp + Using ethernet@4a100000 device + Listening for fastboot command on 192.168.0.102 + On the client side you can fetch the bootloader version for instance:: $ fastboot getvar version-bootloader From patchwork Wed May 10 16:59:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1779643 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=q0gwAjbU; 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 4QGhBg3rRSz214S for ; Thu, 11 May 2023 03:01:31 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 312FE8607F; Wed, 10 May 2023 19:00:30 +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="q0gwAjbU"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 745FD84765; Wed, 10 May 2023 19:00:21 +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,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x54a.google.com (mail-ed1-x54a.google.com [IPv6:2a00:1450:4864:20::54a]) (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 6D2EA86076 for ; Wed, 10 May 2023 19:00:16 +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=3oM1bZAkKBtM27BDG7CCN5DD5A3.1DBJ-0DDIA7HIH.23CM.23@flex--dimorinny.bounces.google.com Received: by mail-ed1-x54a.google.com with SMTP id 4fb4d7f45d1cf-50daa85e940so4417350a12.0 for ; Wed, 10 May 2023 10:00:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683738016; x=1686330016; 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=85zcOFBjdKh3uQkTCEWFrH+Wzy6sNdZ9/otnJ507tyk=; b=q0gwAjbUfTNLO9+tNl2m0RLUvzk2iLAaYT1q0EBIfs53GTSEC1MBNeMmcE29984aip tkv2zotnQj4coSGecYPDJbiAZL2Bspa6upSSZQgy6Pf516jA52Kyf9V4l/xnKbc+Ylid rAzvCTDquJV1s7oAzF+HSVYFP43blQls+vLj9keveUKCcI8PKrywuQQstgm8lJWeT7jo aHX2qcfdrtwSqEsx3i/98tZWL0fYndWJtcfVlruSKhv0z+tMBdia/Jmm1M4xioH5GlaL DkKmZ1yPoB4+VQmvlp7ifL/K0gqVrMRELGYuZZbLwgfEzgfYpJmgU+/dnlDQ2FKnC+gP wpPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683738016; x=1686330016; 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=85zcOFBjdKh3uQkTCEWFrH+Wzy6sNdZ9/otnJ507tyk=; b=jcWanYA901VShd8fYU5eH7WbJ8trK9aUO9AUbqCxaSceqXGKlxopwQuQZrqettULhB HmBk7x8gFSmm7r7LF/WieNtwGKDwk5I9d7KisPydizxSybrUWtjA49eG5AjP1OlgJvKT O+Wt8S2u7wB1YD84CuoalWTjh4+PmUEm61gzEiosCM6oJ31d63n1Gh0lT46wW9XxyMZ6 PHhBcqGh+jfp0ReGS6ztNGJ+gFojpdp05d8XYGwSiDcHSMDPhFN17r7RKgm7EdCE8VMC w7qFp6NZqiRDRLcGmZ9d3udprTKwaJCuSW+zKXEPpJVKWLf2xl7/0A5cm/A54fUZo0th qJmA== X-Gm-Message-State: AC+VfDx3U6pjLAsrVKn9yzikNWsJLnz12q3JarLdI9gJTIzGhl9IyF0g 7Vsz/aXdlNtHmZ16dL+bUBjgI6Z6Lw/xwo8WAhVm+++WOObnDWOnfGXvZaYUxWxM/fo6oowrtFO toyB5axW+FccVjWPTi+nxxLj8+N/TA25snxHnRhBhbfhq1CRnPvdmxL9eaHUkkbZn8sU= X-Google-Smtp-Source: ACHHUZ56D259tR4wKEtFlXlorCfAb7Ckfv6AuSATtu6TjnVq5POD1KZPS/5T3CbtGb7HWuGb+CUYhkAm8N8Vw7A= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:8054:7d60:263c:94b9]) (user=dimorinny job=sendgmr) by 2002:a50:d09d:0:b0:50b:9f77:74b4 with SMTP id v29-20020a50d09d000000b0050b9f7774b4mr6681705edd.6.1683738016037; Wed, 10 May 2023 10:00:16 -0700 (PDT) Date: Wed, 10 May 2023 17:59:59 +0100 In-Reply-To: <20230510165959.2228978-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230510165959.2228978-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230510165959.2228978-6-dimorinny@google.com> Subject: [PATCH v2 6/6] net: update net_ip6 from link_local address when eth device is changed From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.com, rfried.dev@gmail.com, Dmitrii Merkurev , Ying-Chun Liu , Simon Glass 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 Current active eth device may be changed (due to ethprime), so make sure current net_ip6 is updated as a reaction. Signed-off-by: Dmitrii Merkurev Cc: Ying-Chun Liu (PaulLiu) Cc: Simon Glass Сс: Joe Hershberger Сс: Ramon Fried Reviewed-by: Simon Glass --- net/net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/net.c b/net/net.c index 9ef290dc41..0f14f29de8 100644 --- a/net/net.c +++ b/net/net.c @@ -359,10 +359,10 @@ static int net_init_loop(void) if (IS_ENABLED(CONFIG_IPV6)) { ip6_make_lladdr(&net_link_local_ip6, net_ethaddr); - if (!memcmp(&net_ip6, &net_null_addr_ip6, - sizeof(struct in6_addr))) - memcpy(&net_ip6, &net_link_local_ip6, - sizeof(struct in6_addr)); + if (memcmp(&net_link_local_ip6, &net_null_addr_ip6, + sizeof(struct in6_addr))) { + net_copy_ip6(&net_ip6, &net_link_local_ip6); + } } } else