From 6f122f0171fe4bc235d572945e0bf963e81139ea Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Wed, 12 Feb 2025 18:07:17 +1100 Subject: tcp: Get bound address for connected inbound sockets too So that we can bind inbound sockets to specific addresses, like we already do for outbound sockets. While at it, change the error message in tcp_conn_from_tap() to match this one. Reviewed-by: David Gibson Signed-off-by: Stefano Brivio --- flow.c | 6 +++--- flow_table.h | 6 +++--- tcp.c | 22 ++++++++++++++-------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/flow.c b/flow.c index a6fe6d1..3ac551b 100644 --- a/flow.c +++ b/flow.c @@ -390,9 +390,9 @@ const struct flowside *flow_initiate_af(union flow *flow, uint8_t pif, * * Return: pointer to the initiating flowside information */ -const struct flowside *flow_initiate_sa(union flow *flow, uint8_t pif, - const union sockaddr_inany *ssa, - in_port_t dport) +struct flowside *flow_initiate_sa(union flow *flow, uint8_t pif, + const union sockaddr_inany *ssa, + in_port_t dport) { struct flowside *ini = &flow->f.side[INISIDE]; diff --git a/flow_table.h b/flow_table.h index eeb6f41..9a2ff24 100644 --- a/flow_table.h +++ b/flow_table.h @@ -161,9 +161,9 @@ const struct flowside *flow_initiate_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_initiate_sa(union flow *flow, uint8_t pif, - const union sockaddr_inany *ssa, - in_port_t dport); +struct flowside *flow_initiate_sa(union flow *flow, uint8_t pif, + const union sockaddr_inany *ssa, + in_port_t dport); const struct flowside *flow_target_af(union flow *flow, uint8_t pif, sa_family_t af, const void *saddr, in_port_t sport, diff --git a/tcp.c b/tcp.c index b87478f..a1d6c53 100644 --- a/tcp.c +++ b/tcp.c @@ -1536,12 +1536,10 @@ static void tcp_conn_from_tap(const struct ctx *c, sa_family_t af, if (c->mode == MODE_VU) { /* To rebind to same oport after migration */ sl = sizeof(sa); - if (!getsockname(s, &sa.sa, &sl)) { + if (!getsockname(s, &sa.sa, &sl)) inany_from_sockaddr(&tgt->oaddr, &tgt->oport, &sa); - } else { - err("Failed to get local address for socket: %s", - strerror_(errno)); - } + else + err_perror("Can't get local address for socket %i", s); } FLOW_ACTIVATE(conn); @@ -2075,9 +2073,9 @@ static void tcp_tap_conn_from_sock(const struct ctx *c, union flow *flow, void tcp_listen_handler(const struct ctx *c, union epoll_ref ref, const struct timespec *now) { - const struct flowside *ini; union sockaddr_inany sa; socklen_t sl = sizeof(sa); + struct flowside *ini; union flow *flow; int s; @@ -2093,12 +2091,20 @@ void tcp_listen_handler(const struct ctx *c, union epoll_ref ref, tcp_sock_set_bufsize(c, s); tcp_sock_set_nodelay(s); - /* FIXME: When listening port has a specific bound address, record that - * as our address + /* FIXME: If useful: when the listening port has a specific bound + * address, record that as our address, as implemented for vhost-user + * mode only, below. */ ini = flow_initiate_sa(flow, ref.tcp_listen.pif, &sa, ref.tcp_listen.port); + if (c->mode == MODE_VU) { /* Rebind to same address after migration */ + if (!getsockname(s, &sa.sa, &sl)) + inany_from_sockaddr(&ini->oaddr, &ini->oport, &sa); + else + err_perror("Can't get local address for socket %i", s); + } + if (!inany_is_unicast(&ini->eaddr) || ini->eport == 0) { char sastr[SOCKADDR_STRLEN]; -- cgit v1.2.3