From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ecAggaBG; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id 694BF5A0280 for ; Sat, 07 Jun 2025 03:12:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749258728; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fNPJU+t5/p8WzwnVLJ3XLWiPNjMxVclJcYR0ryLeK8g=; b=ecAggaBGXyEqxi+U+ZlSF6u4/seHPs6Kh8fVrb5TIWMWTh6/n38kUG/FLHGbxZwKv5YQ+u oTccRz6U1qlhIrpvI8XSzN+9yA3oxuaRUYw27KX7SzXFZ9Lzptz0Aq3OU6xK3CySk2gjw1 IbZmMKNrzZThoBD/0nanFGas2VsoJ/8= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-693-lgMfk8xpOtaNLyCRodjYAQ-1; Fri, 06 Jun 2025 21:12:07 -0400 X-MC-Unique: lgMfk8xpOtaNLyCRodjYAQ-1 X-Mimecast-MFC-AGG-ID: lgMfk8xpOtaNLyCRodjYAQ_1749258726 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6597918002B0 for ; Sat, 7 Jun 2025 01:12:06 +0000 (UTC) Received: from jmaloy-thinkpadp16vgen1.rmtcaqc.csb (unknown [10.22.80.87]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 59AC618002B3; Sat, 7 Jun 2025 01:12:05 +0000 (UTC) From: Jon Maloy To: sbrivio@redhat.com, dgibson@redhat.com, jmaloy@redhat.com, passt-dev@passt.top Subject: [4/4] tcp: forward external source mac address through tap interface Date: Fri, 6 Jun 2025 21:11:51 -0400 Message-ID: <20250607011151.3290866-5-jmaloy@redhat.com> In-Reply-To: <20250607011151.3290866-1-jmaloy@redhat.com> References: <20250607011151.3290866-1-jmaloy@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 5bCqlF4wt7Bwhzh9xpsjIMqBtNNBKSIsRwYCjWbgHOk_1749258726 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true Message-ID-Hash: 6FGXPQNEUI47IJ7JWCXD7O5S75YKJT3J X-Message-ID-Hash: 6FGXPQNEUI47IJ7JWCXD7O5S75YKJT3J X-MailFrom: jmaloy@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: We forward the incoming mac address through the tap interface when receiving incoming packets from network local hosts. Packets from the local host are excepted from this rule, and are still forwarded with the default passt/pasta mac address as source. This is a part of the solution to bug #120 Signed-off-by: Jon Maloy --- tcp.c | 5 ++++- tcp_buf.c | 27 +++++++++++++-------------- tcp_internal.h | 2 +- tcp_vu.c | 5 ++--- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/tcp.c b/tcp.c index f43c1e2..777f345 100644 --- a/tcp.c +++ b/tcp.c @@ -920,7 +920,7 @@ static void tcp_fill_header(struct tcphdr *th, * @no_tcp_csum: Do not set TCP checksum */ void tcp_fill_headers(const struct tcp_tap_conn *conn, - struct tap_hdr *taph, + struct tap_hdr *taph, struct ethhdr *eh, struct iphdr *ip4h, struct ipv6hdr *ip6h, struct tcphdr *th, struct iov_tail *payload, const uint16_t *ip4_check, uint32_t seq, bool no_tcp_csum) @@ -952,6 +952,7 @@ void tcp_fill_headers(const struct tcp_tap_conn *conn, psum = proto_ipv4_header_psum(l4len, IPPROTO_TCP, *src4, *dst4); } + eh->h_proto = htons_constant(ETH_P_IP); } if (ip6h) { @@ -972,7 +973,9 @@ void tcp_fill_headers(const struct tcp_tap_conn *conn, &ip6h->saddr, &ip6h->daddr); } + eh->h_proto = htons_constant(ETH_P_IPV6); } + eth_update_mac(eh, 0, tapside->mac); tcp_fill_header(th, conn, seq); diff --git a/tcp_buf.c b/tcp_buf.c index d1fca67..2dbeca2 100644 --- a/tcp_buf.c +++ b/tcp_buf.c @@ -40,8 +40,7 @@ /* Static buffers */ /* Ethernet header for IPv4 and IPv6 frames */ -static struct ethhdr tcp4_eth_src; -static struct ethhdr tcp6_eth_src; +static struct ethhdr tcp_eth_hdr[TCP_FRAMES_MEM]; static struct tap_hdr tcp_payload_tap_hdr[TCP_FRAMES_MEM]; @@ -71,8 +70,10 @@ static struct iovec tcp_l2_iov[TCP_FRAMES_MEM][TCP_NUM_IOVS]; */ void tcp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s) { - eth_update_mac(&tcp4_eth_src, eth_d, eth_s); - eth_update_mac(&tcp6_eth_src, eth_d, eth_s); + int i; + + for (i = 0; i < TCP_FRAMES_MEM; i ++) + eth_update_mac(&tcp_eth_hdr[i], eth_d, eth_s); } /** @@ -85,8 +86,8 @@ void tcp_sock_iov_init(const struct ctx *c) struct iphdr iph = L2_BUF_IP4_INIT(IPPROTO_TCP); int i; - tcp6_eth_src.h_proto = htons_constant(ETH_P_IPV6); - tcp4_eth_src.h_proto = htons_constant(ETH_P_IP); + for (i = 0; i < TCP_FRAMES_MEM; i ++) + eth_update_mac(&tcp_eth_hdr[i], NULL, c->our_tap_mac); for (i = 0; i < ARRAY_SIZE(tcp_payload); i++) { tcp6_payload_ip[i] = ip6; @@ -164,6 +165,7 @@ static void tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn, struct tap_hdr *taph = iov[TCP_IOV_TAP].iov_base; const struct flowside *tapside = TAPFLOW(conn); const struct in_addr *a4 = inany_v4(&tapside->oaddr); + struct ethhdr *eh = iov[TCP_IOV_ETH].iov_base; struct ipv6hdr *ip6h = NULL; struct iphdr *ip4h = NULL; @@ -172,7 +174,7 @@ static void tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn, else ip6h = iov[TCP_IOV_IP].iov_base; - tcp_fill_headers(conn, taph, ip4h, ip6h, th, &tail, + tcp_fill_headers(conn, taph, eh, ip4h, ip6h, th, &tail, check, seq, no_tcp_csum); } @@ -194,14 +196,12 @@ int tcp_buf_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags) int ret; iov = tcp_l2_iov[tcp_payload_used]; - if (CONN_V4(conn)) { + if (CONN_V4(conn)) iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp4_payload_ip[tcp_payload_used]); - iov[TCP_IOV_ETH].iov_base = &tcp4_eth_src; - } else { + else iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp6_payload_ip[tcp_payload_used]); - iov[TCP_IOV_ETH].iov_base = &tcp6_eth_src; - } + iov[TCP_IOV_ETH] = IOV_OF_LVALUE(tcp_eth_hdr[tcp_payload_used]); payload = iov[TCP_IOV_PAYLOAD].iov_base; seq = conn->seq_to_tap; ret = tcp_prepare_flags(c, conn, flags, &payload->th, @@ -259,11 +259,10 @@ static void tcp_data_to_tap(const struct ctx *c, struct tcp_tap_conn *conn, check = &iph->check; } iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp4_payload_ip[tcp_payload_used]); - iov[TCP_IOV_ETH].iov_base = &tcp4_eth_src; } else if (CONN_V6(conn)) { iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp6_payload_ip[tcp_payload_used]); - iov[TCP_IOV_ETH].iov_base = &tcp6_eth_src; } + iov[TCP_IOV_ETH].iov_base = &tcp_eth_hdr[tcp_payload_used]; payload = iov[TCP_IOV_PAYLOAD].iov_base; payload->th.th_off = sizeof(struct tcphdr) / 4; payload->th.th_x2 = 0; diff --git a/tcp_internal.h b/tcp_internal.h index 36c6533..6c2d1ef 100644 --- a/tcp_internal.h +++ b/tcp_internal.h @@ -167,7 +167,7 @@ void tcp_rst_do(const struct ctx *c, struct tcp_tap_conn *conn); struct tcp_info_linux; void tcp_fill_headers(const struct tcp_tap_conn *conn, - struct tap_hdr *taph, + struct tap_hdr *taph, struct ethhdr *eh, struct iphdr *ip4h, struct ipv6hdr *ip6h, struct tcphdr *th, struct iov_tail *payload, const uint16_t *ip4_check, uint32_t seq, bool no_tcp_csum); diff --git a/tcp_vu.c b/tcp_vu.c index f3914c7..da1fb37 100644 --- a/tcp_vu.c +++ b/tcp_vu.c @@ -135,7 +135,7 @@ int tcp_vu_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags) flags_elem[0].in_sg[0].iov_len = hdrlen + optlen; payload = IOV_TAIL(flags_elem[0].in_sg, 1, hdrlen); - tcp_fill_headers(conn, NULL, ip4h, ip6h, th, &payload, + tcp_fill_headers(conn, NULL, eh, ip4h, ip6h, th, &payload, NULL, seq, !*c->pcap); if (*c->pcap) { @@ -315,7 +315,6 @@ static void tcp_vu_prepare(const struct ctx *c, struct tcp_tap_conn *conn, eh = vu_eth(base); memcpy(eh->h_dest, c->guest_mac, sizeof(eh->h_dest)); - memcpy(eh->h_source, c->our_tap_mac, sizeof(eh->h_source)); /* initialize header */ @@ -339,7 +338,7 @@ static void tcp_vu_prepare(const struct ctx *c, struct tcp_tap_conn *conn, th->ack = 1; th->psh = push; - tcp_fill_headers(conn, NULL, ip4h, ip6h, th, &payload, + tcp_fill_headers(conn, NULL, eh, ip4h, ip6h, th, &payload, *check, conn->seq_to_tap, no_tcp_csum); if (ip4h) *check = &ip4h->check; -- 2.48.1