public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Jon Maloy <jmaloy@redhat.com>
To: sbrivio@redhat.com, dgibson@redhat.com, jmaloy@redhat.com,
	passt-dev@passt.top
Subject: [PATCH v2 7/8] tcp: make tcp_rst_no_conn() respond with correct mac address
Date: Thu, 12 Jun 2025 00:21:51 -0400	[thread overview]
Message-ID: <20250612042152.695879-8-jmaloy@redhat.com> (raw)
In-Reply-To: <20250612042152.695879-1-jmaloy@redhat.com>

tcp_rst_no_conn() needs to identify and specify which source mac
address to use when sending an RST to the guest. This is because
it doesn't have access to any flow structure where this address
could be fetched.

Signed-off-by: Jon Maloy <jmaloy@redhat.com>
---
 tcp.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/tcp.c b/tcp.c
index 1a32424..b49f603 100644
--- a/tcp.c
+++ b/tcp.c
@@ -309,6 +309,7 @@
 #include "tcp_internal.h"
 #include "tcp_buf.h"
 #include "tcp_vu.h"
+#include "netlink.h"
 
 #ifndef __USE_MISC
 /* From Linux UAPI, missing in netinet/tcp.h provided by musl */
@@ -1888,6 +1889,9 @@ static void tcp_rst_no_conn(const struct ctx *c, int af,
 			    const struct tcphdr *th, size_t l4len)
 {
 	struct iov_tail payload = IOV_TAIL(NULL, 0, 0);
+	unsigned char src_mac[ETH_ALEN];
+	union inany_addr translated;
+	union inany_addr dst;
 	struct tcphdr *rsth;
 	char buf[USHRT_MAX];
 	uint32_t psum = 0;
@@ -1897,8 +1901,15 @@ static void tcp_rst_no_conn(const struct ctx *c, int af,
 	if (th->rst)
 		return;
 
+	/* If remote host on local network - respond with its mac address */
+	memcpy(src_mac, c->our_tap_mac, ETH_ALEN);
+	inany_from_af(&dst, af, daddr);
+	nat_outbound(c, &dst, &translated);
+	if (!memcmp(&dst, &translated, sizeof(dst)))
+		nl_mac_get(nl_sock, &dst, src_mac);
+
 	if (af == AF_INET) {
-		struct iphdr *ip4h = tap_push_l2h(c, buf, NULL, ETH_P_IP);
+		struct iphdr *ip4h = tap_push_l2h(c, buf, src_mac, ETH_P_IP);
 		const struct in_addr *rst_src = daddr;
 		const struct in_addr *rst_dst = saddr;
 
@@ -1908,7 +1919,7 @@ static void tcp_rst_no_conn(const struct ctx *c, int af,
 					      *rst_src, *rst_dst);
 
 	} else {
-		struct ipv6hdr *ip6h = tap_push_l2h(c, buf, NULL, ETH_P_IPV6);
+		struct ipv6hdr *ip6h = tap_push_l2h(c, buf, src_mac, ETH_P_IPV6);
 		const struct in6_addr *rst_src = daddr;
 		const struct in6_addr *rst_dst = saddr;
 
-- 
@@ -309,6 +309,7 @@
 #include "tcp_internal.h"
 #include "tcp_buf.h"
 #include "tcp_vu.h"
+#include "netlink.h"
 
 #ifndef __USE_MISC
 /* From Linux UAPI, missing in netinet/tcp.h provided by musl */
@@ -1888,6 +1889,9 @@ static void tcp_rst_no_conn(const struct ctx *c, int af,
 			    const struct tcphdr *th, size_t l4len)
 {
 	struct iov_tail payload = IOV_TAIL(NULL, 0, 0);
+	unsigned char src_mac[ETH_ALEN];
+	union inany_addr translated;
+	union inany_addr dst;
 	struct tcphdr *rsth;
 	char buf[USHRT_MAX];
 	uint32_t psum = 0;
@@ -1897,8 +1901,15 @@ static void tcp_rst_no_conn(const struct ctx *c, int af,
 	if (th->rst)
 		return;
 
+	/* If remote host on local network - respond with its mac address */
+	memcpy(src_mac, c->our_tap_mac, ETH_ALEN);
+	inany_from_af(&dst, af, daddr);
+	nat_outbound(c, &dst, &translated);
+	if (!memcmp(&dst, &translated, sizeof(dst)))
+		nl_mac_get(nl_sock, &dst, src_mac);
+
 	if (af == AF_INET) {
-		struct iphdr *ip4h = tap_push_l2h(c, buf, NULL, ETH_P_IP);
+		struct iphdr *ip4h = tap_push_l2h(c, buf, src_mac, ETH_P_IP);
 		const struct in_addr *rst_src = daddr;
 		const struct in_addr *rst_dst = saddr;
 
@@ -1908,7 +1919,7 @@ static void tcp_rst_no_conn(const struct ctx *c, int af,
 					      *rst_src, *rst_dst);
 
 	} else {
-		struct ipv6hdr *ip6h = tap_push_l2h(c, buf, NULL, ETH_P_IPV6);
+		struct ipv6hdr *ip6h = tap_push_l2h(c, buf, src_mac, ETH_P_IPV6);
 		const struct in6_addr *rst_src = daddr;
 		const struct in6_addr *rst_dst = saddr;
 
-- 
2.48.1


  parent reply	other threads:[~2025-06-12  4:22 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-12  4:21 [PATCH v2 0/8] use true mac address of LAN local remote hosts Jon Maloy
2025-06-12  4:21 ` [PATCH v2 1/8] netlink: Add function to extract mac addresses from arp table Jon Maloy
2025-06-12 15:17   ` Stefano Brivio
2025-06-13  6:11     ` David Gibson
2025-06-12  4:21 ` [PATCH v2 2/8] arp: respond with true mac address of LAN local remote hosts Jon Maloy
2025-06-12 15:17   ` Stefano Brivio
2025-06-12  4:21 ` [PATCH v2 3/8] flow: add mac address of LAN local remote hosts to flow Jon Maloy
2025-06-12 15:17   ` Stefano Brivio
2025-06-14 13:22     ` David Gibson
2025-06-12  4:21 ` [PATCH v2 4/8] udp: forward external source mac address through tap interface Jon Maloy
2025-06-12 15:17   ` Stefano Brivio
2025-06-12  4:21 ` [PATCH v2 5/8] tcp: " Jon Maloy
2025-06-12 15:17   ` Stefano Brivio
2025-06-12  4:21 ` [PATCH v2 6/8] tap: change signature of function tap_push_l2h() Jon Maloy
2025-06-12 15:17   ` Stefano Brivio
2025-06-12  4:21 ` Jon Maloy [this message]
2025-06-12 15:17   ` [PATCH v2 7/8] tcp: make tcp_rst_no_conn() respond with correct mac address Stefano Brivio
2025-06-12  4:21 ` [PATCH v2 8/8] icmp: let icmp use mac address from flowside structure Jon Maloy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250612042152.695879-8-jmaloy@redhat.com \
    --to=jmaloy@redhat.com \
    --cc=dgibson@redhat.com \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).