aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-04-22 17:03:43 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-04-22 17:03:43 +0200
commit6488c3e8489da9aaa6642a367ac2bff70efff749 (patch)
tree88a0890f8089c0ad99b66e0d24fece6536418a88
parent9ffb317cf9d64a5f883f654d1d5d9466b0937d4f (diff)
downloadpasst-6488c3e8489da9aaa6642a367ac2bff70efff749.tar
passt-6488c3e8489da9aaa6642a367ac2bff70efff749.tar.gz
passt-6488c3e8489da9aaa6642a367ac2bff70efff749.tar.bz2
passt-6488c3e8489da9aaa6642a367ac2bff70efff749.tar.lz
passt-6488c3e8489da9aaa6642a367ac2bff70efff749.tar.xz
passt-6488c3e8489da9aaa6642a367ac2bff70efff749.tar.zst
passt-6488c3e8489da9aaa6642a367ac2bff70efff749.zip
tcp, udp: Replace loopback source address by gateway address
This is symmetric with tap operation and addressing model, and allows again to reach the guest behind the tap interface by contacting the local address. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tcp.c8
-rw-r--r--udp.c7
2 files changed, 15 insertions, 0 deletions
diff --git a/tcp.c b/tcp.c
index 1403da8..330e21a 100644
--- a/tcp.c
+++ b/tcp.c
@@ -1008,6 +1008,11 @@ static void tcp_conn_from_sock(struct ctx *c, int fd)
memset(&tc[s].a.a4.zero, 0, sizeof(tc[s].a.a4.zero));
memset(&tc[s].a.a4.one, 0xff, sizeof(tc[s].a.a4.one));
+
+ if (ntohl(sa4->sin_addr.s_addr) == INADDR_LOOPBACK ||
+ ntohl(sa4->sin_addr.s_addr) == INADDR_ANY)
+ sa4->sin_addr.s_addr = c->gw4;
+
memcpy(&tc[s].a.a4.a, &sa4->sin_addr, sizeof(tc[s].a.a4.a));
tc[s].sock_port = sa4->sin_port;
@@ -1022,6 +1027,9 @@ static void tcp_conn_from_sock(struct ctx *c, int fd)
} else if (sa_l.ss_family == AF_INET6) {
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&sa_r;
+ if (IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
+ memcpy(&sa6->sin6_addr, &c->gw6, sizeof(c->gw6));
+
memcpy(&tc[s].a.a6, &sa6->sin6_addr, sizeof(tc[s].a.a6));
tc[s].sock_port = sa6->sin6_port;
diff --git a/udp.c b/udp.c
index dda3a68..7be88f6 100644
--- a/udp.c
+++ b/udp.c
@@ -84,6 +84,10 @@ void udp_sock_handler(struct ctx *c, int s, uint32_t events)
struct sockaddr_in *sr4 = (struct sockaddr_in *)&sr;
struct sockaddr_in *sl4 = (struct sockaddr_in *)&sl;
+ if (ntohl(sr4->sin_addr.s_addr) == INADDR_LOOPBACK ||
+ ntohl(sr4->sin_addr.s_addr) == INADDR_ANY)
+ sr4->sin_addr.s_addr = c->gw4;
+
memcpy(&a6.s6_addr[12], &sr4->sin_addr, sizeof(sr4->sin_addr));
uh->source = sr4->sin_port;
uh->dest = sl4->sin_port;
@@ -94,6 +98,9 @@ void udp_sock_handler(struct ctx *c, int s, uint32_t events)
struct sockaddr_in6 *sr6 = (struct sockaddr_in6 *)&sr;
struct sockaddr_in6 *sl6 = (struct sockaddr_in6 *)&sl;
+ if (IN6_IS_ADDR_LOOPBACK(&sr6->sin6_addr))
+ memcpy(&sr6->sin6_addr, &c->gw6, sizeof(c->gw6));
+
uh->source = sr6->sin6_port;
uh->dest = sl6->sin6_port;
uh->len = htons(n + sizeof(*uh));