gazelle/0309-Connect-execute-lwip-connect-if-dst_ip-and-host_ip-a.patch
yinbin c2057605b8 sync Connect: execute lwip connect if dst_ip and host_ip are in the same network.
(cherry picked from commit 674a95ff9395859b5b14ede0ed1be07a0fa13ea4)
2024-12-18 19:05:13 +08:00

133 lines
4.3 KiB
Diff

From 434a2509c25f265adb5d7b9398cb3bf8e379b387 Mon Sep 17 00:00:00 2001
From: yinbin <yinbin8@huawei.com>
Date: Sat, 14 Dec 2024 16:55:18 +0800
Subject: [PATCH] Connect: execute lwip connect if dst_ip and host_ip are in
the same network.
---
src/lstack/api/lstack_wrap.c | 82 ++++++++++++++++++++++++++----------
1 file changed, 59 insertions(+), 23 deletions(-)
diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
index 8077753..97e927a 100644
--- a/src/lstack/api/lstack_wrap.c
+++ b/src/lstack/api/lstack_wrap.c
@@ -256,7 +256,7 @@ static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen
return g_wrap_api->bind_fn(s, name, namelen);
}
-static bool kernel_ip_route(const struct sockaddr *addr)
+static bool kernel_ip_match(const struct sockaddr *addr)
{
struct ifaddrs *ifap;
struct ifaddrs *ifa;
@@ -298,7 +298,27 @@ static bool kernel_ip_route(const struct sockaddr *addr)
freeifaddrs(ifap);
return false;
}
-static bool is_relatived_kernel_ip(const struct sockaddr *dst_addr)
+
+static bool lwip_ip_route(const struct sockaddr *dst_addr)
+{
+ uint32_t host_ip;
+ uint32_t host_mask;
+ uint32_t dst_ip;
+
+ host_ip = get_global_cfg_params()->host_addr.addr;
+ host_mask = get_global_cfg_params()->netmask.addr;
+ if (dst_addr->sa_family == AF_INET) {
+ dst_ip = ((struct sockaddr_in *)dst_addr) ->sin_addr.s_addr;
+ /* if dst_addr and host_addr are in the same network, return ture. */
+ if ((host_ip & host_mask) == (dst_ip & host_mask)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool kernel_ip_route(const struct sockaddr *dst_addr)
{
struct ifaddrs *ifap;
struct ifaddrs *ifa;
@@ -339,8 +359,34 @@ static bool is_relatived_kernel_ip(const struct sockaddr *dst_addr)
freeifaddrs(ifap);
return ret;
}
+
+static bool should_enter_kernel_connect(const struct sockaddr *addr)
+{
+ int32_t remote_port;
+ char listen_ring_name[RING_NAME_LEN];
+
+ remote_port = htons(((struct sockaddr_in *)addr)->sin_port);
+ snprintf_s(listen_ring_name, sizeof(listen_ring_name), sizeof(listen_ring_name) - 1,
+ "listen_rx_ring_%d", remote_port);
+ if (kernel_ip_match(addr) && rte_ring_lookup(listen_ring_name) == NULL) {
+ return true;
+ }
+
+ if (lwip_ip_route(addr)) {
+ return false;
+ }
+
+ if (kernel_ip_route(addr)) {
+ return true;
+ }
+
+ return false;
+}
+
static int32_t do_connect(int32_t s, const struct sockaddr *addr, socklen_t addrlen)
{
+ int32_t ret = 0;
+
if (addr == NULL) {
GAZELLE_RETURN(EINVAL);
}
@@ -350,30 +396,20 @@ static int32_t do_connect(int32_t s, const struct sockaddr *addr, socklen_t addr
return posix_api->connect_fn(s, addr, addrlen);
}
- int32_t ret = 0;
- int32_t remote_port;
- bool is_kernel = kernel_ip_route(addr);
- bool is_to_kernel_connect = is_relatived_kernel_ip(addr);
-
- remote_port = htons(((struct sockaddr_in *)addr)->sin_port);
-
- char listen_ring_name[RING_NAME_LEN];
- snprintf_s(listen_ring_name, sizeof(listen_ring_name), sizeof(listen_ring_name) - 1,
- "listen_rx_ring_%d", remote_port);
-
- if ((is_kernel && rte_ring_lookup(listen_ring_name) == NULL) || is_to_kernel_connect) {
+ if (should_enter_kernel_connect(addr)) {
ret = posix_api->connect_fn(s, addr, addrlen);
POSIX_SET_TYPE(sock, POSIX_KERNEL);
+ return ret;
+ }
+
+ /* When the socket is POSIX_LWIP_OR_KERNEL, connect to lwip first and then connect to kernel. */
+ ret = g_wrap_api->connect_fn(s, addr, addrlen);
+ if (ret == 0 || (ret != 0 && errno == EINPROGRESS)) {
+ POSIX_SET_TYPE(sock, POSIX_LWIP);
} else {
- /* When the socket is POSIX_LWIP_OR_KERNEL, connect to lwip first and then connect to kernel. */
- ret = g_wrap_api->connect_fn(s, addr, addrlen);
- if (ret == 0 || (ret != 0 && errno == EINPROGRESS)) {
- POSIX_SET_TYPE(sock, POSIX_LWIP);
- } else {
- ret = posix_api->connect_fn(s, addr, addrlen);
- if (ret == 0) {
- POSIX_SET_TYPE(sock, POSIX_KERNEL);
- }
+ ret = posix_api->connect_fn(s, addr, addrlen);
+ if (ret == 0) {
+ POSIX_SET_TYPE(sock, POSIX_KERNEL);
}
}
return ret;
--
2.33.0