public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
* [PATCH] tcp: Get socket port and address using getsockname() when connecting from guest
@ 2025-02-04  0:05 Stefano Brivio
  0 siblings, 0 replies; only message in thread
From: Stefano Brivio @ 2025-02-04  0:05 UTC (permalink / raw)
  To: passt-dev; +Cc: David Gibson

For migration only: we need to store 'oport', our socket-side port,
as we establish a connection from the guest, so that we can bind the
same oport as source port in the migration target.

Similar for 'oaddr': this is needed in case the migration target has
additional network interfaces, and we need to make sure our socket is
bound to the equivalent interface as it was on the source.

Use getsockname() to fetch them.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
Note: I'm merging this right now, but posting anyway to ease review.

 flow.c       |  4 ++--
 flow_table.h |  4 ++--
 tcp.c        | 26 +++++++++++++++++++++++++-
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/flow.c b/flow.c
index ee1221b..a6fe6d1 100644
--- a/flow.c
+++ b/flow.c
@@ -414,8 +414,8 @@ const struct flowside *flow_initiate_sa(union flow *flow, uint8_t pif,
  *
  * Return: pointer to the target flowside information
  */
-const struct flowside *flow_target(const struct ctx *c, union flow *flow,
-				   uint8_t proto)
+struct flowside *flow_target(const struct ctx *c, union flow *flow,
+			     uint8_t proto)
 {
 	char estr[INANY_ADDRSTRLEN], fstr[INANY_ADDRSTRLEN];
 	struct flow_common *f = &flow->f;
diff --git a/flow_table.h b/flow_table.h
index f15db53..eeb6f41 100644
--- a/flow_table.h
+++ b/flow_table.h
@@ -168,8 +168,8 @@ const struct flowside *flow_target_af(union flow *flow, uint8_t pif,
 				      sa_family_t af,
 				      const void *saddr, in_port_t sport,
 				      const void *daddr, in_port_t dport);
-const struct flowside *flow_target(const struct ctx *c, union flow *flow,
-				   uint8_t proto);
+struct flowside *flow_target(const struct ctx *c, union flow *flow,
+			     uint8_t proto);
 
 union flow *flow_set_type(union flow *flow, enum flow_type type);
 #define FLOW_SET_TYPE(flow_, t_, var_)	(&flow_set_type((flow_), (t_))->var_)
diff --git a/tcp.c b/tcp.c
index 51ad692..cf2943d 100644
--- a/tcp.c
+++ b/tcp.c
@@ -1415,6 +1415,8 @@ static void tcp_bind_outbound(const struct ctx *c,
  * @opts:	Pointer to start of options
  * @optlen:	Bytes in options: caller MUST ensure available length
  * @now:	Current timestamp
+ *
+ * #syscalls:vu getsockname
  */
 static void tcp_conn_from_tap(const struct ctx *c, sa_family_t af,
 			      const void *saddr, const void *daddr,
@@ -1423,9 +1425,10 @@ static void tcp_conn_from_tap(const struct ctx *c, sa_family_t af,
 {
 	in_port_t srcport = ntohs(th->source);
 	in_port_t dstport = ntohs(th->dest);
-	const struct flowside *ini, *tgt;
+	const struct flowside *ini;
 	struct tcp_tap_conn *conn;
 	union sockaddr_inany sa;
+	struct flowside *tgt;
 	union flow *flow;
 	int s = -1, mss;
 	uint64_t hash;
@@ -1530,6 +1533,27 @@ static void tcp_conn_from_tap(const struct ctx *c, sa_family_t af,
 	}
 
 	tcp_epoll_ctl(c, conn);
+
+	if (c->mode == MODE_VU) { /* To rebind to same oport after migration */
+		if (af == AF_INET) {
+			struct sockaddr_in s_in;
+			socklen_t sl;
+
+			sl = sizeof(s_in);
+			getsockname(s, (struct sockaddr *)&s_in, &sl);
+			tgt->oport = ntohs(s_in.sin_port);
+			tgt->oaddr = inany_from_v4(s_in.sin_addr);
+		} else {
+			struct sockaddr_in6 s_in6;
+			socklen_t sl;
+
+			sl = sizeof(s_in6);
+			getsockname(s, (struct sockaddr *)&s_in6, &sl);
+			tgt->oport = ntohs(s_in6.sin6_port);
+			tgt->oaddr.a6 = s_in6.sin6_addr;
+		}
+	}
+
 	FLOW_ACTIVATE(conn);
 	return;
 
-- 
@@ -1415,6 +1415,8 @@ static void tcp_bind_outbound(const struct ctx *c,
  * @opts:	Pointer to start of options
  * @optlen:	Bytes in options: caller MUST ensure available length
  * @now:	Current timestamp
+ *
+ * #syscalls:vu getsockname
  */
 static void tcp_conn_from_tap(const struct ctx *c, sa_family_t af,
 			      const void *saddr, const void *daddr,
@@ -1423,9 +1425,10 @@ static void tcp_conn_from_tap(const struct ctx *c, sa_family_t af,
 {
 	in_port_t srcport = ntohs(th->source);
 	in_port_t dstport = ntohs(th->dest);
-	const struct flowside *ini, *tgt;
+	const struct flowside *ini;
 	struct tcp_tap_conn *conn;
 	union sockaddr_inany sa;
+	struct flowside *tgt;
 	union flow *flow;
 	int s = -1, mss;
 	uint64_t hash;
@@ -1530,6 +1533,27 @@ static void tcp_conn_from_tap(const struct ctx *c, sa_family_t af,
 	}
 
 	tcp_epoll_ctl(c, conn);
+
+	if (c->mode == MODE_VU) { /* To rebind to same oport after migration */
+		if (af == AF_INET) {
+			struct sockaddr_in s_in;
+			socklen_t sl;
+
+			sl = sizeof(s_in);
+			getsockname(s, (struct sockaddr *)&s_in, &sl);
+			tgt->oport = ntohs(s_in.sin_port);
+			tgt->oaddr = inany_from_v4(s_in.sin_addr);
+		} else {
+			struct sockaddr_in6 s_in6;
+			socklen_t sl;
+
+			sl = sizeof(s_in6);
+			getsockname(s, (struct sockaddr *)&s_in6, &sl);
+			tgt->oport = ntohs(s_in6.sin6_port);
+			tgt->oaddr.a6 = s_in6.sin6_addr;
+		}
+	}
+
 	FLOW_ACTIVATE(conn);
 	return;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2025-02-04  0:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-04  0:05 [PATCH] tcp: Get socket port and address using getsockname() when connecting from guest Stefano Brivio

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).