From patchwork Mon May 8 17:15:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1778510 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=e/zlh3Xg; 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 4QFScT3r1mz20fl for ; Tue, 9 May 2023 03:16:07 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B04BA84777; Mon, 8 May 2023 19:15:58 +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="e/zlh3Xg"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 133D184777; Mon, 8 May 2023 19:15:58 +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-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) (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 1F4C38475C for ; Mon, 8 May 2023 19:15:55 +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=3SS5ZZAkKBjQTYcehYddoWeeWbU.Seck-ReejbYiji.TUdn.TU@flex--dimorinny.bounces.google.com Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-b9a6eeea78cso35566633276.0 for ; Mon, 08 May 2023 10:15:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683566153; x=1686158153; h=content-transfer-encoding:cc:to:from:subject:message-id :mime-version:date:from:to:cc:subject:date:message-id:reply-to; bh=y1WQN577Kt5HYSVUxq73xZDoxroCkBT+k+E7iQZyUIA=; b=e/zlh3XgJqi9j3pQV8jKDXVO7Fwqnprxh79KRH9Wgm5bkfxC4qsYfBjq8sR9FVQRyo MTkZ5wSQB8GrVzLgT40RyNF5z4wdZxa0PF9TaeV5ZxEYQvepFiRCGVRXK8xTF/QEFwZz JbmU6gChIiKThYqhKCz52sa29U4ElPJiKtbIUbQmyWNBo0PX9m6eG2vNAhnBgI+plI4p GeTa3RHBx/aMS98T0SVlpJA8W1ctlDUS9PKn53K1ZfsBTHjOLGRjbFjKRDnF9Bfb9xUB qtmq0PZVK4L6zIgihlHYEYqfqRmrM3GwEV2uibnu076+ReKSf86JeMdZfq1esYvzaIax QMLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683566153; x=1686158153; 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=y1WQN577Kt5HYSVUxq73xZDoxroCkBT+k+E7iQZyUIA=; b=jYw3U5mickFGPRu0CX6Rd6tM8MV2HtsSySPp5VoaeY7quM2hmOU5sqSUjG8A9c3Sx4 ojP6BCkMY6fxS2QNIpWnJkzmEeZKO6lQgxxElYf30UQVfTpbpqpnX9XuqjyoPquBI5kv lxDQtQmECkT3NV/4UGiH98Zenjlc7g1LbNGSnbQdn4HXaxwGyln98mLV8ZKjdrwYNR03 c4gAaPgxxAIT4DN75F1TTjRFQ5u6drPADPwmYWtJJJUx/Hch0fFKURfUM7IGfV/N4q0B HTL+lqFb2XRj8jpUpsctWeUG2cxrxRbyL/6HPRstAhrkOO/x8CMvDmDuyYE1PpaqAX2B SafA== X-Gm-Message-State: AC+VfDwecuA4ldoxd022SpvzHh1Tyu94wx3KGzE2B2E6qRbuCFWPb83Z 3f6OXBhzMqI0vBu/vTdBVOP3goxznkVD2SXi7kbbrvzBYO7L10676fliz9I/XOBRA9STsS1Hzl/ onLL3E/kX7d2nLSb8v1kRD9Svs76In6vet6slevTmJV//3pm/qSDEfQpw0+6wiOZpTng= X-Google-Smtp-Source: ACHHUZ5BWafqZkWygo/un4ejO3zM8XJ4ggrA6DqnSTpUvvrVc75hS5vOj5Upaf6FTdL9WwWn9nuZD8iB13OkMoo= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:f357:b9b:9cec:e681]) (user=dimorinny job=sendgmr) by 2002:a25:4503:0:b0:b94:6989:7fa6 with SMTP id s3-20020a254503000000b00b9469897fa6mr6820818yba.4.1683566153597; Mon, 08 May 2023 10:15:53 -0700 (PDT) Date: Mon, 8 May 2023 18:15:20 +0100 Mime-Version: 1.0 X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230508171525.1082432-1-dimorinny@google.com> Subject: [PATCH 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, 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 --- include/net/tcp.h | 50 ++++++++++++++------------------- net/tcp.c | 70 +++++++++++++++++++++++------------------------ test/cmd/wget.c | 16 +++++------ 3 files changed, 64 insertions(+), 72 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index c29d4ce24a..5ab1127d8b 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,13 +186,15 @@ 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 ip_hdr ip_hdr; + struct tcp_hdr tcp_hdr; struct tcp_t_opt t_opt; struct tcp_sack_v sack_v; u8 end; @@ -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..fd6ed26e8a 100644 --- a/test/cmd/wget.c +++ b/test/cmd/wget.c @@ -52,9 +52,9 @@ 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 tcp_hdr *tcp = packet + ETHER_HDR_SIZE + IP_HDR_SIZE; struct ethernet_hdr *eth_send; - struct ip_tcp_hdr *tcp_send; + struct tcp_hdr *tcp_send; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -64,7 +64,7 @@ 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; + tcp_send = (void *)eth_send + ETHER_HDR_SIZE + IP_HDR_SIZE; tcp_send->tcp_src = tcp->tcp_dst; tcp_send->tcp_dst = tcp->tcp_src; tcp_send->tcp_seq = htonl(0); @@ -97,9 +97,9 @@ 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 tcp_hdr *tcp = packet + ETHER_HDR_SIZE + IP_HDR_SIZE; struct ethernet_hdr *eth_send; - struct ip_tcp_hdr *tcp_send; + struct tcp_hdr *tcp_send; void *data; int pkt_len; int payload_len = 0; @@ -115,7 +115,7 @@ 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; + tcp_send = (void *)eth_send + ETHER_HDR_SIZE + IP_HDR_SIZE; tcp_send->tcp_src = tcp->tcp_dst; tcp_send->tcp_dst = tcp->tcp_src; data = (void *)tcp_send + IP_TCP_HDR_SIZE; @@ -163,14 +163,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 = ip + 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 Mon May 8 17:15:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1778511 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=cKpTIKWu; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QFScf2Rx3z20fl for ; Tue, 9 May 2023 03:16:18 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BB9C785F18; Mon, 8 May 2023 19:16: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=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="cKpTIKWu"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1B2DB85F3D; Mon, 8 May 2023 19:16:01 +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 CC94785AFF for ; Mon, 8 May 2023 19:15:56 +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=3TC5ZZAkKBjcWbfhkbggrZhhZeX.Vhfn-Uhhmeblml.WXgq.WX@flex--dimorinny.bounces.google.com Received: by mail-ed1-x54a.google.com with SMTP id 4fb4d7f45d1cf-50bffc723c5so4506937a12.1 for ; Mon, 08 May 2023 10:15:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683566156; x=1686158156; 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=B75nH9kczAPt4RGUNv+lZ+fPPipO/iQov4QjL/fstFc=; b=cKpTIKWu6tvsGS2NF7oJmOU3gXZiOuLZsuOp3GCr8DrFp+6gYFSm2UnG3UkhQ5kqe6 ugeXhSvRM0U2YmvEd5Tc0ss0vIcx0FiWdqmA9jBZU9AZhc8XVm96bD0l3ATminN5Fvho U++nJpsCMrQKtsscestPLYlEg1v4uGAVZyOp/FpMFjo2DZiS2moNwfbpQ9uul+eJcZZe QD5WsY3MXqWlbdulUyi3bIapawCFd+eHecYGVb8wkOuXuhSjTCXvNfzVPMftqQ3z/1AQ Z4qDEUcG0N/e6vT3hR+UGI4y43N3anQCaRZnpSCU3kk+B64iuun0WYeckgYjpEgWOMwq w1jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683566156; x=1686158156; 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=B75nH9kczAPt4RGUNv+lZ+fPPipO/iQov4QjL/fstFc=; b=FvrFoY9/c1ce5n2OyTsiFuMrQVGgYLydZE9H/k41OjHnr+0kJpgvPH1KKLONCWnPVK c09rnbFU3RZOz0sSN+KeFYczxFVq+c3AUObEGypj0ToV0LZpcOOCG+1Gqs+pnubFVfR4 hVRFvozLL7j09vqV//dgKIXXFg1/gdGalAg3VhXfoZzRy5gGw/MzkIb0gyS5reRVVPS4 Bbu1+4yZC9cfZIWqtvTHjaqFcDJisVnBSWVbycVEoVgQ0wAROldUe2IU7LvztDNBb9r5 SbvkdtzVvoB6S0TZwLzTa7gyhLgOi+mCrmCY4NQTpGhcKcebSEI31UhMnQIRgj/KgOk0 iqRQ== X-Gm-Message-State: AC+VfDzGuWWcxrIYLHEPuppA6qhYZokw+58OyUHHzvwgce2pFujkzMMG tYV1S6Z3NYjuCgWkS6sb+V99Uu+KSlcq9eUtEcbBr9puZe09greu9FqmVLXFWJaJ8i8C5TpO/8Z TysKDbalF8OXENZ4xX3R3qyHthHVlid/YsELwJ/MfD12qBvRWX3CgmDqrpmLsTW5e0g0= X-Google-Smtp-Source: ACHHUZ7IYgyJ3Omm7lYQAwc9mTykvjidWKdnKARxbZ5eoGl+gVwHZRe8jJC8O43ODLKgP3VfL2Re9dI4gR9isZY= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:f357:b9b:9cec:e681]) (user=dimorinny job=sendgmr) by 2002:a17:906:8471:b0:965:ecf8:4af5 with SMTP id hx17-20020a170906847100b00965ecf84af5mr4094763ejc.12.1683566156208; Mon, 08 May 2023 10:15:56 -0700 (PDT) Date: Mon, 8 May 2023 18:15:21 +0100 In-Reply-To: <20230508171525.1082432-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230508171525.1082432-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230508171525.1082432-2-dimorinny@google.com> Subject: [PATCH 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, 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 --- 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 5ab1127d8b..1332f19153 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 Mon May 8 17:15:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1778512 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=EG1c+bZV; 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) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QFScy3xJgz20fl for ; Tue, 9 May 2023 03:16:34 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0919C85ED7; Mon, 8 May 2023 19:16: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=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="EG1c+bZV"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1C1D085F0D; Mon, 8 May 2023 19:16:05 +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-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) (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 416B885F0D for ; Mon, 8 May 2023 19:16:00 +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=3Ti5ZZAkKBjkYdhjmdiitbjjbgZ.Xjhp-Wjjogdnon.YZis.YZ@flex--dimorinny.bounces.google.com Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-b9a7553f95dso9771795276.2 for ; Mon, 08 May 2023 10:16:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683566159; x=1686158159; 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=h8Jzcu8sP+YCRT1F6OuKkxCXE61b/YXFkhA5NljHh7g=; b=EG1c+bZVLf5GFTCJ3rFfowuzkmUP/XqkDj2CFiaZqwD6Oboo2Qvvp1PCQ/bbPKag6n 5UvoQwXboKGw7M7JhPTPanMasj1jiEqbdhoff9XBQcuePVhLVptYMq3Y/hUSXC5HoFJ5 rlwhy0VQlY4RUH+nuiPGAXrAV/2H/oDdzuZbzQOOphtMpeZP3sktGxVsvUAtNFu1SZZb VwTgf3XpzqToO8SkvPwUzBUXpYIbZI4t3rxVEam0JxpMSUIUpGgQDiyn8gNGVvKlyzG0 cJ4H3UrHIKbw+DdLNuxIHwtn3IzAYaA3dOoyrof6WbP9Z9uAXtnfB8hAByJi+Tuka/iG 0ldg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683566159; x=1686158159; 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=h8Jzcu8sP+YCRT1F6OuKkxCXE61b/YXFkhA5NljHh7g=; b=DBE065RHU8/tJ9dkd7MX7PV1J76SctYedyx/gVERGriCU91jruR6VL5iBqAUuHpWDb RqYlOATt2kbuwNbR5dyjdeHYwGNoGr759UGyyzUkGp0ec78tcdjTgENvgmwpMVQwv6Ja h9c2JvnXc5Y3FS8NiIlr9v8a5wyOwZzRym7n+t5AmoExUIe1/VJhCi8e2o/dwQUezaaI J7af7kWPVQV+yngE/EyExEBc+0Y7uTYsUaZM5dODlkVZQPHrVCgzNCfTdtB1yUbW9oyT IMj/ZehUKW+blUFSrjCGPTdQ+kdIsNIrjj/EMZkRSCeex/qPyCXpm33DK73NMe5hz13d bHCA== X-Gm-Message-State: AC+VfDyRX+kCSJjdOwOHKn/8RhXe9dkvgy/Zf+Mc3Zb7DkEr0urQqW0A Fj1u3teqX+YHs2zTLfnu9eidi1XOqSJyyIDxfY8qliwhgpw4xTsCzD+ut32+e3vBtfWJbUjAu0A uTNW/IKLnH8gshIp+nTIbuNRKTrvgXwq+UQrC1BK10rd0XbnJp0/n4jtm9biTSiUBVR8= X-Google-Smtp-Source: ACHHUZ6OqXeGGl5JggX6Z4nWbCos6lx5J0RpJ74OjPFNdLM8a9dugIushBDarGGgfnfdZEBl8iMLsv9bLAq3SrY= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:f357:b9b:9cec:e681]) (user=dimorinny job=sendgmr) by 2002:a5b:1c1:0:b0:b9e:1436:990e with SMTP id f1-20020a5b01c1000000b00b9e1436990emr6902693ybp.3.1683566158917; Mon, 08 May 2023 10:15:58 -0700 (PDT) Date: Mon, 8 May 2023 18:15:22 +0100 In-Reply-To: <20230508171525.1082432-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230508171525.1082432-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230508171525.1082432-3-dimorinny@google.com> Subject: [PATCH 3/6] net: introduce TCP/IP6 support From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.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 --- include/net/tcp6.h | 103 +++++++++++++++++++++++++++++++++++++++++++++ include/net6.h | 14 ++++++ net/Makefile | 1 + net/net.c | 6 +++ net/net6.c | 43 ++++++++++++++++++- net/tcp6.c | 95 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 260 insertions(+), 2 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..102f5a240a --- /dev/null +++ b/include/net/tcp6.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2022 The Android Open Source Project + */ + +#ifndef __TCP6_H__ +#define __TCP6_H__ + +#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 // __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..3fc6681898 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) + 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..6418611403 100644 --- a/net/net6.c +++ b/net/net6.c @@ -14,6 +14,7 @@ #include #include #include +#include #include /* NULL IPv6 address */ @@ -362,8 +363,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 +378,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 +424,21 @@ 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) { + union tcp6_build_pkt *tcp_headers; struct in_addr zero_ip = {.s_addr = 0 }; struct icmp6hdr *icmp; struct udp_hdr *udp; + struct tcp_hdr *tcp; u16 csum; u16 csum_p; u16 hlen; @@ -475,6 +498,22 @@ int net_ip6_handler(struct ethernet_hdr *et, struct ip6_hdr *ip6, int len) ntohs(udp->udp_src), ntohs(udp->udp_len) - 8); break; + 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; default: return -EINVAL; } diff --git a/net/tcp6.c b/net/tcp6.c new file mode 100644 index 0000000000..9add8cddab --- /dev/null +++ b/net/tcp6.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 The Android Open Source Project + */ + +#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); + } +} From patchwork Mon May 8 17:15:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1778513 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=q2IX6/Hb; 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 4QFSdD2Qg0z20fl for ; Tue, 9 May 2023 03:16:48 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 598DD85F7F; Mon, 8 May 2023 19:16:09 +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="q2IX6/Hb"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5885585F3D; Mon, 8 May 2023 19:16:06 +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-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) (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 947998472A for ; Mon, 8 May 2023 19:16:03 +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=3US5ZZAkKBjwbgkmpgllwemmejc.amks-Zmmrjgqrq.bclv.bc@flex--dimorinny.bounces.google.com Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-559d35837bbso91287817b3.3 for ; Mon, 08 May 2023 10:16:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683566161; x=1686158161; 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=jE/yD2GXrl1fTZwM4VoEfyvlaBj4jxtqyzrp5oD8vQk=; b=q2IX6/Hb0AnDKvACuq3dFpuZFKmtQYe3P7bVuMakOY06jfchPtYIJxhVHS6Ubsi93i r2l1u9lev4cAqBVMiW4RUtPuSuXgkQb1HxQEyYFnvDbobXMawqSC2zIEiSwBTVVF+RZd uSiqUQjZxJHbao9f77XmQ4RVvdpa9NOXta3J3Chi3WtrJWsT3+JNB4S3ccaEhQwC3bO4 sy5dP2Ymav2pavqyxoPEYtGHWKdSOZvJZF1mSw1JXnbn5fzIIIsy6gDrB5uzV3LNf/OI /yJpRNeOSfsVTVztTOn2/uA7+cFpiUb3O3u0NUwOStz/I6Hf1Na8R+RaODwmZm/S5vj1 kohw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683566161; x=1686158161; 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=jE/yD2GXrl1fTZwM4VoEfyvlaBj4jxtqyzrp5oD8vQk=; b=C03NzuQzoKi+Qmcr2B3ttXjUOMH/Tgo79UiCDa2MX4VbJgxHFvyQZA7R5fBt1ViTEY f/OSKZOSFpSexpKO7xMgJulFlbMdUdhqtdi667gKQepUxOpYBKtIGriq2SHaBx7l+FZe j0KpcRB04X9crs8/dNK7HT1OOi4ohfVHsewBRtWAXYXZWvv+GPgaXdkyMzB8/c6rr6Oe NISF0pvPwZU68crVpBNCTyg8TSlInoX2LHra9Qtx2tBxvnAxqfa/63yz3DtAyRcwiMym fjJI8W9N0+S6hTvTjB2TdVVY8at6iRDJsaN6dwCVYFPBNSgDMreHE9Qqhe7Y6c6aT/w9 aM0Q== X-Gm-Message-State: AC+VfDwh1OqOldG1x/KxMjRNGwz34AV+/2ky5BsGV/OZaRDiLNSrjFN4 k8ZwxxvWXN79AL71D7Mg83/948Sdsn+NVAQ5IIh+P5fMqMOTowOdNr+H616gIOIjgrR/VimcACz qyYMYSHmnXRkiwSv6pTeshA7tqLePR9rWLIUK+X4esHBc528VkgQvnGeBMZRPVXKrzUY= X-Google-Smtp-Source: ACHHUZ5+tKskY0ilqgcfS8K8+YpoQ4Awufd0UftsSSk1JoC5KGPFmGm04b7AfWaH3U41bAo94YvlG7jnmcNlKkY= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:f357:b9b:9cec:e681]) (user=dimorinny job=sendgmr) by 2002:a81:ae54:0:b0:559:f89f:bc81 with SMTP id g20-20020a81ae54000000b00559f89fbc81mr6732832ywk.6.1683566161331; Mon, 08 May 2023 10:16:01 -0700 (PDT) Date: Mon, 8 May 2023 18:15:23 +0100 In-Reply-To: <20230508171525.1082432-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230508171525.1082432-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230508171525.1082432-4-dimorinny@google.com> Subject: [PATCH 4/6] net: add fastboot TCP6 support From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.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 --- 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 Mon May 8 17:15:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1778514 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=rwCv+bAN; 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 4QFSdV1Q0Xz20fl for ; Tue, 9 May 2023 03:17:02 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 821A985FD0; Mon, 8 May 2023 19:16:10 +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="rwCv+bAN"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id CCC108472A; Mon, 8 May 2023 19:16:06 +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 53C2285AFF for ; Mon, 8 May 2023 19:16: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=3Uy5ZZAkKBj4inrtwnss3lttlqj.htrz-gttyqnxyx.ijs2.ij@flex--dimorinny.bounces.google.com Received: by mail-ed1-x54a.google.com with SMTP id 4fb4d7f45d1cf-50bc1a01cffso4357747a12.3 for ; Mon, 08 May 2023 10:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683566164; x=1686158164; 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=r5Tr3cdCBXDTyDSyppOpOo//wA42E3OsCAt8r///DhI=; b=rwCv+bANM3RFXio6fs/ihVOMcTibKuweIRsaogBKig9mIwHEUb5LDX3Dja4mUZZ/L4 uN24V7gVZmEzY5AkZzYzlOqxF7kh2Jv87C0MqYu9NZIR6xpLXTgcyGGp91v04OdATmE1 eCeTKltUf+ZGUNGazYcqhvYwL+cQd8eIj1AM2V5XYyWZsmva1vwYufv7xGcjgI5698rh 0qNim4bUyHODFxEOErNPLv9fMfhVkMuOPROFLenaLElQwXIj5NrgBGEJ0e48M7V0svNf cePvwWdWXkOUkZXo5O0QBII0Nk7hhHjem6/AF09Mwk/0Jult5MrzLoyUedx7xWPhImH7 jNeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683566164; x=1686158164; 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=r5Tr3cdCBXDTyDSyppOpOo//wA42E3OsCAt8r///DhI=; b=apVk4qjHNAULIrxyXKdfWWUmCoR4AoUahBoej2rAbadvDNlel/qiy8mZW4LYU2GkdC 51XqSEM47o7brXBzr/TzPi8BAlWo7ciSbYemJU2SXB5278h5VudOpCriSN7tOEVKkivH 4gMcvxBBfBRZbbv0CF/SVj47XHPGF1H0+KT0NhimrVu8itLSmSAXXhZ59bQdcdB4l0Pn wMyiUmmrf++arBp+yMPxDOLecWH2mOVjzJb0LjLaFH5AUyb7HrLeuQPqN/8sdte9eNLH pCn43Uni22HNRNih3FzVNa8aq0pGFdoPIyrCRfd//Rv055pNwRpakRXUQwTb0eNqUa4R ReGQ== X-Gm-Message-State: AC+VfDw9nUN0Bjai3CnvlG3OMTcgTyQspYer+yhFBRj/08TtXf2Dl3g8 ZyL4tCCRdpXU1nlFF6Y3mVUa4Fp1NHMNIah3fCl9JhJwEWgAl33ZyD0TN2AZiZ6YShL/S2vKYuv OOvv+UnzkhSyTHohvKlC1O8x6rhEazJzzQkKo0kBgFQYlUc1yotNWhAJLth9rz5RQ0m8= X-Google-Smtp-Source: ACHHUZ7Z19Qb9je8RjIilHfOXvDpIolvJ+NAedhcW6L7Y2euTsA5tn8AAHzb9OpPC0u+22FTMo+zlbYmdAy9bu8= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:f357:b9b:9cec:e681]) (user=dimorinny job=sendgmr) by 2002:a17:907:1dcf:b0:95e:d417:ee25 with SMTP id og15-20020a1709071dcf00b0095ed417ee25mr4075916ejc.11.1683566163893; Mon, 08 May 2023 10:16:03 -0700 (PDT) Date: Mon, 8 May 2023 18:15:24 +0100 In-Reply-To: <20230508171525.1082432-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230508171525.1082432-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230508171525.1082432-5-dimorinny@google.com> Subject: [PATCH 5/6] net: add fastboot TCP documentation and IP6-only mode From: Dmitrii Merkurev To: u-boot@lists.denx.de Cc: rammuthiah@google.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) --- 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 Mon May 8 17:15:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitrii Merkurev X-Patchwork-Id: 1778515 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=sKK3fDXY; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QFSdm0k6Xz20fl for ; Tue, 9 May 2023 03:17:16 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D67AC85FE8; Mon, 8 May 2023 19:16:11 +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="sKK3fDXY"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E07EB8472A; Mon, 8 May 2023 19:16:09 +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-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 92F0B8472A for ; Mon, 8 May 2023 19:16:07 +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=3Vi5ZZAkKBkEglprulqq1jrrjoh.frpx-errwolvwv.ghq0.gh@flex--dimorinny.bounces.google.com Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-55a1aec6693so80480087b3.1 for ; Mon, 08 May 2023 10:16:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683566166; x=1686158166; 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=cKfktSIGkcx2yiot5x4fmTw0uXf3lZzp2TCmaMfGs2c=; b=sKK3fDXYEITYXom+h87dUgwiC5f9/Hu1wWgP/d8xsRRa1yXuXUkODvCOJuRIqxLnfa VRxmeo7H/wcWjNTfaHdQyjNCWgV/ugz+MvyEl8LQk/oZd1kW016jONYEEHPJJtRa1fhY lIeWEAWpmY91C8YDbx8sRHYVY13MWbWWVKZp/FPChO2v2M/6pgoF7FWJOgNMMET9kWtb TqNE/0B+hAQPS19KeidLzfx5f88j8OGKp5OxE7EEulgVq1WTRlceFnZXLSUsxwt3Fip7 Zegq1QMa1YP1wOTwWLQuMZxUiF4TI81l/Svs6+JleHg3ZKghovVSG5cDu/8ybDWC1xhW t+pQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683566166; x=1686158166; 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=cKfktSIGkcx2yiot5x4fmTw0uXf3lZzp2TCmaMfGs2c=; b=j9GJJyIIXmnk9z1GAh1xjjAbeyOC5SrEB83/YcHk0OFu9uLT+g/lMGgTgL6DbWxADY YOMoaM+dWzxSPuujvMGwmQgOfjuCb3zVRqtKONbRRK3hK3tMjYQAu0G+k2TUhi3skta1 nGTYmzQ4AWgM8RsY9CpE7oBmAE5tHS3C3N8cUS+pUXPkUE3tKUPZMnbC5KxlqVpypOmJ BbAH3AoI3IINSp2b5R0IA5kEbXYqtG/HgzHYQruCTkjIuJy5mA5E1iwqWrDVVrun6CDF 1RyNk6RHB5o1LYBk+nIe4Z2Yw5UVbjhHw9Dc1Lnepl8lST0/oMfRUD439eeYBnvDh7Dy F4pQ== X-Gm-Message-State: AC+VfDwSejuIkGGT53FeEZ0FHbn3BIRvtDenVPUz2305a8cnHVZGUB4s WhnyzRS3JrzuyCMWo81ynPwNbiJVOSDwXtvlYIRPgJlVmQuq5qnlGUGpMhRbhIjJJOTWWi4navn X2/4j4wd/+iYZMIxHsL7ja3DITxZsEvrQAKMifzTy/DRZqlshZf5HFwh5MwnhoIy+Fak= X-Google-Smtp-Source: ACHHUZ5oHGMbRAbRTlZaNURF/scfkBJ5cW1T+qVOD7QEUHzhj2hoskOvnpePPK41mfvM08yMxmSzCldMyOrhivM= X-Received: from dimorinny0.lon.corp.google.com ([2a00:79e0:d:209:f357:b9b:9cec:e681]) (user=dimorinny job=sendgmr) by 2002:a81:a9c5:0:b0:556:2da0:fb8 with SMTP id g188-20020a81a9c5000000b005562da00fb8mr6570116ywh.7.1683566166327; Mon, 08 May 2023 10:16:06 -0700 (PDT) Date: Mon, 8 May 2023 18:15:25 +0100 In-Reply-To: <20230508171525.1082432-1-dimorinny@google.com> Mime-Version: 1.0 References: <20230508171525.1082432-1-dimorinny@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230508171525.1082432-6-dimorinny@google.com> Subject: [PATCH 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, 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 --- net/net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/net.c b/net/net.c index 3fc6681898..a52c110d93 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