diff --git a/0081-dfx-fix-kernel_events-stat.patch b/0081-dfx-fix-kernel_events-stat.patch new file mode 100644 index 0000000..b924ae3 --- /dev/null +++ b/0081-dfx-fix-kernel_events-stat.patch @@ -0,0 +1,24 @@ +From 3f93ac98b09a3bdb0dc557f9b93a008d809cd5c3 Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Sun, 10 Dec 2023 14:55:16 +0800 +Subject: [PATCH] dfx: fix kernel_events stat + +--- + src/lstack/core/lstack_stack_stat.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index 2d85efa..e4ccc41 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -136,6 +136,7 @@ static void get_wakeup_stat(struct protocol_stack_group *stack_group, struct pro + struct wakeup_poll *wakeup = container_of(node, struct wakeup_poll, poll_list); + + if (wakeup->bind_stack == stack) { ++ stat->kernel_events += wakeup->stat.kernel_events; + stat->app_events += wakeup->stat.app_events; + stat->read_null += wakeup->stat.read_null; + stat->app_write_cnt += wakeup->stat.app_write_cnt; +-- +2.27.0 + diff --git a/0082-add-keep-alive-info.patch b/0082-add-keep-alive-info.patch new file mode 100644 index 0000000..c9cdf07 --- /dev/null +++ b/0082-add-keep-alive-info.patch @@ -0,0 +1,111 @@ +From 5e6a73b66e0b231237ea3a3bbedfe4dd4d974f45 Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Mon, 11 Dec 2023 05:03:04 +0800 +Subject: [PATCH] add keep-alive info + +--- + src/common/gazelle_dfx_msg.h | 2 ++ + src/lstack/core/lstack_lwip.c | 2 ++ + src/ltran/ltran_dfx.c | 25 ++++++++++++++++++++++--- + 3 files changed, 26 insertions(+), 3 deletions(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 3d559c3..478c440 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -197,6 +197,8 @@ struct gazelle_stat_lstack_conn_info { + uint32_t eventlist; + uint32_t keepalive; + uint32_t keep_idle; ++ uint32_t keep_intvl; ++ uint32_t keep_cnt; + }; + + struct gazelle_stat_lstack_conn { +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index c4b1ebc..cbb771f 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -1151,6 +1151,8 @@ static void copy_pcb_to_conn(struct gazelle_stat_lstack_conn_info *conn, const s + conn->rcv_nxt = pcb->rcv_nxt; + conn->keepalive = (ip_get_option(pcb, SOF_KEEPALIVE) != 0); + conn->keep_idle = pcb->keep_idle; ++ conn->keep_intvl = pcb->keep_intvl; ++ conn->keep_cnt = pcb->keep_cnt; + + if (netconn != NULL && netconn->recvmbox != NULL) { + conn->recv_cnt = rte_ring_count(netconn->recvmbox->ring); +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index ebe1323..2a84cb8 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -52,6 +52,7 @@ + #define GAZELLE_MAX_LATENCY_TIME 1800 // max latency time 30mins + + #define GAZELLE_DECIMAL 10 ++#define GAZELLE_KEEPALIVE_STR_LEN 35 + + static int32_t g_unix_fd = -1; + static int32_t g_ltran_rate_show_flag = GAZELLE_OFF; // not show when first get total statistics +@@ -995,6 +996,20 @@ static void gazelle_print_lstack_stat_snmp(void *buf, const struct gazelle_stat_ + } while (true); + } + ++static void gazelle_keepalive_string(char* str, int buff_len, struct gazelle_stat_lstack_conn_info *conn_info) ++{ ++ if (conn_info->keepalive == 0) { ++ return; ++ } ++ int ret = sprintf_s(str, buff_len - 1, "(%u,%u,%u)", conn_info->keep_idle, conn_info->keep_intvl, ++ conn_info->keep_cnt); ++ if (ret < 0) { ++ printf("gazelle_keepalive_string sprintf_s fail ret=%d\n", ret); ++ return; ++ } ++ str[strlen(str)] = '\0'; ++} ++ + static void gazelle_print_lstack_stat_conn(void *buf, const struct gazelle_stat_msg_request *req_msg) + { + uint32_t i; +@@ -1007,6 +1022,7 @@ static void gazelle_print_lstack_stat_conn(void *buf, const struct gazelle_stat_ + struct gazelle_stat_lstack_conn *conn = &stat->data.conn; + struct timeval time = {0}; + gettimeofday(&time, NULL); ++ char keepalive_info_str[GAZELLE_KEEPALIVE_STR_LEN] = {0}; + + printf("Active Internet connections (servers and established)\n"); + do { +@@ -1014,7 +1030,7 @@ static void gazelle_print_lstack_stat_conn(void *buf, const struct gazelle_stat_ + printf("No. Proto lwip_recv recv_ring in_send send_ring cwn rcv_wnd snd_wnd snd_buf snd_nxt" + " lastack rcv_nxt events epoll_ev evlist fd Local Address" + " Foreign Address State" +- " keep-alive keep-idle\n"); ++ " keep-alive keep-alive(idle,intvl,cnt)\n"); + uint32_t unread_pkts = 0; + uint32_t unsend_pkts = 0; + for (i = 0; i < conn->conn_num && i < GAZELLE_LSTACK_MAX_CONN; i++) { +@@ -1027,15 +1043,18 @@ static void gazelle_print_lstack_stat_conn(void *buf, const struct gazelle_stat_ + if ((conn_info->state == GAZELLE_ACTIVE_LIST) || (conn_info->state == GAZELLE_TIME_WAIT_LIST)) { + inet_ntop(domain, lip, str_ip, sizeof(str_ip)); + inet_ntop(domain, rip, str_rip, sizeof(str_rip)); ++ ++ gazelle_keepalive_string(keepalive_info_str, sizeof(keepalive_info_str)/sizeof(char), conn_info); ++ + sprintf_s(str_laddr, sizeof(str_laddr), "%s:%hu", str_ip, conn_info->l_port); + sprintf_s(str_raddr, sizeof(str_raddr), "%s:%hu", str_rip, conn_info->r_port); + printf("%-6utcp %-10u%-10u%-8u%-10u%-9d%-9d%-10d%-10d%-15u%-15u%-15u%-10x%-10x%-7d%-7d" +- "%-52s %-52s %s %-5d %-9u\n", i, conn_info->recv_cnt, conn_info->recv_ring_cnt, conn_info->in_send, ++ "%-52s %-52s %s %-5d %s\n", i, conn_info->recv_cnt, conn_info->recv_ring_cnt, conn_info->in_send, + conn_info->send_ring_cnt, conn_info->cwn, conn_info->rcv_wnd, conn_info->snd_wnd, + conn_info->snd_buf, conn_info->snd_nxt, conn_info->lastack, conn_info->rcv_nxt, conn_info->events, + conn_info->epoll_events, conn_info->eventlist, conn_info->fd, + str_laddr, str_raddr, tcp_state_to_str(conn_info->tcp_sub_state), +- conn_info->keepalive, conn_info->keep_idle); ++ conn_info->keepalive, keepalive_info_str); + } else if (conn_info->state == GAZELLE_LISTEN_LIST) { + inet_ntop(domain, lip, str_ip, sizeof(str_ip)); + sprintf_s(str_laddr, sizeof(str_laddr), "%s:%hu", str_ip, conn_info->l_port); +-- +2.27.0 + diff --git a/0083-fix-close-can-t-exit.patch b/0083-fix-close-can-t-exit.patch new file mode 100644 index 0000000..9bf3399 --- /dev/null +++ b/0083-fix-close-can-t-exit.patch @@ -0,0 +1,137 @@ +From f4abd3b3fd5004405cb186981b93f5d40e4648db Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sun, 10 Dec 2023 17:47:56 +0800 +Subject: [PATCH] fix close can't exit + +--- + src/lstack/core/lstack_lwip.c | 12 ++++++++---- + src/lstack/core/lstack_protocol_stack.c | 25 +++++++++++++++---------- + src/lstack/core/lstack_thread_rpc.c | 6 +++--- + src/lstack/include/lstack_lwip.h | 4 ++-- + 4 files changed, 28 insertions(+), 19 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index c4b1ebc..73a6f12 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -646,14 +646,18 @@ bool do_lwip_replenish_sendring(struct protocol_stack *stack, struct lwip_sock * + return replenish_again; + } + +-bool do_lwip_send(struct protocol_stack *stack, int32_t fd, struct lwip_sock *sock, +- size_t len, int32_t flags) ++int do_lwip_send(struct protocol_stack *stack, int32_t fd, struct lwip_sock *sock, ++ size_t len, int32_t flags) + { ++ ssize_t ret; + /* send all send_ring, so len set lwip send max. */ + if (NETCONN_IS_UDP(sock)) { +- (void)lwip_send(fd, sock, len, flags); ++ ret = lwip_send(fd, sock, len, flags); + } else { +- (void)lwip_send(fd, sock, UINT16_MAX, flags); ++ ret = lwip_send(fd, sock, UINT16_MAX, flags); ++ } ++ if (ret < 0 && (errno == ENOTCONN || errno == ECONNRESET || errno == ECONNABORTED)) { ++ return -1; + } + + return do_lwip_replenish_sendring(stack, sock); +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index f61e7a8..8dbd9ad 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -699,10 +699,10 @@ void stack_close(struct rpc_msg *msg) + struct protocol_stack *stack = get_protocol_stack_by_fd(fd); + struct lwip_sock *sock = get_socket(fd); + +- if (sock && NETCONN_IS_DATAOUT(sock)) { ++ if (sock && __atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) > 0) { + msg->recall_flag = 1; + rpc_call(&stack->rpc_queue, msg); /* until stack_send recall finish */ +- return; ++ return; + } + + msg->result = lwip_close(fd); +@@ -860,27 +860,32 @@ void stack_send(struct rpc_msg *msg) + int32_t fd = msg->args[MSG_ARG_0].i; + size_t len = msg->args[MSG_ARG_1].size; + struct protocol_stack *stack = (struct protocol_stack *)msg->args[MSG_ARG_3].p; +- bool replenish_again; ++ int replenish_again; + + struct lwip_sock *sock = get_socket(fd); + if (sock == NULL) { + msg->result = -1; + LSTACK_LOG(ERR, LSTACK, "get sock error! fd=%d, len=%ld\n", fd, len); +- rpc_msg_free(msg); ++ __sync_fetch_and_sub(&sock->call_num, 1); + return; + } + + replenish_again = do_lwip_send(stack, sock->conn->socket, sock, len, 0); +- __sync_fetch_and_sub(&sock->call_num, 1); +- if (!NETCONN_IS_DATAOUT(sock) && !replenish_again) { ++ if (replenish_again < 0) { ++ __sync_fetch_and_sub(&sock->call_num, 1); + return; +- } else { +- if (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 0) { +- msg->recall_flag = 1; ++ } ++ ++ if (NETCONN_IS_DATAOUT(sock) || replenish_again > 0) { ++ if (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1) { ++ msg->recall_flag = 1; + rpc_call(&stack->rpc_queue, msg); +- __sync_fetch_and_add(&sock->call_num, 1); ++ return; + } + } ++ ++ __sync_fetch_and_sub(&sock->call_num, 1); ++ return; + } + + /* any protocol stack thread receives arp packet and sync it to other threads so that it can have the arp table */ +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index 4aceee6..0b2a62a 100644 +--- a/src/lstack/core/lstack_thread_rpc.c ++++ b/src/lstack/core/lstack_thread_rpc.c +@@ -109,14 +109,14 @@ void poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num) + } + + if (!msg->recall_flag) { +- if (msg->sync_flag) { ++ if (msg->sync_flag) { + pthread_spin_unlock(&msg->lock); + } else { + rpc_msg_free(msg); + } + } else { +- msg->recall_flag = 0; +- } ++ msg->recall_flag = 0; ++ } + } + } + +diff --git a/src/lstack/include/lstack_lwip.h b/src/lstack/include/lstack_lwip.h +index 4a13204..a11489c 100644 +--- a/src/lstack/include/lstack_lwip.h ++++ b/src/lstack/include/lstack_lwip.h +@@ -50,8 +50,8 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + + void do_lwip_read_recvlist(struct protocol_stack *stack, uint32_t max_num); + void do_lwip_add_recvlist(int32_t fd); +-bool do_lwip_send(struct protocol_stack *stack, int32_t fd, struct lwip_sock *sock, +- size_t len, int32_t flags); ++int do_lwip_send(struct protocol_stack *stack, int32_t fd, struct lwip_sock *sock, ++ size_t len, int32_t flags); + + uint32_t do_lwip_get_conntable(struct gazelle_stat_lstack_conn_info *conn, uint32_t max_num); + uint32_t do_lwip_get_connnum(void); +-- +2.27.0 + diff --git a/0084-mod-unix-time-stamp-to-local-time.patch b/0084-mod-unix-time-stamp-to-local-time.patch new file mode 100644 index 0000000..fda79e9 --- /dev/null +++ b/0084-mod-unix-time-stamp-to-local-time.patch @@ -0,0 +1,72 @@ +From 95784bb047ae30ebff9d224ef178430fda91027e Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Fri, 15 Dec 2023 03:34:46 +0800 +Subject: [PATCH] mod unix time stamp to local time + +--- + src/ltran/ltran_dfx.c | 26 +++++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 2a84cb8..25d4f35 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -53,6 +53,7 @@ + + #define GAZELLE_DECIMAL 10 + #define GAZELLE_KEEPALIVE_STR_LEN 35 ++#define GAZELLE_TIME_STR_LEN 25 + + static int32_t g_unix_fd = -1; + static int32_t g_ltran_rate_show_flag = GAZELLE_OFF; // not show when first get total statistics +@@ -1001,13 +1002,27 @@ static void gazelle_keepalive_string(char* str, int buff_len, struct gazelle_sta + if (conn_info->keepalive == 0) { + return; + } +- int ret = sprintf_s(str, buff_len - 1, "(%u,%u,%u)", conn_info->keep_idle, conn_info->keep_intvl, ++ int ret = sprintf_s(str, buff_len, "(%u,%u,%u)", conn_info->keep_idle, conn_info->keep_intvl, + conn_info->keep_cnt); + if (ret < 0) { + printf("gazelle_keepalive_string sprintf_s fail ret=%d\n", ret); + return; + } +- str[strlen(str)] = '\0'; ++} ++ ++static void gazelle_localtime_string(char* str, int buff_len) ++{ ++ struct timeval time = {0}; ++ gettimeofday(&time, NULL); ++ struct tm* tm; ++ time_t t = time.tv_sec; ++ tm = localtime(&t); ++ int ret = sprintf_s(str, buff_len, "%d-%d-%d %d:%d:%d", ++ tm->tm_yday + 1900, tm->tm_mon + 1, tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec); ++ if (ret < 0) { ++ printf("gazelle_localtime_string sprintf_s fail ret=%d\n", ret); ++ return; ++ } + } + + static void gazelle_print_lstack_stat_conn(void *buf, const struct gazelle_stat_msg_request *req_msg) +@@ -1020,13 +1035,14 @@ static void gazelle_print_lstack_stat_conn(void *buf, const struct gazelle_stat_ + char str_raddr[INET6_ADDRSTRLEN + 6] = {0}; + struct gazelle_stack_dfx_data *stat = (struct gazelle_stack_dfx_data *)buf; + struct gazelle_stat_lstack_conn *conn = &stat->data.conn; +- struct timeval time = {0}; +- gettimeofday(&time, NULL); ++ + char keepalive_info_str[GAZELLE_KEEPALIVE_STR_LEN] = {0}; ++ char sys_local_time_str[GAZELLE_TIME_STR_LEN] = {0}; ++ gazelle_localtime_string(sys_local_time_str, GAZELLE_TIME_STR_LEN); + + printf("Active Internet connections (servers and established)\n"); + do { +- printf("\n------ stack tid: %6u ------time=%lu\n", stat->tid, time.tv_sec * 1000000 + time.tv_usec); ++ printf("\n------ stack tid: %6u ------time=%s\n", stat->tid, sys_local_time_str); + printf("No. Proto lwip_recv recv_ring in_send send_ring cwn rcv_wnd snd_wnd snd_buf snd_nxt" + " lastack rcv_nxt events epoll_ev evlist fd Local Address" + " Foreign Address State" +-- +2.27.0 + diff --git a/0085-optimize-gazelle-exit-process.patch b/0085-optimize-gazelle-exit-process.patch new file mode 100644 index 0000000..a8a68b5 --- /dev/null +++ b/0085-optimize-gazelle-exit-process.patch @@ -0,0 +1,671 @@ +From 95c0a884ff26b42a75ee35639d789b40af131fd3 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Tue, 12 Dec 2023 19:24:14 +0800 +Subject: [PATCH] optimize gazelle exit process 1. close all fds 2. lstack + thread exits, then gazelle process exits + +--- + src/common/gazelle_base_func.h | 2 + + src/common/gazelle_dfx_msg.c | 8 +- + src/lstack/api/dir.mk | 2 +- + src/lstack/api/lstack_dummy_api.c | 55 +++++++++++++ + src/lstack/api/lstack_rtc_api.c | 1 + + src/lstack/api/lstack_signal.c | 5 +- + src/lstack/api/lstack_wrap.c | 12 +++ + src/lstack/core/lstack_dpdk.c | 2 +- + src/lstack/core/lstack_init.c | 18 ++++- + src/lstack/core/lstack_lwip.c | 16 ++-- + src/lstack/core/lstack_protocol_stack.c | 93 ++++++++++++++++++---- + src/lstack/core/lstack_thread_rpc.c | 22 ++++- + src/lstack/include/lstack_dummy_api.h | 23 ++++++ + src/lstack/include/lstack_lwip.h | 4 +- + src/lstack/include/lstack_protocol_stack.h | 6 +- + src/lstack/include/lstack_thread_rpc.h | 3 +- + src/lstack/include/lstack_wrap.h | 1 + + 17 files changed, 237 insertions(+), 36 deletions(-) + create mode 100644 src/lstack/api/lstack_dummy_api.c + create mode 100644 src/lstack/include/lstack_dummy_api.h + +diff --git a/src/common/gazelle_base_func.h b/src/common/gazelle_base_func.h +index d21ef5f..2d629c1 100644 +--- a/src/common/gazelle_base_func.h ++++ b/src/common/gazelle_base_func.h +@@ -34,6 +34,8 @@ int32_t check_and_set_run_dir(void); + + int32_t filename_check(const char* args); + ++void gazelle_exit(void); ++ + #undef container_of + #define container_of(ptr, type, field) ((type *)(void*)(((char *)(ptr)) - offsetof(type, field))) + +diff --git a/src/common/gazelle_dfx_msg.c b/src/common/gazelle_dfx_msg.c +index 5fe4e06..ec23401 100644 +--- a/src/common/gazelle_dfx_msg.c ++++ b/src/common/gazelle_dfx_msg.c +@@ -29,19 +29,19 @@ int read_specied_len(int fd, char *buf, size_t target_size) + while (total_read < target_size) { + int ret = poll(fds, 1, GAZELLECTL_TIMEOUT); + if (ret < 0) { +- printf("read_specied_len:: poll ret=%d \n", ret); ++ printf("read_specied_len: poll ret=%d \n", ret); + return -1; + } else if (ret == 0) { +- printf("read_specied_len:: time out \n"); ++ printf("read_specied_len: time out \n"); + return -1; + } + if (fds[0].revents & POLLIN) { + int n = read(fd, buf + total_read, target_size - total_read); + if (n < 0) { +- printf("read_specied_len:: read ret=%d \n", ret); ++ printf("read_specied_len: read ret=%d \n", ret); + return -1; + } else if (n == 0) { +- printf("read_specied_len:: Connection closed \n"); ++ printf("read_specied_len: Connection closed \n"); + return -1; + } + total_read += n; +diff --git a/src/lstack/api/dir.mk b/src/lstack/api/dir.mk +index ffbb137..729690d 100644 +--- a/src/lstack/api/dir.mk ++++ b/src/lstack/api/dir.mk +@@ -8,7 +8,7 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + +-SRC = lstack_epoll.c lstack_signal.c lstack_fork.c lstack_wrap.c lstack_rtw_api.c lstack_rtc_api.c ++SRC = lstack_epoll.c lstack_signal.c lstack_fork.c lstack_wrap.c lstack_rtw_api.c lstack_rtc_api.c lstack_dummy_api.c + + $(eval $(call register_dir, api, $(SRC))) + +diff --git a/src/lstack/api/lstack_dummy_api.c b/src/lstack/api/lstack_dummy_api.c +new file mode 100644 +index 0000000..f327916 +--- /dev/null ++++ b/src/lstack/api/lstack_dummy_api.c +@@ -0,0 +1,55 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++#include ++#include ++#include ++ ++#define DUMMY_SLEEP_S 5 ++ ++static inline ssize_t dummy_exit(void) ++{ ++ sleep(DUMMY_SLEEP_S); ++ errno = ENOTCONN; ++ return -1; ++} ++ ++int dummy_socket(int domain, int type, int protocol) ++{ ++ sleep(DUMMY_SLEEP_S); ++ return -1; ++} ++ ++ssize_t dummy_write(int s, const void *mem, size_t size) ++{ ++ return dummy_exit(); ++} ++ ++ssize_t dummy_writev(int s, const struct iovec *iov, int iovcnt) ++{ ++ return dummy_exit(); ++} ++ ++ssize_t dummy_send(int sockfd, const void *buf, size_t len, int flags) ++{ ++ return dummy_exit(); ++} ++ ++ssize_t dummy_sendmsg(int s, const struct msghdr *message, int flags) ++{ ++ return dummy_exit(); ++} ++ ++ssize_t dummy_sendto(int sockfd, const void *buf, size_t len, int flags, ++ const struct sockaddr *addr, socklen_t addrlen) ++{ ++ return dummy_exit(); ++} +diff --git a/src/lstack/api/lstack_rtc_api.c b/src/lstack/api/lstack_rtc_api.c +index 50d72bc..d29e51e 100644 +--- a/src/lstack/api/lstack_rtc_api.c ++++ b/src/lstack/api/lstack_rtc_api.c +@@ -20,6 +20,7 @@ + #include "lstack_log.h" + #include "lstack_cfg.h" + #include "lstack_protocol_stack.h" ++#include "lstack_thread_rpc.h" + #include "lstack_rtc_api.h" + + int rtc_poll(struct pollfd *fds, nfds_t nfds, int timeout) +diff --git a/src/lstack/api/lstack_signal.c b/src/lstack/api/lstack_signal.c +index 285aaf3..6da6eb4 100644 +--- a/src/lstack/api/lstack_signal.c ++++ b/src/lstack/api/lstack_signal.c +@@ -18,6 +18,7 @@ + #include + #include + ++#include "gazelle_base_func.h" + #include "lstack_cfg.h" + #include "dpdk_common.h" + #include "lstack_log.h" +@@ -60,15 +61,13 @@ static void lstack_sig_default_handler(int sig) + if (get_global_cfg_params() && get_global_cfg_params()->is_primary) { + delete_primary_path(); + } +- if (!use_ltran()) { +- dpdk_kni_release(); +- } + control_fd_close(); + /* When operations such as pressing Ctrl+C or Kill, the call stack exit is not displayed. */ + if (sig != SIGINT && sig != SIGTERM && sig != SIGKILL) { + dump_stack(); + } + lwip_exit(); ++ gazelle_exit(); + (void)kill(getpid(), sig); + } + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 65a0a5a..89f54f8 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -36,6 +36,7 @@ + + #include "lstack_rtc_api.h" + #include "lstack_rtw_api.h" ++#include "lstack_dummy_api.h" + + #ifndef SOCK_TYPE_MASK + #define SOCK_TYPE_MASK 0xf +@@ -112,6 +113,17 @@ void wrap_api_init(void) + } + } + ++void wrap_api_set_dummy(void) ++{ ++ g_wrap_api->socket_fn = dummy_socket; ++ g_wrap_api->send_fn = dummy_send; ++ g_wrap_api->write_fn = dummy_write; ++ g_wrap_api->writev_fn = dummy_writev; ++ g_wrap_api->send_msg = dummy_sendmsg; ++ g_wrap_api->send_to = dummy_sendto; ++ rte_wmb(); ++} ++ + static inline int32_t do_epoll_create1(int32_t flags) + { + if (select_posix_path() == PATH_KERNEL) { +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 8950591..e20dea8 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -897,4 +897,4 @@ void dpdk_nic_features_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id) + dfx->data.nic_features.tx_offload = dev_conf.txmode.offloads; + dfx->data.nic_features.rx_offload = dev_conf.rxmode.offloads; + return; +-} +\ No newline at end of file ++} +diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c +index a3ca4ff..fef2942 100644 +--- a/src/lstack/core/lstack_init.c ++++ b/src/lstack/core/lstack_init.c +@@ -107,10 +107,24 @@ static int32_t check_process_conflict(void) + return 0; + } + ++void gazelle_exit(void) ++{ ++ if (!get_global_cfg_params()->stack_mode_rtc) { ++ wrap_api_set_dummy(); ++ /* 1: wait until app thread call send functio complete */ ++ sleep(1); ++ stack_group_exit(); ++ } ++ if (!use_ltran()) { ++ dpdk_kni_release(); ++ } ++} ++ + __attribute__((destructor)) void gazelle_network_exit(void) + { + if (posix_api != NULL && !posix_api->ues_posix) { + lwip_exit(); ++ gazelle_exit(); + } + + if (!use_ltran()) { +@@ -118,8 +132,6 @@ __attribute__((destructor)) void gazelle_network_exit(void) + if (ret < 0) { + LSTACK_LOG(ERR, LSTACK, "rte_pdump_uninit failed\n"); + } +- +- dpdk_kni_release(); + } + } + +@@ -289,6 +301,7 @@ __attribute__((constructor)) void gazelle_network_init(void) + + if (!get_global_cfg_params()->stack_mode_rtc) { + if (stack_setup_thread() != 0) { ++ gazelle_exit(); + LSTACK_EXIT(1, "stack_setup_thread failed\n"); + } + } +@@ -301,6 +314,7 @@ __attribute__((constructor)) void gazelle_network_init(void) + } + + if (set_process_start_flag() != 0) { ++ gazelle_exit(); + LSTACK_EXIT(1, "set_process_start_flag failed\n"); + } + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index fb286d6..15f99f9 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -201,7 +201,7 @@ void do_lwip_init_sock(int32_t fd) + init_list_node_null(&sock->event_list); + } + +-void do_lwip_clean_sock(int32_t fd) ++void do_lwip_clean_sock(int fd) + { + struct lwip_sock *sock = get_socket_by_fd(fd); + if (sock == NULL || sock->stack == NULL) { +@@ -1193,7 +1193,15 @@ void do_lwip_clone_sockopt(struct lwip_sock *dst_sock, struct lwip_sock *src_soc + } + } + +-int32_t do_lwip_socket(int domain, int type, int protocol) ++int do_lwip_close(int fd) ++{ ++ int ret = lwip_close(fd); ++ do_lwip_clean_sock(fd); ++ posix_api->close_fn(fd); ++ return ret; ++} ++ ++int do_lwip_socket(int domain, int type, int protocol) + { + int32_t fd = lwip_socket(domain, type, 0); + if (fd < 0) { +@@ -1204,9 +1212,7 @@ int32_t do_lwip_socket(int domain, int type, int protocol) + + struct lwip_sock *sock = get_socket(fd); + if (sock == NULL || sock->stack == NULL) { +- lwip_close(fd); +- do_lwip_clean_sock(fd); +- posix_api->close_fn(fd); ++ do_lwip_close(fd); + return -1; + } + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 8dbd9ad..3123ca3 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -45,6 +45,22 @@ static struct protocol_stack_group g_stack_group = {0}; + + typedef void *(*stack_thread_func)(void *arg); + ++static void stack_set_state(struct protocol_stack *stack, enum rte_lcore_state_t state) ++{ ++ __atomic_store_n(&stack->state, state, __ATOMIC_RELEASE); ++} ++ ++static enum rte_lcore_state_t stack_get_state(struct protocol_stack *stack) ++{ ++ return __atomic_load_n(&stack->state, __ATOMIC_ACQUIRE); ++} ++ ++static void stack_wait_quit(struct protocol_stack *stack) ++{ ++ while (__atomic_load_n(&stack->state, __ATOMIC_ACQUIRE) != WAIT) { ++ rte_pause(); ++ } ++} + + void bind_to_stack_numa(struct protocol_stack *stack) + { +@@ -436,8 +452,9 @@ END: + return NULL; + } + +-void stack_polling(uint32_t wakeup_tick) ++int stack_polling(uint32_t wakeup_tick) + { ++ int force_quit; + struct cfg_params *cfg = get_global_cfg_params(); + uint8_t use_ltran_flag = cfg->use_ltran; + bool kni_switch = cfg->kni_switch; +@@ -448,7 +465,7 @@ void stack_polling(uint32_t wakeup_tick) + uint32_t read_connect_number = cfg->read_connect_number; + struct protocol_stack *stack = get_protocol_stack(); + +- poll_rpc_msg(stack, rpc_number); ++ force_quit = poll_rpc_msg(stack, rpc_number); + gazelle_eth_dev_poll(stack, use_ltran_flag, nic_read_number); + sys_timer_run(); + if (cfg->low_power_mod != 0) { +@@ -456,7 +473,7 @@ void stack_polling(uint32_t wakeup_tick) + } + + if (stack_mode_rtc) { +- return; ++ return force_quit; + } + + do_lwip_read_recvlist(stack, read_connect_number); +@@ -482,7 +499,7 @@ void stack_polling(uint32_t wakeup_tick) + kni_handle_rx(stack->port_id); + } + } +- return; ++ return force_quit; + } + + static void* gazelle_stack_thread(void *arg) +@@ -512,11 +529,14 @@ static void* gazelle_stack_thread(void *arg) + return NULL; + } + +- for (;;) { +- stack_polling(wakeup_tick); ++ stack_set_state(stack, RUNNING); ++ ++ while (stack_polling(wakeup_tick) == 0) { + wakeup_tick++; + } + ++ stack_set_state(stack, WAIT); ++ + return NULL; + } + +@@ -576,6 +596,7 @@ int32_t stack_group_init(void) + LSTACK_LOG(ERR, LSTACK, "sem_init failed errno=%d\n", errno); + return -1; + } ++ + stack_group->stack_setup_fail = 0; + + if (get_global_cfg_params()->is_primary) { +@@ -705,14 +726,10 @@ void stack_close(struct rpc_msg *msg) + return; + } + +- msg->result = lwip_close(fd); ++ msg->result = do_lwip_close(fd); + if (msg->result != 0) { + LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d failed %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); + } +- +- do_lwip_clean_sock(fd); +- +- posix_api->close_fn(fd); + } + + void stack_shutdown(struct rpc_msg *msg) +@@ -775,9 +792,7 @@ void stack_accept(struct rpc_msg *msg) + + struct lwip_sock *sock = get_socket(accept_fd); + if (sock == NULL || sock->stack == NULL) { +- lwip_close(accept_fd); +- do_lwip_clean_sock(accept_fd); +- posix_api->close_fn(accept_fd); ++ do_lwip_close(accept_fd); + LSTACK_LOG(ERR, LSTACK, "fd %d ret %d\n", fd, accept_fd); + return; + } +@@ -866,7 +881,6 @@ void stack_send(struct rpc_msg *msg) + if (sock == NULL) { + msg->result = -1; + LSTACK_LOG(ERR, LSTACK, "get sock error! fd=%d, len=%ld\n", fd, len); +- __sync_fetch_and_sub(&sock->call_num, 1); + return; + } + +@@ -1260,3 +1274,52 @@ int32_t stack_broadcast_accept(int32_t fd, struct sockaddr *addr, socklen_t *add + return stack_broadcast_accept4(fd, addr, addrlen, 0); + } + ++static void stack_all_fds_close(void) ++{ ++ for (int i = 3; i < GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS; i++) { ++ struct lwip_sock *sock = get_socket(i); ++ if (sock && sock->stack == get_protocol_stack()) { ++ do_lwip_close(i); ++ } ++ } ++} ++ ++static void stack_exit(void) ++{ ++ stack_all_fds_close(); ++} ++ ++void stack_exit_by_rpc(struct rpc_msg *msg) ++{ ++ stack_exit(); ++} ++ ++void stack_group_exit(void) ++{ ++ int i; ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ struct protocol_stack *stack = get_protocol_stack(); ++ ++ for (i = 0; i < stack_group->stack_num; i++) { ++ if ((stack_group->stacks[i] == NULL) || ++ stack_get_state(stack_group->stacks[i]) != RUNNING) { ++ continue; ++ } ++ ++ if (stack != stack_group->stacks[i]) { ++ rpc_call_stack_exit(stack_group->stacks[i]); ++ } ++ } ++ ++ if (stack != NULL) { ++ stack_exit(); ++ } ++ ++ for (i = 0; i < stack_group->stack_num; i++) { ++ if (stack_group->stacks[i] == NULL || stack == stack_group->stacks[i]) { ++ continue; ++ } ++ /* wait stack thread quit */ ++ stack_wait_quit(stack_group->stacks[i]); ++ } ++} +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index 0b2a62a..2af30d7 100644 +--- a/src/lstack/core/lstack_thread_rpc.c ++++ b/src/lstack/core/lstack_thread_rpc.c +@@ -90,8 +90,9 @@ static inline __attribute__((always_inline)) int32_t rpc_sync_call(lockless_queu + return ret; + } + +-void poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num) ++int poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num) + { ++ int force_quit = 0; + struct rpc_msg *msg = NULL; + + while (max_num--) { +@@ -108,6 +109,10 @@ void poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num) + stack->stats.call_null++; + } + ++ if (msg->func == stack_exit_by_rpc) { ++ force_quit = 1; ++ } ++ + if (!msg->recall_flag) { + if (msg->sync_flag) { + pthread_spin_unlock(&msg->lock); +@@ -118,6 +123,8 @@ void poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num) + msg->recall_flag = 0; + } + } ++ ++ return force_quit; + } + + int32_t rpc_call_conntable(struct protocol_stack *stack, void *conn_table, uint32_t max_conn) +@@ -246,6 +253,7 @@ int32_t rpc_call_arp(struct protocol_stack *stack, struct rte_mbuf *mbuf) + int32_t rpc_call_socket(int32_t domain, int32_t type, int32_t protocol) + { + struct protocol_stack *stack = get_bind_protocol_stack(); ++ + struct rpc_msg *msg = rpc_msg_alloc(stack, stack_socket); + if (msg == NULL) { + return -1; +@@ -271,6 +279,18 @@ int32_t rpc_call_close(int fd) + return rpc_sync_call(&stack->rpc_queue, msg); + } + ++int32_t rpc_call_stack_exit(struct protocol_stack *stack) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(stack, stack_exit_by_rpc); ++ if (msg == NULL) { ++ LSTACK_LOG(INFO, LSTACK, "rpc msg alloc failed\n"); ++ return -1; ++ } ++ ++ rpc_call(&stack->rpc_queue, msg); ++ return 0; ++} ++ + int32_t rpc_call_shutdown(int fd, int how) + { + struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +diff --git a/src/lstack/include/lstack_dummy_api.h b/src/lstack/include/lstack_dummy_api.h +new file mode 100644 +index 0000000..48bce31 +--- /dev/null ++++ b/src/lstack/include/lstack_dummy_api.h +@@ -0,0 +1,23 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++ ++#ifndef _LSTACK_DUMMY_API_H_ ++#define _LSTACK_DUMMY_API_H_ ++ ++int dummy_socket(int domain, int type, int protocol); ++ssize_t dummy_write(int s, const void *mem, size_t size); ++ssize_t dummy_writev(int s, const struct iovec *iov, int iovcnt); ++ssize_t dummy_sendmsg(int s, const struct msghdr *message, int flags); ++ssize_t dummy_send(int sockfd, const void *buf, size_t len, int flags); ++ssize_t dummy_sendto(int sockfd, const void *buf, size_t len, int flags, ++ const struct sockaddr *addr, socklen_t addrlen); ++#endif /* __LSTACK_DUMMY_API_H_ */ +diff --git a/src/lstack/include/lstack_lwip.h b/src/lstack/include/lstack_lwip.h +index a11489c..0a82781 100644 +--- a/src/lstack/include/lstack_lwip.h ++++ b/src/lstack/include/lstack_lwip.h +@@ -28,9 +28,9 @@ struct rpc_msg; + struct rte_mbuf; + struct protocol_stack; + +-int32_t do_lwip_socket(int domain, int type, int protocol); ++int do_lwip_socket(int domain, int type, int protocol); ++int do_lwip_close(int32_t fd); + void do_lwip_init_sock(int32_t fd); +-void do_lwip_clean_sock(int32_t fd); + void do_lwip_clone_sockopt(struct lwip_sock *dst_sock, struct lwip_sock *src_sock); + + struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_size, uint8_t *apiflags); +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index 6638984..8e2e807 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -46,6 +46,7 @@ struct protocol_stack { + uint32_t stack_idx; + cpu_set_t idle_cpuset; /* idle cpu in numa of stack, app thread bind to it */ + int32_t epollfd; /* kernel event thread epoll fd */ ++ volatile enum rte_lcore_state_t state; + + struct rte_mempool *rxtx_mbuf_pool; + struct rte_ring *rx_ring; +@@ -114,6 +115,7 @@ struct protocol_stack *get_bind_protocol_stack(void); + struct protocol_stack_group *get_protocol_stack_group(void); + + int32_t stack_group_init(void); ++void stack_group_exit(void); + int32_t stack_setup_thread(void); + int32_t stack_setup_app_thread(void); + +@@ -176,6 +178,8 @@ void stack_replenish_sendring(struct rpc_msg *msg); + void stack_get_conntable(struct rpc_msg *msg); + void stack_get_connnum(struct rpc_msg *msg); + void stack_recvlist_count(struct rpc_msg *msg); +-void stack_polling(uint32_t wakeup_tick); ++void stack_exit_by_rpc(struct rpc_msg *msg); ++ ++int stack_polling(uint32_t wakeup_tick); + void kni_handle_tx(struct rte_mbuf *mbuf); + #endif +diff --git a/src/lstack/include/lstack_thread_rpc.h b/src/lstack/include/lstack_thread_rpc.h +index ca8a510..633ef93 100644 +--- a/src/lstack/include/lstack_thread_rpc.h ++++ b/src/lstack/include/lstack_thread_rpc.h +@@ -62,7 +62,7 @@ struct protocol_stack; + struct rte_mbuf; + struct wakeup_poll; + struct lwip_sock; +-void poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num); ++int poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num); + void rpc_call_clean_epoll(struct protocol_stack *stack, struct wakeup_poll *wakeup); + int32_t rpc_call_msgcnt(struct protocol_stack *stack); + int32_t rpc_call_shadow_fd(struct protocol_stack *stack, int32_t fd, const struct sockaddr *addr, socklen_t addrlen); +@@ -89,6 +89,7 @@ int32_t rpc_call_ioctl(int fd, long cmd, void *argp); + int32_t rpc_call_replenish(struct protocol_stack *stack, struct lwip_sock *sock); + int32_t rpc_call_mbufpoolsize(struct protocol_stack *stack); + int32_t rpc_call_rpcpool_size(struct protocol_stack *stack); ++int32_t rpc_call_stack_exit(struct protocol_stack *stack); + + static inline __attribute__((always_inline)) void rpc_call(lockless_queue *queue, struct rpc_msg *msg) + { +diff --git a/src/lstack/include/lstack_wrap.h b/src/lstack/include/lstack_wrap.h +index 80e5f3c..dab5222 100644 +--- a/src/lstack/include/lstack_wrap.h ++++ b/src/lstack/include/lstack_wrap.h +@@ -14,6 +14,7 @@ + #define _LSTACK_WRAP_H_ + + void wrap_api_init(void); ++void wrap_api_set_dummy(void); + + #endif + +-- +2.27.0 + diff --git a/0086-fix-EPOLLIN-event-error.patch b/0086-fix-EPOLLIN-event-error.patch new file mode 100644 index 0000000..c534f3e --- /dev/null +++ b/0086-fix-EPOLLIN-event-error.patch @@ -0,0 +1,52 @@ +From a72ed2effc718023316452866632f52058ae8218 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Mon, 11 Dec 2023 13:24:33 +0000 +Subject: [PATCH] fix EPOLLIN event error + +--- + src/lstack/api/lstack_epoll.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index 7825bed..7dbef9d 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -61,6 +61,17 @@ void add_sock_event_nolock(struct lwip_sock *sock, uint32_t event) + if (wakeup == NULL || wakeup->type == WAKEUP_CLOSE || (event & sock->epoll_events) == 0) { + return; + } ++ ++ if (!get_global_cfg_params()->stack_mode_rtc) { ++ if (event == EPOLLIN && !NETCONN_IS_DATAIN(sock) && !NETCONN_IS_ACCEPTIN(sock)) { ++ return; ++ } ++ ++ if (event == EPOLLOUT && !NETCONN_IS_OUTIDLE(sock)) { ++ return; ++ } ++ } ++ + sock->events |= (event == EPOLLERR) ? (EPOLLIN | EPOLLERR) : (event & sock->epoll_events); + if (list_is_null(&sock->event_list)) { + list_add_node(&wakeup->event_list, &sock->event_list); +@@ -88,7 +99,16 @@ void add_sock_event(struct lwip_sock *sock, uint32_t event) + + void del_sock_event_nolock(struct lwip_sock *sock, uint32_t event) + { +- sock->events &= ~event; ++ if (get_global_cfg_params()->stack_mode_rtc) { ++ sock->events &= ~event; ++ } else { ++ if ((event & EPOLLOUT) && !NETCONN_IS_OUTIDLE(sock)) { ++ sock->events &= ~EPOLLOUT; ++ } ++ if ((event & EPOLLIN) && !NETCONN_IS_DATAIN(sock) && !NETCONN_IS_ACCEPTIN(sock)) { ++ sock->events &= ~EPOLLIN; ++ } ++ } + + if (sock->events == 0) { + list_del_node_null(&sock->event_list); +-- +2.27.0 + diff --git a/0087-mod-time-err.patch b/0087-mod-time-err.patch new file mode 100644 index 0000000..9893b9a --- /dev/null +++ b/0087-mod-time-err.patch @@ -0,0 +1,25 @@ +From 1d578011ed2ee7e508af119d963e7283b1d0dc6f Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Mon, 18 Dec 2023 09:52:21 +0800 +Subject: [PATCH] mod time err + +--- + src/ltran/ltran_dfx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 25d4f35..c8dc562 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -1018,7 +1018,7 @@ static void gazelle_localtime_string(char* str, int buff_len) + time_t t = time.tv_sec; + tm = localtime(&t); + int ret = sprintf_s(str, buff_len, "%d-%d-%d %d:%d:%d", +- tm->tm_yday + 1900, tm->tm_mon + 1, tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec); ++ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); + if (ret < 0) { + printf("gazelle_localtime_string sprintf_s fail ret=%d\n", ret); + return; +-- +2.27.0 + diff --git a/0088-fix-gazellectl-lstack-show-ip-r-with-ltran-error-log.patch b/0088-fix-gazellectl-lstack-show-ip-r-with-ltran-error-log.patch new file mode 100644 index 0000000..a9076d1 --- /dev/null +++ b/0088-fix-gazellectl-lstack-show-ip-r-with-ltran-error-log.patch @@ -0,0 +1,39 @@ +From 24b45463b653cf2aa204ca3ff303f8fe848d416f Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Sat, 16 Dec 2023 20:21:21 +0800 +Subject: [PATCH] fix gazellectl lstack show ip -r with ltran error && log info + display unknow error + +--- + src/lstack/core/lstack_stack_stat.c | 1 + + src/ltran/ltran_dfx.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index e4ccc41..23571b4 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -201,6 +201,7 @@ static void get_stack_dfx_data(struct gazelle_stack_dfx_data *dfx, struct protoc + switch (stat_mode) { + case GAZELLE_STAT_LSTACK_SHOW: + case GAZELLE_STAT_LSTACK_SHOW_RATE: ++ case GAZELLE_STAT_LTRAN_SHOW_LSTACK: + get_stack_stats(dfx, stack); + /* fall through */ + case GAZELLE_STAT_LSTACK_SHOW_AGGREGATE: +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 25d4f35..5291fe0 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -99,7 +99,7 @@ static void gazelle_print_lstack_nic_features(void *buf, const struct gazelle_st + static struct gazelle_dfx_list g_gazelle_dfx_tbl[] = { + {GAZELLE_STAT_LTRAN_SHOW, sizeof(struct gazelle_stat_ltran_total), gazelle_print_ltran_stat_total}, + {GAZELLE_STAT_LTRAN_SHOW_RATE, sizeof(struct gazelle_stat_ltran_total), gazelle_print_ltran_stat_rate}, +- {GAZELLE_STAT_LTRAN_SHOW_LB_RATE, sizeof(struct gazelle_stat_ltran_total), gazelle_print_ltran_stat_lb_rate}, ++ {GAZELLE_STAT_LTRAN_SHOW_LB_RATE, sizeof(struct gazelle_stat_lstack_total), gazelle_print_ltran_stat_lb_rate}, + {GAZELLE_STAT_LTRAN_SHOW_INSTANCE, sizeof(struct gazelle_stat_ltran_client), gazelle_print_ltran_stat_client}, + {GAZELLE_STAT_LTRAN_SHOW_BURST, sizeof(struct gazelle_stat_ltran_total), gazelle_print_ltran_stat_burst}, + {GAZELLE_STAT_LTRAN_SHOW_LATENCY, sizeof(struct in_addr), gazelle_print_ltran_stat_latency}, +-- +2.27.0 + diff --git a/0089-fix-udp-multicast-bind-error.patch b/0089-fix-udp-multicast-bind-error.patch new file mode 100644 index 0000000..37184ea --- /dev/null +++ b/0089-fix-udp-multicast-bind-error.patch @@ -0,0 +1,29 @@ +From d14e214a9cd32f05f097b023baa7c4a6d8629fce Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 18 Dec 2023 21:30:32 +0800 +Subject: [PATCH] fix udp multicast bind error + +--- + src/lstack/api/lstack_wrap.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 89f54f8..5feadc3 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -211,6 +211,12 @@ static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen + return posix_api->bind_fn(s, name, namelen); + } + ++ /* select user path when udp enable and ip addr is multicast */ ++ if (IN_MULTICAST(ntohl(((struct sockaddr_in *)name)->sin_addr.s_addr))) { ++ SET_CONN_TYPE_LIBOS(sock->conn); ++ return g_wrap_api->bind_fn(s, name, namelen); ++ } ++ + if (match_host_addr(((struct sockaddr_in *)name)->sin_addr.s_addr)) { + /* maybe kni addr */ + if (posix_api->bind_fn(s, name, namelen) != 0) { +-- +2.27.0 + diff --git a/0090-support-netperf.patch b/0090-support-netperf.patch new file mode 100644 index 0000000..d0f70dc --- /dev/null +++ b/0090-support-netperf.patch @@ -0,0 +1,179 @@ +From 8dfa19585b0e5b23e7855e1d544c41dd7a6a1dd9 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Fri, 15 Dec 2023 17:56:30 +0800 +Subject: [PATCH] support netperf + +--- + src/lstack/api/lstack_wrap.c | 13 ++++++------- + src/lstack/core/lstack_lwip.c | 21 +++++++++++++++++++-- + src/lstack/core/lstack_protocol_stack.c | 19 +++++++++++-------- + src/lstack/include/posix/lstack_epoll.h | 19 +++++++++++++++++++ + src/ltran/ltran_dfx.c | 2 +- + 5 files changed, 56 insertions(+), 18 deletions(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 65a0a5a..a226dc4 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -276,11 +276,6 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name + return posix_api->connect_fn(s, name, namelen); + } + +- if (!netconn_is_nonblocking(sock->conn)) { +- LSTACK_LOG(ERR, LSTACK, "connect does not support blocking fd currently\n"); +- GAZELLE_RETURN(EINVAL); +- } +- + int32_t ret = 0; + int32_t remote_port; + bool is_local = is_dst_ip_localhost(name); +@@ -347,7 +342,11 @@ static bool unsupport_optname(int32_t optname) + optname == SO_PROTOCOL || + optname == TCP_QUICKACK || + optname == SO_SNDTIMEO || +- optname == SO_RCVTIMEO) { ++ optname == SO_RCVTIMEO || ++ optname == SO_SNDBUF || ++ optname == TCP_INFO || ++ optname == TCP_MAXSEG || ++ optname == TCP_CONGESTION) { + return true; + } + return false; +@@ -615,7 +614,7 @@ static int32_t do_select(int32_t nfds, fd_set *readfds, fd_set *writefds, fd_set + return posix_api->select_fn(nfds, readfds, writefds, exceptfds, timeout); + } + +- return posix_api->select_fn(nfds, readfds, writefds, exceptfds, timeout); ++ return g_wrap_api->select_fn(nfds, readfds, writefds, exceptfds, timeout); + } + + #define WRAP_VA_PARAM(_fd, _cmd, _lwip_fcntl, _fcntl_fn) \ +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index fb286d6..a944f7a 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -564,6 +564,12 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + uint32_t write_avail = gazelle_ring_readable_count(sock->send_ring); + struct wakeup_poll *wakeup = sock->wakeup; + ++ if (!netconn_is_nonblocking(sock->conn)) { ++ while (write_avail < write_num) { ++ write_avail = gazelle_ring_readable_count(sock->send_ring); ++ } ++ } ++ + /* send_ring is full, data attach last pbuf */ + if (write_avail == 0) { + if (!get_global_cfg_params()->expand_send_ring) { +@@ -1005,8 +1011,19 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + pbuf = sock->recv_lastdata; + sock->recv_lastdata = NULL; + } else { +- if (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1) { +- break; ++ if (netconn_is_nonblocking(sock->conn)) { ++ if (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1) { ++ break; ++ } ++ } else { ++ while (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1 && recvd == 0) { ++ /* if the connection is disconnected, recv return 0 */ ++ if ((sock->errevent > 0 || (sock->conn->pcb.tcp->flags & TF_FIN)) && !NETCONN_IS_DATAIN(sock)) { ++ return 0; ++ } ++ ++ lstack_block_wait(sock->wakeup); ++ } + } + } + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 8dbd9ad..414b5f8 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -268,12 +268,8 @@ static void wakeup_kernel_event(struct protocol_stack *stack) + continue; + } + +- __atomic_store_n(&wakeup->have_kernel_event, true, __ATOMIC_RELEASE); +- if (__atomic_load_n(&wakeup->in_wait, __ATOMIC_ACQUIRE)) { +- __atomic_store_n(&wakeup->in_wait, false, __ATOMIC_RELEASE); +- rte_mb(); +- pthread_mutex_unlock(&wakeup->wait); +- } ++ __atomic_store_n(&wakeup->have_kernel_event, true, __ATOMIC_RELEASE); ++ lstack_block_wakeup(wakeup); + } + + return; +@@ -1233,14 +1229,21 @@ int32_t stack_broadcast_bind(int32_t fd, const struct sockaddr *name, socklen_t + int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *addrlen, int flags) + { + int32_t ret = -1; +- ++ struct lwip_sock *min_sock = NULL; + struct lwip_sock *sock = get_socket(fd); + if (sock == NULL) { + errno = EINVAL; + return -1; + } + +- struct lwip_sock *min_sock = get_min_accept_sock(fd); ++ if (netconn_is_nonblocking(sock->conn)) { ++ min_sock = get_min_accept_sock(fd); ++ } else { ++ while ((min_sock = get_min_accept_sock(fd)) == NULL) { ++ lstack_block_wait(sock->wakeup); ++ } ++ } ++ + if (min_sock && min_sock->conn) { + ret = rpc_call_accept(min_sock->conn->socket, addr, addrlen, flags); + } +diff --git a/src/lstack/include/posix/lstack_epoll.h b/src/lstack/include/posix/lstack_epoll.h +index 9c34eb3..7591f0f 100644 +--- a/src/lstack/include/posix/lstack_epoll.h ++++ b/src/lstack/include/posix/lstack_epoll.h +@@ -80,6 +80,25 @@ int32_t lstack_rtc_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t + int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout); + int lstack_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeval); + ++static inline void lstack_block_wait(struct wakeup_poll *wakeup) ++{ ++ if (wakeup == NULL) { ++ return; ++ } ++ ++ __atomic_store_n(&wakeup->in_wait, true, __ATOMIC_RELEASE); ++ pthread_mutex_lock(&wakeup->wait); ++} ++ ++static inline void lstack_block_wakeup(struct wakeup_poll *wakeup) ++{ ++ if (wakeup && __atomic_load_n(&wakeup->in_wait, __ATOMIC_ACQUIRE)) { ++ __atomic_store_n(&wakeup->in_wait, false, __ATOMIC_RELEASE); ++ rte_mb(); ++ pthread_mutex_unlock(&wakeup->wait); ++ } ++} ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 2a84cb8..ee80359 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -168,7 +168,7 @@ static void gazelle_print_lstack_nic_features(void *buf, const struct gazelle_st + printf("###### NIC offload and other features for port %-2d #########\n", f->port_id); + + printf("tx-ipv4-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_IPV4_CKSUM) ? "on" : "off"); +- printf("tx-tcp_checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_CKSUM) ? "on" : "off"); ++ printf("tx-tcp-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_CKSUM) ? "on" : "off"); + printf("tx-tcp-tso: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_TSO) ? "on" : "off"); + printf("tx-udp-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_UDP_CKSUM) ? "on" : "off"); + printf("tx-vlan-insert: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_VLAN_INSERT) ? "on" : "off"); +-- +2.27.0 + diff --git a/0091-fix-alloc-not-free.patch b/0091-fix-alloc-not-free.patch new file mode 100644 index 0000000..33c3c55 --- /dev/null +++ b/0091-fix-alloc-not-free.patch @@ -0,0 +1,49 @@ +From 053024d4cbedc106276e25a7ace5d833f8a62dea Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Wed, 20 Dec 2023 01:37:12 +0000 +Subject: [PATCH] fix alloc not free + +--- + src/lstack/core/lstack_cfg.c | 2 ++ + src/lstack/core/lstack_dpdk.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 6324c97..f639473 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -1185,11 +1185,13 @@ static int32_t parse_bond_slave_mac(void) + if (k >= GAZELLE_MAX_BOND_NUM) { + LSTACK_PRE_LOG(LSTACK_ERR, "cfg: too many slave mac address. The maximum number of mac address is %d.\n", + GAZELLE_MAX_BOND_NUM); ++ free(bond_slave_mac_tmp); + return -EINVAL; + } + ret = str_to_eth_addr(mac_addr, g_config_params.bond_slave_mac_addr[k].addr_bytes); + if (ret != 0) { + LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid device name %s ret=%d.\n", mac_addr, ret); ++ free(bond_slave_mac_tmp); + return ret; + } + mac_addr = strtok_s(NULL, delim, &tmp); +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index e20dea8..6933ecd 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -553,11 +553,13 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + int slave_id = rte_eth_bond_primary_get(port_id); + if (slave_id < 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk get bond primary port failed port = %d\n", slave_id); ++ free(eth_params); + return slave_id; + } + ret = rte_eth_dev_info_get(slave_id, &slave_dev_info); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk get bond dev info failed ret = %d\n", ret); ++ free(eth_params); + return ret; + } + dev_info.rx_offload_capa = slave_dev_info.rx_offload_capa; +-- +2.27.0 + diff --git a/0092-sigaction-fix-deprecated-signal-flags.patch b/0092-sigaction-fix-deprecated-signal-flags.patch new file mode 100644 index 0000000..899febb --- /dev/null +++ b/0092-sigaction-fix-deprecated-signal-flags.patch @@ -0,0 +1,59 @@ +From 3af406243bb2a4a6c8ac5b3f1d98a9cd7e0af295 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Wed, 20 Dec 2023 11:37:13 +0800 +Subject: [PATCH] sigaction: fix deprecated signal flags + +--- + src/lstack/api/lstack_signal.c | 10 +++++++++- + src/lstack/core/lstack_lwip.c | 7 ++++--- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/src/lstack/api/lstack_signal.c b/src/lstack/api/lstack_signal.c +index 6da6eb4..314c14c 100644 +--- a/src/lstack/api/lstack_signal.c ++++ b/src/lstack/api/lstack_signal.c +@@ -57,7 +57,7 @@ static inline bool match_hijack_signal(int sig) + + static void lstack_sig_default_handler(int sig) + { +- LSTACK_LOG(ERR, LSTACK, "lstack dumped,caught signal:%d\n", sig); ++ LSTACK_LOG(ERR, LSTACK, "lstack dumped, caught signal: %d\n", sig); + if (get_global_cfg_params() && get_global_cfg_params()->is_primary) { + delete_primary_path(); + } +@@ -94,5 +94,13 @@ int lstack_sigaction(int sig_num, const struct sigaction *action, struct sigacti + new_action.sa_handler = lstack_sig_default_handler; + return posix_api->sigaction_fn(sig_num, &new_action, old_action); + } ++ ++ /* SA_INTERRUPT is deprecated, use SA_RESETHAND instead. */ ++ if ((match_hijack_signal(sig_num) != 0) && (action && action->sa_flags == SA_INTERRUPT)) { ++ new_action = *action; ++ new_action.sa_flags |= SA_RESETHAND; ++ return posix_api->sigaction_fn(sig_num, &new_action, old_action); ++ } ++ + return posix_api->sigaction_fn(sig_num, action, old_action); + } +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 34ec1bd..100f075 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -564,10 +564,11 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + uint32_t write_avail = gazelle_ring_readable_count(sock->send_ring); + struct wakeup_poll *wakeup = sock->wakeup; + +- if (!netconn_is_nonblocking(sock->conn)) { +- while (write_avail < write_num) { +- write_avail = gazelle_ring_readable_count(sock->send_ring); ++ while (!netconn_is_nonblocking(sock->conn) && (write_avail < write_num)) { ++ if (sock->errevent > 0) { ++ GAZELLE_RETURN(ENOTCONN); + } ++ write_avail = gazelle_ring_readable_count(sock->send_ring); + } + + /* send_ring is full, data attach last pbuf */ +-- +2.27.0 + diff --git a/0093-fix-gazellectl-c-msg-error.patch b/0093-fix-gazellectl-c-msg-error.patch new file mode 100644 index 0000000..26cc6c0 --- /dev/null +++ b/0093-fix-gazellectl-c-msg-error.patch @@ -0,0 +1,38 @@ +From 887130c90c7875b4c0860ed0667224418e690752 Mon Sep 17 00:00:00 2001 +From: jinag12 +Date: Thu, 21 Dec 2023 09:03:02 +0000 +Subject: [PATCH] fix gazellectl -c msg error + +Signed-off-by: jinag12 +--- + src/lstack/core/lstack_lwip.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 15f99f9..1913d03 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -1158,15 +1158,14 @@ static void copy_pcb_to_conn(struct gazelle_stat_lstack_conn_info *conn, const s + conn->keep_intvl = pcb->keep_intvl; + conn->keep_cnt = pcb->keep_cnt; + +- if (netconn != NULL && netconn->recvmbox != NULL) { +- conn->recv_cnt = rte_ring_count(netconn->recvmbox->ring); ++ if (netconn != NULL) { + conn->fd = netconn->socket; +- ++ conn->recv_cnt = (netconn->recvmbox == NULL) ? 0 : rte_ring_count(netconn->recvmbox->ring); + struct lwip_sock *sock = get_socket(netconn->socket); +- if (netconn->socket > 0 && sock != NULL && sock->recv_ring != NULL && sock->send_ring != NULL) { +- conn->recv_ring_cnt = gazelle_ring_readable_count(sock->recv_ring); ++ if (sock != NULL) { ++ conn->recv_ring_cnt = (sock->recv_ring == NULL) ? 0 : gazelle_ring_readable_count(sock->recv_ring); + conn->recv_ring_cnt += (sock->recv_lastdata) ? 1 : 0; +- conn->send_ring_cnt = gazelle_ring_readover_count(sock->send_ring); ++ conn->send_ring_cnt = (sock->send_ring == NULL) ? 0 : gazelle_ring_readover_count(sock->send_ring); + conn->events = sock->events; + conn->epoll_events = sock->epoll_events; + conn->eventlist = !list_is_null(&sock->event_list); +-- +2.27.0 + diff --git a/0094-CFG-fix-check-func-strdup-return-value-is-NULL.patch b/0094-CFG-fix-check-func-strdup-return-value-is-NULL.patch new file mode 100644 index 0000000..ddd4df6 --- /dev/null +++ b/0094-CFG-fix-check-func-strdup-return-value-is-NULL.patch @@ -0,0 +1,107 @@ +From 43985056c5446c0ad45acb2309165543bd8e15e1 Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Fri, 22 Dec 2023 15:42:40 +0800 +Subject: [PATCH] CFG:fix check func strdup return value is NULL + +--- + src/lstack/core/lstack_cfg.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 6324c97..6e97c96 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -145,6 +145,15 @@ static struct config_vector_t g_config_tbl[] = { + { NULL, NULL } + }; + ++static char* strdup_assert_return(const char* str) ++{ ++ char* result = strdup(str); ++ if (result == NULL) { ++ LSTACK_EXIT(1, "strdup_assert_return failed, func strdup return NULL!\n"); ++ } ++ return result; ++} ++ + struct cfg_params *get_global_cfg_params(void) + { + return &g_config_params; +@@ -336,15 +345,15 @@ static int32_t parse_stack_cpu_number(void) + if (!have_corelist_arg(g_config_params.dpdk_argc, g_config_params.dpdk_argv)) { + int32_t idx = get_param_idx(g_config_params.dpdk_argc, g_config_params.dpdk_argv, OPT_BIND_CORELIST); + if (idx < 0) { +- g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup(OPT_BIND_CORELIST); ++ g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup_assert_return(OPT_BIND_CORELIST); + g_config_params.dpdk_argc++; + +- g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup(args); ++ g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup_assert_return(args); + g_config_params.dpdk_argc++; + } + } + +- char *tmp_arg = strdup(args); ++ char *tmp_arg = strdup_assert_return(args); + int32_t cnt = separate_str_to_array(tmp_arg, g_config_params.cpus, CFG_MAX_CPUS, CFG_MAX_CPUS); + free(tmp_arg); + if (cnt <= 0 || cnt > CFG_MAX_CPUS) { +@@ -369,15 +378,15 @@ static int32_t parse_stack_cpu_number(void) + if (!have_corelist_arg(g_config_params.dpdk_argc, g_config_params.dpdk_argv)) { + int32_t idx = get_param_idx(g_config_params.dpdk_argc, g_config_params.dpdk_argv, OPT_BIND_CORELIST); + if (idx < 0) { +- g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup(OPT_BIND_CORELIST); ++ g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup_assert_return(OPT_BIND_CORELIST); + g_config_params.dpdk_argc++; + +- g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup(args); ++ g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup_assert_return(args); + g_config_params.dpdk_argc++; + } + } + +- char *tmp_arg_send = strdup(args); ++ char *tmp_arg_send = strdup_assert_return(args); + int32_t send_cpu_cnt = separate_str_to_array(tmp_arg_send, g_config_params.send_cpus, + CFG_MAX_CPUS, CFG_MAX_CPUS); + free(tmp_arg_send); +@@ -396,15 +405,15 @@ static int32_t parse_stack_cpu_number(void) + if (!have_corelist_arg(g_config_params.dpdk_argc, g_config_params.dpdk_argv)) { + int32_t idx = get_param_idx(g_config_params.dpdk_argc, g_config_params.dpdk_argv, OPT_BIND_CORELIST); + if (idx < 0) { +- g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup(OPT_BIND_CORELIST); ++ g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup_assert_return(OPT_BIND_CORELIST); + g_config_params.dpdk_argc++; + +- g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup(args); ++ g_config_params.dpdk_argv[g_config_params.dpdk_argc] = strdup_assert_return(args); + g_config_params.dpdk_argc++; + } + } + +- char *tmp_arg_recv = strdup(args); ++ char *tmp_arg_recv = strdup_assert_return(args); + int32_t recv_cpu_cnt = separate_str_to_array(tmp_arg_recv, g_config_params.recv_cpus, + CFG_MAX_CPUS, CFG_MAX_CPUS); + free(tmp_arg_recv); +@@ -450,7 +459,7 @@ static int32_t parse_app_exclude_cpus(void) + return -EINVAL; + } + +- tmp_arg = strdup(args); ++ tmp_arg = strdup_assert_return(args); + cnt = separate_str_to_array(tmp_arg, g_config_params.app_exclude_cpus, CFG_MAX_CPUS, CFG_MAX_CPUS); + free(tmp_arg); + if (cnt <= 0 || cnt > CFG_MAX_CPUS) { +@@ -1176,7 +1185,7 @@ static int32_t parse_bond_slave_mac(void) + } + + int32_t k = 0; +- char *bond_slave_mac_tmp = strdup(bond_slave_mac); ++ char *bond_slave_mac_tmp = strdup_assert_return(bond_slave_mac); + char *tmp = NULL; + const char *delim = ";"; + +-- +2.27.0 + diff --git a/0095-fix-func-separate_str_to_array-overflow-problem.patch b/0095-fix-func-separate_str_to_array-overflow-problem.patch new file mode 100644 index 0000000..1cfbaf7 --- /dev/null +++ b/0095-fix-func-separate_str_to_array-overflow-problem.patch @@ -0,0 +1,26 @@ +From f6a7a9585bfb82680519034869b4141c514d9214 Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Mon, 25 Dec 2023 00:34:55 +0800 +Subject: [PATCH] fix func separate_str_to_array overflow problem + +--- + src/common/gazelle_parse_config.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/common/gazelle_parse_config.c b/src/common/gazelle_parse_config.c +index 42e12b5..77d0b82 100644 +--- a/src/common/gazelle_parse_config.c ++++ b/src/common/gazelle_parse_config.c +@@ -80,6 +80,9 @@ int32_t separate_str_to_array(char *args, uint32_t *array, int32_t array_size, i + for (idx = min; idx <= max; idx++) { + array[count] = idx; + count++; ++ if (count > array_size) { ++ return -1; ++ } + } + min = array_size; + } else { +-- +2.27.0 + diff --git a/0096-use-default-nonblock-mode.patch b/0096-use-default-nonblock-mode.patch new file mode 100644 index 0000000..e9e1bb8 --- /dev/null +++ b/0096-use-default-nonblock-mode.patch @@ -0,0 +1,76 @@ +From 47ab261c2b533975a59b34f06da0ccf83692bb78 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Tue, 26 Dec 2023 16:53:58 +0000 +Subject: [PATCH] use default nonblock mode + +--- + src/lstack/core/lstack_cfg.c | 12 ++++++++++++ + src/lstack/core/lstack_protocol_stack.c | 5 ++++- + src/lstack/include/lstack_cfg.h | 1 + + 3 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index a292070..d9c23fb 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -80,6 +80,7 @@ static int32_t parse_nic_rxqueue_size(void); + static int32_t parse_nic_txqueue_size(void); + static int32_t parse_stack_thread_mode(void); + static int32_t parse_nic_vlan_mode(void); ++static int32_t parse_defaule_nonblock_mode(void); + + #define PARSE_ARG(_arg, _arg_string, _default_val, _min_val, _max_val, _ret) \ + do { \ +@@ -142,6 +143,7 @@ static struct config_vector_t g_config_tbl[] = { + { "nic_txqueue_size", parse_nic_txqueue_size}, + { "stack_thread_mode", parse_stack_thread_mode }, + { "nic_vlan_mode", parse_nic_vlan_mode }, ++ { "nonblock_mode", parse_defaule_nonblock_mode }, + { NULL, NULL } + }; + +@@ -1280,3 +1282,13 @@ static int32_t parse_nic_vlan_mode(void) + return ret; + } + ++static int32_t parse_defaule_nonblock_mode(void) ++{ ++ int32_t ret; ++ PARSE_ARG(g_config_params.nonblock_mode, "nonblock_mode", 1, 0, 1, ret); ++ if (ret != 0) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid nonblock mode value %d. only support 0 or 1\n", \ ++ g_config_params.nonblock_mode); ++ } ++ return ret; ++} +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 9158d20..a000224 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -1287,7 +1287,10 @@ int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *ad + + int32_t stack_broadcast_accept(int32_t fd, struct sockaddr *addr, socklen_t *addrlen) + { +- return stack_broadcast_accept4(fd, addr, addrlen, 0); ++ if (get_global_cfg_params()->nonblock_mode) ++ return stack_broadcast_accept4(fd, addr, addrlen, O_NONBLOCK); ++ else ++ return stack_broadcast_accept4(fd, addr, addrlen, 0); + } + + static void stack_all_fds_close(void) +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index a6bdfd5..82e96d8 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -118,6 +118,7 @@ struct cfg_params { + bool udp_enable; + struct cfg_nic_params nic; + bool stack_mode_rtc; ++ bool nonblock_mode; + }; + + struct cfg_params *get_global_cfg_params(void); +-- +2.27.0 + diff --git a/0097-fix-rte_ring_create-free-time-consuming.patch b/0097-fix-rte_ring_create-free-time-consuming.patch new file mode 100644 index 0000000..55b45a4 --- /dev/null +++ b/0097-fix-rte_ring_create-free-time-consuming.patch @@ -0,0 +1,128 @@ +From 66b0ba4be7a5c3b79482eafdc28fd75e8f44e761 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Wed, 27 Dec 2023 10:26:07 +0800 +Subject: [PATCH] fix rte_ring_create/free time consuming + +--- + src/lstack/core/lstack_dpdk.c | 27 +++------------------------ + src/lstack/core/lstack_lwip.c | 14 ++++++-------- + src/lstack/include/lstack_dpdk.h | 1 - + 3 files changed, 9 insertions(+), 33 deletions(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 6933ecd..729a84c 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -245,43 +245,22 @@ struct rte_mempool *create_mempool(const char *name, uint32_t count, uint32_t si + return mempool; + } + +-struct rte_ring *create_ring(const char *name, uint32_t count, uint32_t flags, int32_t queue_id) +-{ +- char ring_name[RTE_RING_NAMESIZE] = {0}; +- struct rte_ring *ring; +- +- int32_t ret = snprintf_s(ring_name, sizeof(ring_name), RTE_RING_NAMESIZE - 1, +- "%s_%d_%d", name, get_global_cfg_params()->process_idx, queue_id); +- if (ret < 0) { +- LSTACK_LOG(ERR, LSTACK, "snprintf_s fail ret=%d\n", ret); +- return NULL; +- } +- +- ring = rte_ring_create(ring_name, count, rte_socket_id(), flags); +- if (ring == NULL) { +- LSTACK_LOG(ERR, LSTACK, "%s create failed. errno: %d.\n", name, rte_errno); +- } +- +- return ring; +-} +- + int32_t create_shared_ring(struct protocol_stack *stack) + { + lockless_queue_init(&stack->rpc_queue); + + if (use_ltran()) { +- stack->rx_ring = create_ring("RING_RX", VDEV_RX_QUEUE_SZ, RING_F_SP_ENQ | RING_F_SC_DEQ, stack->queue_id); ++ stack->rx_ring = gazelle_ring_create_fast("RING_RX", VDEV_RX_QUEUE_SZ, RING_F_SP_ENQ | RING_F_SC_DEQ); + if (stack->rx_ring == NULL) { + return -1; + } + +- stack->tx_ring = create_ring("RING_TX", VDEV_TX_QUEUE_SZ, RING_F_SP_ENQ | RING_F_SC_DEQ, stack->queue_id); ++ stack->tx_ring = gazelle_ring_create_fast("RING_TX", VDEV_TX_QUEUE_SZ, RING_F_SP_ENQ | RING_F_SC_DEQ); + if (stack->tx_ring == NULL) { + return -1; + } + +- stack->reg_ring = create_ring("SHARED_REG_RING", VDEV_REG_QUEUE_SZ, RING_F_SP_ENQ | RING_F_SC_DEQ, +- stack->queue_id); ++ stack->reg_ring = gazelle_ring_create_fast("SHARED_REG_RING", VDEV_REG_QUEUE_SZ, RING_F_SP_ENQ | RING_F_SC_DEQ); + if (stack->reg_ring == NULL) { + return -1; + } +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index c167ba4..4953f3d 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -72,13 +72,13 @@ static void reset_sock_data(struct lwip_sock *sock) + /* check null pointer in ring_free func */ + if (sock->recv_ring) { + free_ring_pbuf(sock->recv_ring); +- rte_ring_free(sock->recv_ring); ++ gazelle_ring_free_fast(sock->recv_ring); + sock->recv_ring = NULL; + } + + if (sock->send_ring) { + free_ring_pbuf(sock->send_ring); +- rte_ring_free(sock->send_ring); ++ gazelle_ring_free_fast(sock->send_ring); + sock->send_ring = NULL; + } + +@@ -169,7 +169,6 @@ static bool replenish_send_idlembuf(struct protocol_stack *stack, struct lwip_so + + void do_lwip_init_sock(int32_t fd) + { +- static _Atomic uint32_t name_tick = 0; + struct protocol_stack *stack = get_protocol_stack(); + struct lwip_sock *sock = get_socket(fd); + if (sock == NULL) { +@@ -178,18 +177,17 @@ void do_lwip_init_sock(int32_t fd) + + reset_sock_data(sock); + +- sock->recv_ring = create_ring("sock_recv", SOCK_RECV_RING_SIZE, RING_F_SP_ENQ | RING_F_SC_DEQ, +- atomic_fetch_add(&name_tick, 1)); ++ sock->recv_ring = gazelle_ring_create_fast("sock_recv", SOCK_RECV_RING_SIZE, RING_F_SP_ENQ | RING_F_SC_DEQ); + if (sock->recv_ring == NULL) { + LSTACK_LOG(ERR, LSTACK, "sock_recv create failed. errno: %d.\n", rte_errno); + return; + } + +- sock->send_ring = create_ring("sock_send", ++ sock->send_ring = gazelle_ring_create_fast("sock_send", + get_global_cfg_params()->send_ring_size, +- RING_F_SP_ENQ | RING_F_SC_DEQ, +- atomic_fetch_add(&name_tick, 1)); ++ RING_F_SP_ENQ | RING_F_SC_DEQ); + if (sock->send_ring == NULL) { ++ gazelle_ring_free_fast(sock->recv_ring); + LSTACK_LOG(ERR, LSTACK, "sock_send create failed. errno: %d.\n", rte_errno); + return; + } +diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h +index 05f5bc6..4a160e0 100644 +--- a/src/lstack/include/lstack_dpdk.h ++++ b/src/lstack/include/lstack_dpdk.h +@@ -44,7 +44,6 @@ struct rte_mbuf; + int32_t fill_mbuf_to_ring(struct rte_mempool *mempool, struct rte_ring *ring, uint32_t mbuf_num); + int32_t dpdk_eal_init(void); + int32_t pktmbuf_pool_init(struct protocol_stack *stack); +-struct rte_ring *create_ring(const char *name, uint32_t count, uint32_t flags, int32_t queue_id); + struct rte_mempool *create_mempool(const char *name, uint32_t count, uint32_t size, + uint32_t flags, int32_t idx); + int32_t create_shared_ring(struct protocol_stack *stack); +-- +2.27.0 + diff --git a/0098-optimize-shutdown-exit-process.patch b/0098-optimize-shutdown-exit-process.patch new file mode 100644 index 0000000..e444784 --- /dev/null +++ b/0098-optimize-shutdown-exit-process.patch @@ -0,0 +1,25 @@ +From 5ca16b89699250a52d11ee5a181fef227fd399b6 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 18 Dec 2023 10:50:53 +0800 +Subject: [PATCH] optimize shutdown exit process + +--- + src/lstack/core/lstack_protocol_stack.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 8dbd9ad..564f055 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -722,7 +722,7 @@ void stack_shutdown(struct rpc_msg *msg) + struct protocol_stack *stack = get_protocol_stack_by_fd(fd); + struct lwip_sock *sock = get_socket(fd); + +- if (sock && NETCONN_IS_DATAOUT(sock)) { ++ if (sock && __atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) > 0) { + msg->recall_flag = 1; + rpc_call(&stack->rpc_queue, msg); + return; +-- +2.27.0 + diff --git a/0099-fix-func-separate_str_to_array-overflow-problem.patch b/0099-fix-func-separate_str_to_array-overflow-problem.patch new file mode 100644 index 0000000..a4d790f --- /dev/null +++ b/0099-fix-func-separate_str_to_array-overflow-problem.patch @@ -0,0 +1,32 @@ +From e4eeed95dcbb47b3413e51df6c82e85a735aa31c Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Mon, 25 Dec 2023 09:31:44 +0000 +Subject: [PATCH] fix func separate_str_to_array overflow problem + +Signed-off-by: yinbin6 +--- + src/common/gazelle_parse_config.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/common/gazelle_parse_config.c b/src/common/gazelle_parse_config.c +index 77d0b82..82be52c 100644 +--- a/src/common/gazelle_parse_config.c ++++ b/src/common/gazelle_parse_config.c +@@ -78,11 +78,11 @@ int32_t separate_str_to_array(char *args, uint32_t *array, int32_t array_size, i + min = idx; + } + for (idx = min; idx <= max; idx++) { ++ if (count > array_size) { ++ return -1; ++ } + array[count] = idx; + count++; +- if (count > array_size) { +- return -1; +- } + } + min = array_size; + } else { +-- +2.27.0 + diff --git a/0100-fix-func-separate_str_to_array-overflow-problem.patch b/0100-fix-func-separate_str_to_array-overflow-problem.patch new file mode 100644 index 0000000..8f3b2a5 --- /dev/null +++ b/0100-fix-func-separate_str_to_array-overflow-problem.patch @@ -0,0 +1,28 @@ +From 89abb6f4e231cf378b1e7f7415cfa196fdf7b3da Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Mon, 25 Dec 2023 10:25:42 +0000 +Subject: [PATCH] fix func separate_str_to_array overflow problem + +Signed-off-by: yinbin6 +--- + src/common/gazelle_parse_config.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/common/gazelle_parse_config.c b/src/common/gazelle_parse_config.c +index 82be52c..9772af9 100644 +--- a/src/common/gazelle_parse_config.c ++++ b/src/common/gazelle_parse_config.c +@@ -79,8 +79,8 @@ int32_t separate_str_to_array(char *args, uint32_t *array, int32_t array_size, i + } + for (idx = min; idx <= max; idx++) { + if (count > array_size) { +- return -1; +- } ++ return -1; ++ } + array[count] = idx; + count++; + } +-- +2.27.0 + diff --git a/0101-fix-func-separate_str_to_array-overflow-problem.patch b/0101-fix-func-separate_str_to_array-overflow-problem.patch new file mode 100644 index 0000000..c0e7eb4 --- /dev/null +++ b/0101-fix-func-separate_str_to_array-overflow-problem.patch @@ -0,0 +1,26 @@ +From 58248cb2bae3d2c50f65b3ade360fc14716a0ce7 Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Mon, 25 Dec 2023 11:06:18 +0000 +Subject: [PATCH] fix func separate_str_to_array overflow problem + +Signed-off-by: yinbin6 +--- + src/common/gazelle_parse_config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/common/gazelle_parse_config.c b/src/common/gazelle_parse_config.c +index 9772af9..16efdc8 100644 +--- a/src/common/gazelle_parse_config.c ++++ b/src/common/gazelle_parse_config.c +@@ -78,7 +78,7 @@ int32_t separate_str_to_array(char *args, uint32_t *array, int32_t array_size, i + min = idx; + } + for (idx = min; idx <= max; idx++) { +- if (count > array_size) { ++ if (count >= array_size) { + return -1; + } + array[count] = idx; +-- +2.27.0 + diff --git a/0102-fix-func-separate_str_to_array-overflow-problem.patch b/0102-fix-func-separate_str_to_array-overflow-problem.patch new file mode 100644 index 0000000..4266ac5 --- /dev/null +++ b/0102-fix-func-separate_str_to_array-overflow-problem.patch @@ -0,0 +1,26 @@ +From fafd5c387910da2f81f38c320b3da01ffd97c6c2 Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Mon, 25 Dec 2023 13:01:39 +0000 +Subject: [PATCH] fix func separate_str_to_array overflow problem + +Signed-off-by: yinbin6 +--- + src/common/gazelle_parse_config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/common/gazelle_parse_config.c b/src/common/gazelle_parse_config.c +index 16efdc8..1adce78 100644 +--- a/src/common/gazelle_parse_config.c ++++ b/src/common/gazelle_parse_config.c +@@ -33,7 +33,7 @@ + + int32_t separate_str_to_array(char *args, uint32_t *array, int32_t array_size, int32_t max_value) + { +- uint32_t count = 0; ++ int32_t count = 0; + char *end = NULL; + int32_t min, max; + int32_t idx; +-- +2.27.0 + diff --git a/0103-fix-func-stack_setup_thread-array-doesn-t-init.patch b/0103-fix-func-stack_setup_thread-array-doesn-t-init.patch new file mode 100644 index 0000000..5015c7a --- /dev/null +++ b/0103-fix-func-stack_setup_thread-array-doesn-t-init.patch @@ -0,0 +1,25 @@ +From 9ed5bee888ab4936372a81919d894d8fd291e7c1 Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Tue, 26 Dec 2023 22:49:03 +0800 +Subject: [PATCH] fix func stack_setup_thread array doesn't init + +--- + src/lstack/core/lstack_protocol_stack.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 829313f..0aff1b4 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -648,7 +648,7 @@ int32_t stack_setup_thread(void) + int32_t ret; + char name[PATH_MAX]; + int queue_num = get_global_cfg_params()->num_queue; +- struct thread_params *t_params[queue_num]; ++ struct thread_params *t_params[queue_num] = {0}; + int process_index = get_global_cfg_params()->process_idx; + + for (uint32_t i = 0; i < queue_num; i++) { +-- +2.27.0 + diff --git a/0104-fix-stack_setup_thread-array-range.patch b/0104-fix-stack_setup_thread-array-range.patch new file mode 100644 index 0000000..57b54ed --- /dev/null +++ b/0104-fix-stack_setup_thread-array-range.patch @@ -0,0 +1,21 @@ +From f6df059cf18aa0019c5bdea8947a5b4a53c02bde Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Wed, 27 Dec 2023 09:58:30 +0800 +Subject: [PATCH] fix stack_setup_thread array range + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 0aff1b4..b5d4ea3 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -648,7 +648,7 @@ int32_t stack_setup_thread(void) + int32_t ret; + char name[PATH_MAX]; + int queue_num = get_global_cfg_params()->num_queue; +- struct thread_params *t_params[queue_num] = {0}; ++ struct thread_params *t_params[PROTOCOL_STACK_MAX] = {NULL}; + int process_index = get_global_cfg_params()->process_idx; + + for (uint32_t i = 0; i < queue_num; i++) { +-- +2.27.0 + diff --git a/0105-fix-func-separate_str_to_array-overflow-problem.patch b/0105-fix-func-separate_str_to_array-overflow-problem.patch new file mode 100644 index 0000000..69a3de4 --- /dev/null +++ b/0105-fix-func-separate_str_to_array-overflow-problem.patch @@ -0,0 +1,80 @@ +From c6de43f7e7cb866f8d5ddd453c73783d5daafca0 Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Wed, 27 Dec 2023 12:22:06 +0800 +Subject: [PATCH] fix func separate_str_to_array overflow problem + +--- + src/lstack/core/lstack_protocol_stack.c | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index b5d4ea3..f3d2452 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -651,44 +651,57 @@ int32_t stack_setup_thread(void) + struct thread_params *t_params[PROTOCOL_STACK_MAX] = {NULL}; + int process_index = get_global_cfg_params()->process_idx; + ++ for (uint32_t i = 0; i < queue_num; ++i) { ++ t_params[i] = malloc(sizeof(struct thread_params)); ++ if (t_params[i] == NULL) { ++ goto OUT; ++ } ++ } ++ + for (uint32_t i = 0; i < queue_num; i++) { + if (get_global_cfg_params()->seperate_send_recv) { + if (i % 2 == 0) { + ret = sprintf_s(name, sizeof(name), "%s_%d_%d", LSTACK_RECV_THREAD_NAME, process_index, i / 2); + if (ret < 0) { +- return -1; ++ goto OUT; + } + } else { + ret = sprintf_s(name, sizeof(name), "%s_%d_%d", LSTACK_SEND_THREAD_NAME, process_index, i / 2); + if (ret < 0) { +- return -1; ++ goto OUT; + } + } + } else { + ret = sprintf_s(name, sizeof(name), "%s", LSTACK_THREAD_NAME); + if (ret < 0) { +- return -1; ++ goto OUT; + } + } + +- t_params[i] = malloc(sizeof(struct thread_params)); + t_params[i]->idx = i; + t_params[i]->queue_id = process_index * queue_num + i; + + ret = create_thread((void *)t_params[i], name, gazelle_stack_thread); + if (ret != 0) { +- return ret; ++ goto OUT; + } + } + + /* 2: wait stack thread and kernel_event thread init finish */ + wait_sem_value(&g_stack_group.sem_stack_setup, queue_num * 2); + if (g_stack_group.stack_setup_fail) { +- return -1; ++ goto OUT; + } + g_stack_group.stack_num = queue_num; + + return 0; ++OUT: ++ for (int32_t i = 0; i < queue_num; ++i) { ++ if (t_params[i] != NULL) { ++ free(t_params[i]); ++ } ++ } ++ return -1; + } + + void stack_arp(struct rpc_msg *msg) +-- +2.27.0 + diff --git a/0106-fix-dpdk_alloc_pktmbuf-time-consuming.patch b/0106-fix-dpdk_alloc_pktmbuf-time-consuming.patch new file mode 100644 index 0000000..cc41030 --- /dev/null +++ b/0106-fix-dpdk_alloc_pktmbuf-time-consuming.patch @@ -0,0 +1,32 @@ +From d40a2e46403547fc8d12ee1dacc6484eca1fbbeb Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Fri, 5 Jan 2024 10:15:22 +0800 +Subject: [PATCH] fix dpdk_alloc_pktmbuf time-consuming + +--- + src/lstack/core/lstack_dpdk.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 729a84c..3182bb5 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -271,9 +271,14 @@ int32_t create_shared_ring(struct protocol_stack *stack) + + int32_t dpdk_alloc_pktmbuf(struct rte_mempool *pool, struct rte_mbuf **mbufs, uint32_t num) + { +- if (rte_mempool_avail_count(pool) < MBUFPOOL_RESERVE_NUM + num) { ++ /* ++ * don't use rte_mempool_avail_count, it traverse cpu local cache, ++ * when RTE_MAX_LCORE is too large, it's time-consuming ++ */ ++ if (rte_ring_count(pool->pool_data) < MBUFPOOL_RESERVE_NUM + num) { + return -ENOMEM; + } ++ + int32_t ret = rte_pktmbuf_alloc_bulk(pool, mbufs, num); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "rte_pktmbuf_alloc_bulk fail allocNum=%d, ret=%d, info:%s \n", +-- +2.33.0 + diff --git a/0107-ltran-optimize-config-file-error-message.patch b/0107-ltran-optimize-config-file-error-message.patch new file mode 100644 index 0000000..bc1572b --- /dev/null +++ b/0107-ltran-optimize-config-file-error-message.patch @@ -0,0 +1,46 @@ +From e46c71fda9678df02d7373a1bb987cbc3979f1f6 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Fri, 5 Jan 2024 18:07:42 +0800 +Subject: [PATCH] ltran: optimize config file error message + +--- + src/ltran/ltran_param.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/src/ltran/ltran_param.c b/src/ltran/ltran_param.c +index 11a4bc8..1eaace4 100644 +--- a/src/ltran/ltran_param.c ++++ b/src/ltran/ltran_param.c +@@ -664,8 +664,15 @@ struct param_parser g_param_parse_tbl[] = { + int32_t parse_config_file_args(const char *conf_file_path, struct ltran_config *ltran_config) + { + config_t config; +- config_init(&config); + int32_t ret; ++ char real_path[PATH_MAX]; ++ ++ if (realpath(conf_file_path, real_path) == NULL) { ++ syslog(LOG_ERR, "Err: Config file path %s error, please check conf file path.\n", conf_file_path); ++ return -1; ++ } ++ ++ config_init(&config); + + ret = memset_s(ltran_config, sizeof(struct ltran_config), 0, sizeof(struct ltran_config)); + if (ret != 0) { +@@ -673,10 +680,10 @@ int32_t parse_config_file_args(const char *conf_file_path, struct ltran_config * + syslog(LOG_ERR, "memset_s failed\n"); + return ret; + } +- ret = config_read_file(&config, conf_file_path); ++ ret = config_read_file(&config, real_path); + if (ret == 0) { ++ syslog(LOG_ERR, "Err: Read config file \"%s\" error: %s\n", real_path, config_error_text(&config)); + config_destroy(&config); +- syslog(LOG_ERR, "Err: Config file path %s error, please check conf file path.\n", conf_file_path); + return -GAZELLE_EPATH; + } + +-- +2.33.0 + diff --git a/0108-replace-with-gz_addr_t.patch b/0108-replace-with-gz_addr_t.patch new file mode 100644 index 0000000..b72791f --- /dev/null +++ b/0108-replace-with-gz_addr_t.patch @@ -0,0 +1,224 @@ +From fa28c2bf790466ab3a4cfc8fa39ed14764797e87 Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Tue, 2 Jan 2024 17:10:44 +0800 +Subject: [PATCH] replace with gz_addr_t + +--- + src/common/gazelle_opt.h | 5 +---- + src/lstack/core/lstack_control_plane.c | 6 +++--- + src/lstack/core/lstack_lwip.c | 3 +-- + src/lstack/netif/lstack_vdev.c | 16 +++++++++------- + src/ltran/ltran_forward.c | 10 +++++----- + src/ltran/ltran_stat.c | 4 ++-- + src/ltran/ltran_tcp_conn.c | 4 ++-- + src/ltran/ltran_tcp_sock.c | 4 ++-- + src/ltran/ltran_timer.c | 4 ++-- + 9 files changed, 27 insertions(+), 29 deletions(-) + +diff --git a/src/common/gazelle_opt.h b/src/common/gazelle_opt.h +index bb540f4..36915c6 100644 +--- a/src/common/gazelle_opt.h ++++ b/src/common/gazelle_opt.h +@@ -27,6 +27,7 @@ + #define KERNEL_EPOLL_MAX 512 + + #define ETHER_ADDR_LEN 6 ++#define IPV6_ADDR_LEN 16 + + #define DEFAULT_RING_SIZE (512) + #define DEFAULT_RING_MASK (511) +@@ -52,10 +53,6 @@ + #define STACK_THREAD_DEFAULT 4 + #define STACK_NIC_READ_DEFAULT 128 + +-/* same as define in lwip/ip_addr.h */ +-#define GZ_ADDR_TYPE_V4 0 +-#define GZ_ADDR_TYPE_V6 6 +- + #define MTU_DEFAULT_DATA_LEN 1460 + #define VLAN_HEAD_LEN 4 + #define IPV6_EXTRA_HEAD_LEN 20 +diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c +index 668ff80..2d629c8 100644 +--- a/src/lstack/core/lstack_control_plane.c ++++ b/src/lstack/core/lstack_control_plane.c +@@ -361,12 +361,12 @@ static int32_t reg_conn(enum tcp_list_state table_state, enum reg_ring_type reg_ + continue; + } + qtuple.protocol = 0; +- qtuple.src_ip = conn->conn_list[i].lip.u_addr.ip4.addr; ++ qtuple.src_ip = conn->conn_list[i].lip; + qtuple.src_port = lwip_htons(conn->conn_list[i].l_port); +- qtuple.dst_ip = conn->conn_list[i].rip.u_addr.ip4.addr; ++ qtuple.dst_ip = conn->conn_list[i].rip; + qtuple.dst_port = lwip_htons(conn->conn_list[i].r_port); + +- if ((table_state == LISTEN_LIST) && (!match_host_addr(qtuple.src_ip))) { ++ if ((table_state == LISTEN_LIST) && (!match_host_addr(qtuple.src_ip.u_addr.ip4.addr))) { + continue; + } + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 4953f3d..87ec1f5 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -446,8 +446,7 @@ static inline ssize_t app_buff_write(struct lwip_sock *sock, void *buf, size_t l + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)addr; + for (int i = 0; i < write_num; i++) { +- memcpy_s(pbufs[i]->addr.u_addr.ip6.addr, sizeof(pbufs[i]->addr.u_addr.ip6.addr), +- saddr->sin6_addr.s6_addr, sizeof(saddr->sin6_addr.s6_addr)); ++ memcpy_s(pbufs[i]->addr.u_addr.ip6.addr, IPV6_ADDR_LEN, saddr->sin6_addr.s6_addr, IPV6_ADDR_LEN); + pbufs[i]->port = lwip_ntohs((saddr)->sin6_port); + IP_SET_TYPE(&pbufs[i]->addr, IPADDR_TYPE_V6); + } +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index ccf664a..9a79dc3 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -185,10 +185,12 @@ int32_t vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple) + delete_user_process_port(qtuple->src_port, PORT_CONNECT); + uint16_t queue_id = get_protocol_stack()->queue_id; + if (queue_id != 0) { +- transfer_delete_rule_info_to_process0(qtuple->dst_ip, qtuple->src_port, qtuple->dst_port); ++ transfer_delete_rule_info_to_process0(qtuple->dst_ip.u_addr.ip4.addr, ++ qtuple->src_port, qtuple->dst_port); + } + } else { +- transfer_delete_rule_info_to_process0(qtuple->dst_ip, qtuple->src_port, qtuple->dst_port); ++ transfer_delete_rule_info_to_process0(qtuple->dst_ip.u_addr.ip4.addr, ++ qtuple->src_port, qtuple->dst_port); + } + } + +@@ -197,12 +199,12 @@ int32_t vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple) + if (get_global_cfg_params()->is_primary) { + add_user_process_port(qtuple->src_port, get_global_cfg_params()->process_idx, PORT_CONNECT); + if (queue_id != 0) { +- transfer_create_rule_info_to_process0(queue_id, qtuple->src_ip, qtuple->dst_ip, +- qtuple->src_port, qtuple->dst_port); ++ transfer_create_rule_info_to_process0(queue_id, qtuple->src_ip.u_addr.ip4.addr, ++ qtuple->dst_ip.u_addr.ip4.addr, qtuple->src_port, qtuple->dst_port); + } + } else { +- transfer_create_rule_info_to_process0(queue_id, qtuple->src_ip, qtuple->dst_ip, +- qtuple->src_port, qtuple->dst_port); ++ transfer_create_rule_info_to_process0(queue_id, qtuple->src_ip.u_addr.ip4.addr, ++ qtuple->dst_ip.u_addr.ip4.addr, qtuple->src_port, qtuple->dst_port); + } + } + +@@ -228,7 +230,7 @@ int32_t vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple) + struct protocol_stack *stack = get_protocol_stack(); + + if (type == REG_RING_TCP_LISTEN || type == REG_RING_TCP_LISTEN_CLOSE) { +- if (!match_host_addr(qtuple->src_ip)) { ++ if (!match_host_addr(qtuple->src_ip.u_addr.ip4.addr)) { + LSTACK_LOG(INFO, LSTACK, "lstack ip not match in conf.\n"); + return 0; + } +diff --git a/src/ltran/ltran_forward.c b/src/ltran/ltran_forward.c +index a6f2d71..ee379b5 100644 +--- a/src/ltran/ltran_forward.c ++++ b/src/ltran/ltran_forward.c +@@ -246,8 +246,8 @@ static __rte_always_inline int32_t tcp_handle(struct rte_mbuf *m, const struct r + struct gazelle_tcp_sock *tcp_sock = NULL; + struct gazelle_quintuple quintuple; + +- quintuple.dst_ip = ipv4_hdr->dst_addr; +- quintuple.src_ip = ipv4_hdr->src_addr; ++ quintuple.dst_ip.u_addr.ip4.addr = ipv4_hdr->dst_addr; ++ quintuple.src_ip.u_addr.ip4.addr = ipv4_hdr->src_addr; + quintuple.dst_port = tcp_hdr->dst_port; + quintuple.src_port = tcp_hdr->src_port; + quintuple.protocol = 0; +@@ -260,7 +260,7 @@ static __rte_always_inline int32_t tcp_handle(struct rte_mbuf *m, const struct r + } + + tcp_sock = gazelle_sock_get_by_min_conn(gazelle_get_tcp_sock_htable(), +- quintuple.dst_ip, quintuple.dst_port); ++ quintuple.dst_ip.u_addr.ip4.addr, quintuple.dst_port); + if (unlikely(tcp_sock == NULL)) { + return GAZELLE_ERR; + } +@@ -494,7 +494,7 @@ static void tcp_hash_table_modify(struct gazelle_stack *stack, const struct reg_ + case REG_RING_TCP_LISTEN: + /* add sock htable */ + tcp_sock = gazelle_sock_add_by_ipporttid(gazelle_get_tcp_sock_htable(), +- transfer_qtuple.dst_ip, transfer_qtuple.dst_port, msg->tid); ++ transfer_qtuple.dst_ip.u_addr.ip4.addr, transfer_qtuple.dst_port, msg->tid); + if (tcp_sock == NULL) { + LTRAN_ERR("add tcp sock htable failed\n"); + break; +@@ -506,7 +506,7 @@ static void tcp_hash_table_modify(struct gazelle_stack *stack, const struct reg_ + case REG_RING_TCP_LISTEN_CLOSE: + /* del sock htable */ + gazelle_sock_del_by_ipporttid(gazelle_get_tcp_sock_htable(), +- transfer_qtuple.dst_ip, transfer_qtuple.dst_port, msg->tid); ++ transfer_qtuple.dst_ip.u_addr.ip4.addr, transfer_qtuple.dst_port, msg->tid); + break; + case REG_RING_TCP_CONNECT: + /* add conn htable */ +diff --git a/src/ltran/ltran_stat.c b/src/ltran/ltran_stat.c +index 2a0c03a..dfd5fc9 100644 +--- a/src/ltran/ltran_stat.c ++++ b/src/ltran/ltran_stat.c +@@ -267,8 +267,8 @@ void handle_resp_ltran_conn(int32_t fd) + if (index < GAZELLE_LSTACK_MAX_CONN) { + forward_table.conn_list[index].protocol = conn->quintuple.protocol; + forward_table.conn_list[index].tid = conn->tid; +- forward_table.conn_list[index].dst_ip = conn->quintuple.dst_ip; +- forward_table.conn_list[index].src_ip = conn->quintuple.src_ip; ++ forward_table.conn_list[index].dst_ip = conn->quintuple.dst_ip.u_addr.ip4.addr; ++ forward_table.conn_list[index].src_ip = conn->quintuple.src_ip.u_addr.ip4.addr; + forward_table.conn_list[index].dst_port = ntohs(conn->quintuple.dst_port); + forward_table.conn_list[index].src_port = ntohs(conn->quintuple.src_port); + } +diff --git a/src/ltran/ltran_tcp_conn.c b/src/ltran/ltran_tcp_conn.c +index e0ad562..026d22a 100644 +--- a/src/ltran/ltran_tcp_conn.c ++++ b/src/ltran/ltran_tcp_conn.c +@@ -78,8 +78,8 @@ struct gazelle_tcp_conn_hbucket *gazelle_conn_hbucket_get(struct gazelle_tcp_con + const struct gazelle_quintuple *quintuple) + { + uint32_t index; +- index = tuple_hash_fn(quintuple->src_ip, quintuple->src_port, quintuple->dst_ip, quintuple->dst_port) % +- GAZELLE_MAX_CONN_HTABLE_SIZE; ++ index = tuple_hash_fn(quintuple->src_ip.u_addr.ip4.addr, quintuple->src_port, quintuple->dst_ip.u_addr.ip4.addr, ++ quintuple->dst_port) % GAZELLE_MAX_CONN_HTABLE_SIZE; + return &conn_htable->array[index]; + } + +diff --git a/src/ltran/ltran_tcp_sock.c b/src/ltran/ltran_tcp_sock.c +index d6a0d17..940ded8 100644 +--- a/src/ltran/ltran_tcp_sock.c ++++ b/src/ltran/ltran_tcp_sock.c +@@ -104,8 +104,8 @@ static void recover_sock_info_from_conn(struct gazelle_tcp_sock *tcp_sock) + head = &conn_htable->array[i].chain; + + hlist_for_each_entry(conn, node, head, conn_node) { +- if ((conn->quintuple.dst_ip != tcp_sock->ip) || (conn->quintuple.dst_port != tcp_sock->port) || +- (conn->tid != tcp_sock->tid)) { ++ if ((conn->quintuple.dst_ip.u_addr.ip4.addr != tcp_sock->ip) || ++ (conn->quintuple.dst_port != tcp_sock->port) || (conn->tid != tcp_sock->tid)) { + continue; + } + count++; +diff --git a/src/ltran/ltran_timer.c b/src/ltran/ltran_timer.c +index 85ea324..96c622e 100644 +--- a/src/ltran/ltran_timer.c ++++ b/src/ltran/ltran_timer.c +@@ -103,8 +103,8 @@ void gazelle_detect_conn_logout(struct gazelle_tcp_conn_htable *conn_htable) + conn_htable->array[i].chain_size--; + LTRAN_DEBUG("delete the tcp conn htable: tid %u quintuple[%u %u %u %u %u]\n", + conn->tid, conn->quintuple.protocol, +- conn->quintuple.src_ip, (uint32_t)ntohs(conn->quintuple.src_port), +- conn->quintuple.dst_ip, (uint32_t)ntohs(conn->quintuple.dst_port)); ++ conn->quintuple.src_ip.u_addr.ip4.addr, (uint32_t)ntohs(conn->quintuple.src_port), ++ conn->quintuple.dst_ip.u_addr.ip4.addr, (uint32_t)ntohs(conn->quintuple.dst_port)); + rte_free(conn); + } + } +-- +2.33.0 + diff --git a/0109-match_host_addr-func-support-ipv6.patch b/0109-match_host_addr-func-support-ipv6.patch new file mode 100644 index 0000000..0e55ed2 --- /dev/null +++ b/0109-match_host_addr-func-support-ipv6.patch @@ -0,0 +1,103 @@ +From 2489b4b21632c9016f87c6fe963d27ef3e20951b Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Fri, 5 Jan 2024 14:32:48 +0800 +Subject: [PATCH] match_host_addr func support ipv6 + +--- + src/lstack/api/lstack_wrap.c | 12 +++++++++++- + src/lstack/core/lstack_cfg.c | 12 +++++++++--- + src/lstack/core/lstack_control_plane.c | 2 +- + src/lstack/include/lstack_cfg.h | 2 +- + src/lstack/netif/lstack_vdev.c | 2 +- + 5 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 56f89b2..3db62c7 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -217,7 +217,17 @@ static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen + return g_wrap_api->bind_fn(s, name, namelen); + } + +- if (match_host_addr(((struct sockaddr_in *)name)->sin_addr.s_addr)) { ++ ip_addr_t sock_addr = IPADDR_ANY_TYPE_INIT; ++ if (name->sa_family == AF_INET) { ++ sock_addr.type = IPADDR_TYPE_V4; ++ sock_addr.u_addr.ip4.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; ++ } else if (name->sa_family == AF_INET6) { ++ sock_addr.type = IPADDR_TYPE_V6; ++ memcpy_s(sock_addr.u_addr.ip6.addr, IPV6_ADDR_LEN, ++ ((struct sockaddr_in6 *)name)->sin6_addr.s6_addr, IPV6_ADDR_LEN); ++ } ++ ++ if (match_host_addr(&sock_addr)) { + /* maybe kni addr */ + if (posix_api->bind_fn(s, name, namelen) != 0) { + SET_CONN_TYPE_LIBOS(sock->conn); +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index d9c23fb..c1f5680 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -253,11 +253,17 @@ static int32_t parse_host_addr6(void) + return 0; + } + +-int32_t match_host_addr(uint32_t addr) ++int32_t match_host_addr(ip_addr_t *addr) + { + /* network byte order */ +- if (addr == g_config_params.host_addr.addr || addr == INADDR_ANY) { +- return 1; ++ if (IP_IS_V4_VAL(*addr)) { ++ if (ip4_addr_cmp(&addr->u_addr.ip4, &g_config_params.host_addr) || ip4_addr_isany_val(addr->u_addr.ip4)) { ++ return 1; ++ } ++ } else if (IP_IS_V6_VAL(*addr)) { ++ if (ip6_addr_cmp(&addr->u_addr.ip6, &g_config_params.host_addr6) || ip6_addr_isany_val(addr->u_addr.ip6)) { ++ return 1; ++ } + } + return 0; + } +diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c +index 2d629c8..a9a3814 100644 +--- a/src/lstack/core/lstack_control_plane.c ++++ b/src/lstack/core/lstack_control_plane.c +@@ -366,7 +366,7 @@ static int32_t reg_conn(enum tcp_list_state table_state, enum reg_ring_type reg_ + qtuple.dst_ip = conn->conn_list[i].rip; + qtuple.dst_port = lwip_htons(conn->conn_list[i].r_port); + +- if ((table_state == LISTEN_LIST) && (!match_host_addr(qtuple.src_ip.u_addr.ip4.addr))) { ++ if ((table_state == LISTEN_LIST) && (!match_host_addr((ip_addr_t *)&qtuple.src_ip))) { + continue; + } + +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index 82e96d8..c1074f8 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -133,7 +133,7 @@ int gazelle_param_init(int *argc, char **argv); + int gazelle_copy_param(const char *param, bool is_double, + int *argc, char argv[][PATH_MAX]); + +-int match_host_addr(uint32_t ipv4); ++int match_host_addr(ip_addr_t *addr); + int32_t init_stack_numa_cpuset(struct protocol_stack *stack); + + #endif /* GAZELLE_NET_CFG_H */ +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index 9a79dc3..c845f7a 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -230,7 +230,7 @@ int32_t vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple) + struct protocol_stack *stack = get_protocol_stack(); + + if (type == REG_RING_TCP_LISTEN || type == REG_RING_TCP_LISTEN_CLOSE) { +- if (!match_host_addr(qtuple->src_ip.u_addr.ip4.addr)) { ++ if (!match_host_addr((ip_addr_t *)&qtuple->src_ip)) { + LSTACK_LOG(INFO, LSTACK, "lstack ip not match in conf.\n"); + return 0; + } +-- +2.33.0 + diff --git a/0110-add-example-keep-alive-interval-para.patch b/0110-add-example-keep-alive-interval-para.patch new file mode 100644 index 0000000..c97ee42 --- /dev/null +++ b/0110-add-example-keep-alive-interval-para.patch @@ -0,0 +1,27 @@ +From f2770a0dd75007d152bdb346e16009227a6d55fa Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Thu, 4 Jan 2024 16:08:02 +0800 +Subject: [PATCH] add example keep-alive interval para + +--- + src/ltran/ltran_dfx.c | 4 ++-- + 8 files changed, 47 insertions(+), 8 deletions(-) + +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 08c9da3..5e22e20 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -1002,8 +1002,8 @@ static void gazelle_keepalive_string(char* str, int buff_len, struct gazelle_sta + if (conn_info->keepalive == 0) { + return; + } +- int ret = sprintf_s(str, buff_len, "(%u,%u,%u)", conn_info->keep_idle, conn_info->keep_intvl, +- conn_info->keep_cnt); ++ int ret = sprintf_s(str, buff_len, "(%u,%u,%u)", (conn_info->keep_idle) / 1000, ++ (conn_info->keep_intvl) / 1000, conn_info->keep_cnt); + if (ret < 0) { + printf("gazelle_keepalive_string sprintf_s fail ret=%d\n", ret); + return; +-- +2.33.0 + diff --git a/0111-update-src-common-dpdk_common.c.patch b/0111-update-src-common-dpdk_common.c.patch new file mode 100644 index 0000000..a7aa72c --- /dev/null +++ b/0111-update-src-common-dpdk_common.c.patch @@ -0,0 +1,68 @@ +From c6a7e8224dd9faff9120be8814638fe939570908 Mon Sep 17 00:00:00 2001 +From: Caohongtao +Date: Thu, 4 Jan 2024 09:34:04 +0000 +Subject: [PATCH] update src/common/dpdk_common.c. + +Signed-off-by: Caohongtao +--- + src/common/dpdk_common.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/common/dpdk_common.c b/src/common/dpdk_common.c +index 50f0bf0..62278c2 100644 +--- a/src/common/dpdk_common.c ++++ b/src/common/dpdk_common.c +@@ -65,13 +65,13 @@ static int32_t kni_config_network_interface(uint16_t port_id, uint8_t if_up) + g_bond_dev_started = true; + } + } else { +- COMMON_INFO("trying to start a started dev. \n"); ++ COMMON_INFO("Trying to start a started dev. \n"); + } + } else { /* Configure network interface down */ + if (g_kni_started) { + g_kni_started = false; + } else { +- COMMON_INFO("trying to stop a stopped dev. \n"); ++ COMMON_INFO("Trying to stop a stopped dev. \n"); + } + } + +@@ -154,7 +154,7 @@ void eth_params_checksum(struct rte_eth_conf *conf, struct rte_eth_dev_info *dev + conf->rxmode.offloads = rx_ol; + conf->txmode.offloads = tx_ol; + +- COMMON_INFO("set checksum offloads\n"); ++ COMMON_INFO("Set checksum offloads\n"); + } + + int32_t dpdk_kni_init(uint16_t port, struct rte_mempool *pool) +@@ -179,14 +179,14 @@ int32_t dpdk_kni_init(uint16_t port, struct rte_mempool *pool) + + ret = snprintf_s(conf.name, RTE_KNI_NAMESIZE, RTE_KNI_NAMESIZE - 1, "%s", GAZELLE_KNI_NAME); + if (ret < 0) { +- COMMON_ERR("snprintf_s failed. ret=%d\n", ret); ++ COMMON_ERR("Snprintf_s failed. ret=%d\n", ret); + return -1; + } + conf.mbuf_size = GAZELLE_MAX_PKT_SZ; + conf.group_id = port; + + if (rte_eth_dev_info_get(port, &dev_info) != 0) { +- COMMON_ERR("Fail rte_eth_dev_info_get\n"); ++ COMMON_ERR("Failed rte_eth_dev_info_get\n"); + return -1; + } + +@@ -204,7 +204,7 @@ int32_t dpdk_kni_init(uint16_t port, struct rte_mempool *pool) + ops.port_id = port; + g_pkni = rte_kni_alloc(pool, &conf, &ops); + if (g_pkni == NULL) { +- COMMON_ERR("Fail to create kni for port: %hu \n", port); ++ COMMON_ERR("Failed to create kni for port: %hu \n", port); + return -1; + } + return 0; +-- +2.33.0 + diff --git a/0112-listen_shadow-support-ipv6.patch b/0112-listen_shadow-support-ipv6.patch new file mode 100644 index 0000000..35949ab --- /dev/null +++ b/0112-listen_shadow-support-ipv6.patch @@ -0,0 +1,51 @@ +From 0fddaa74aa71ec25ee9cb1db141dd8a778e6e76d Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Mon, 8 Jan 2024 15:08:24 +0800 +Subject: [PATCH] listen_shadow support ipv6 + +--- + src/lstack/core/lstack_protocol_stack.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index f849bcd..e7b541e 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -1128,9 +1128,15 @@ int32_t stack_single_listen(int32_t fd, int32_t backlog) + /* listen sync to all protocol stack thread, so that any protocol stack thread can build connect */ + int32_t stack_broadcast_listen(int32_t fd, int32_t backlog) + { ++ typedef union sockaddr_union { ++ struct sockaddr sa; ++ struct sockaddr_in in; ++ struct sockaddr_in6 in6; ++ } sockaddr_t; ++ + struct protocol_stack *cur_stack = get_protocol_stack_by_fd(fd); + struct protocol_stack *stack = NULL; +- struct sockaddr addr; ++ sockaddr_t addr; + socklen_t addr_len = sizeof(addr); + int32_t ret, clone_fd; + +@@ -1140,7 +1146,7 @@ int32_t stack_broadcast_listen(int32_t fd, int32_t backlog) + GAZELLE_RETURN(EINVAL); + } + +- ret = rpc_call_getsockname(fd, &addr, &addr_len); ++ ret = rpc_call_getsockname(fd, (struct sockaddr *)&addr, &addr_len); + if (ret != 0) { + return ret; + } +@@ -1154,7 +1160,7 @@ int32_t stack_broadcast_listen(int32_t fd, int32_t backlog) + continue; + } + if (stack != cur_stack) { +- clone_fd = rpc_call_shadow_fd(stack, fd, &addr, sizeof(addr)); ++ clone_fd = rpc_call_shadow_fd(stack, fd, (struct sockaddr *)&addr, addr_len); + if (clone_fd < 0) { + stack_broadcast_close(fd); + return clone_fd; +-- +2.33.0 + diff --git a/0113-lstack_dpdk-limit-mbuf-max-num.patch b/0113-lstack_dpdk-limit-mbuf-max-num.patch new file mode 100644 index 0000000..6ced2f7 --- /dev/null +++ b/0113-lstack_dpdk-limit-mbuf-max-num.patch @@ -0,0 +1,78 @@ +From aa0bd688a6dae115e136771fda747c9428e65561 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Tue, 2 Jan 2024 09:32:00 +0800 +Subject: [PATCH] lstack_dpdk: limit mbuf max num + +--- + src/lstack/core/lstack_dpdk.c | 5 +++++ + src/lstack/include/lstack_dpdk.h | 18 ++++++++---------- + src/ltran/main.c | 2 +- + 3 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 729a84c..580dd1d 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -155,6 +155,11 @@ struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_mbuf, + LSTACK_LOG(ERR, LSTACK, "snprintf_s fail ret=%d \n", ret); + return NULL; + } ++ /* limit mbuf max num based on the dpdk capability */ ++ if (nb_mbuf > MBUF_MAX_NUM) { ++ LSTACK_LOG(ERR, LSTACK, "out of the dpdk mbuf quantity range\n"); ++ return NULL; ++ } + + /* time stamp before pbuf_custom as priv_data */ + uint16_t private_size = RTE_ALIGN(sizeof(struct mbuf_private), RTE_CACHE_LINE_SIZE); +diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h +index 4a160e0..2a44c6e 100644 +--- a/src/lstack/include/lstack_dpdk.h ++++ b/src/lstack/include/lstack_dpdk.h +@@ -17,22 +17,20 @@ + #include "gazelle_opt.h" + #include "gazelle_dfx_msg.h" + +-#define RXTX_CACHE_SZ (VDEV_RX_QUEUE_SZ) +-#define KNI_NB_MBUF (DEFAULT_RING_SIZE << 4) ++#define RXTX_CACHE_SZ (VDEV_RX_QUEUE_SZ) + +-#define RESERVE_NIC_RECV (1024) ++#define KNI_NB_MBUF (DEFAULT_RING_SIZE << 4) + +-#define MBUF_HEADER_LEN 64 +- +-#define MAX_PACKET_SZ 2048 ++#define MAX_PACKET_SZ 2048 + + #define RING_SIZE(x) ((x) - 1) + +-#define MBUF_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM) ++#define MBUF_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM) + +-#define MAX_CORE_NUM 256 +-#define CALL_MSG_RING_SIZE (unsigned long long)32 +-#define CALL_CACHE_SZ 0 ++/* DPDK limit ring head-tail distance in rte_ring_init. ++ * Max value is RTE_RING_SZ_MASK / HTD_MAX_DEF, RTE_RING_SZ_MASK is 0x7fffffff, HTD_MAX_DEF is 8. ++ */ ++#define MBUF_MAX_NUM 0xfffffff + + int thread_affinity_default(void); + int thread_affinity_init(int cpu_id); +diff --git a/src/ltran/main.c b/src/ltran/main.c +index 87f1e14..c2598a7 100644 +--- a/src/ltran/main.c ++++ b/src/ltran/main.c +@@ -55,7 +55,7 @@ static void print_stack(void) + + static void sig_default_handler(int32_t sig) + { +- LTRAN_ERR("ltran dumped,caught signal:%d.\n", sig); ++ LTRAN_ERR("ltran dumped, caught signal: %d.\n", sig); + print_stack(); + dpdk_kni_release(); + int ret = 0; +-- +2.33.0 + diff --git a/0114-gazellectl-add-tcp_input-empty-ack-cnt.patch b/0114-gazellectl-add-tcp_input-empty-ack-cnt.patch new file mode 100644 index 0000000..8485e02 --- /dev/null +++ b/0114-gazellectl-add-tcp_input-empty-ack-cnt.patch @@ -0,0 +1,66 @@ +From 295ad7d27233404457488089453a51d39e4d8038 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 8 Jan 2024 09:12:59 +0800 +Subject: [PATCH] gazellectl: add tcp_input empty ack cnt + +--- + src/common/gazelle_dfx_msg.h | 1 + + src/ltran/ltran_dfx.c | 29 +++++++++++++++-------------- + 2 files changed, 16 insertions(+), 14 deletions(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 478c440..d58a072 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -143,6 +143,7 @@ struct gazelle_stat_lstack_snmp { + uint32_t tcp_out_of_seq; + uint32_t tcp_acceptmbox_full; + uint32_t tcp_listen_drops; ++ uint32_t tcp_in_empty_acks; + + /* UDP */ + uint32_t udp_in_datagrams; +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 08c9da3..5d4e74c 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -855,21 +855,22 @@ static void gazelle_print_lstack_stat_rate(void *buf, const struct gazelle_stat_ + + static void gazelle_print_lstack_tcp_stat(const struct gazelle_stat_lstack_snmp *snmp) + { +- printf("tcp_act_open: %u\n", snmp->tcp_act_open); +- printf("tcp_passive_open: %u\n", snmp->tcp_passive_open); +- printf("tcp_attempt_fail: %u\n", snmp->tcp_attempt_fail); +- printf("tcp_estab_rst: %u\n", snmp->tcp_estab_rst); +- printf("tcp_out_seg: %u\n", snmp->tcp_out_seg); +- printf("tcp_retran_seg: %u\n", snmp->tcp_retran_seg); +- printf("tcp_in_seg: %u\n", snmp->tcp_in_seg); +- printf("tcp_in_err: %u\n", snmp->tcp_in_err); +- printf("tcp_out_rst: %u\n", snmp->tcp_out_rst); +- printf("tcp_fin_ack_cnt: %u\n", snmp->tcp_fin_ack_cnt); +- printf("tcp_delay_ack_cnt: %u\n", snmp->tcp_delay_ack_cnt); +- printf("tcp_refused_cnt: %u\n", snmp->tcp_refused_cnt); +- printf("tcp_out_of_seq: %u\n", snmp->tcp_out_of_seq); ++ printf("tcp_act_open: %u\n", snmp->tcp_act_open); ++ printf("tcp_passive_open: %u\n", snmp->tcp_passive_open); ++ printf("tcp_attempt_fail: %u\n", snmp->tcp_attempt_fail); ++ printf("tcp_estab_rst: %u\n", snmp->tcp_estab_rst); ++ printf("tcp_out_seg: %u\n", snmp->tcp_out_seg); ++ printf("tcp_retran_seg: %u\n", snmp->tcp_retran_seg); ++ printf("tcp_in_seg: %u\n", snmp->tcp_in_seg); ++ printf("tcp_in_err: %u\n", snmp->tcp_in_err); ++ printf("tcp_out_rst: %u\n", snmp->tcp_out_rst); ++ printf("tcp_fin_ack_cnt: %u\n", snmp->tcp_fin_ack_cnt); ++ printf("tcp_delay_ack_cnt: %u\n", snmp->tcp_delay_ack_cnt); ++ printf("tcp_refused_cnt: %u\n", snmp->tcp_refused_cnt); ++ printf("tcp_out_of_seq: %u\n", snmp->tcp_out_of_seq); + printf("tcp_acceptmbox_full: %u\n", snmp->tcp_acceptmbox_full); +- printf("tcp_listen_drops: %u\n", snmp->tcp_listen_drops); ++ printf("tcp_listen_drops: %u\n", snmp->tcp_listen_drops); ++ printf("tcp_in_empty_acks: %u\n", snmp->tcp_in_empty_acks); + } + + static void gazelle_print_ltran_stat_lb_rate(void *buf, const struct gazelle_stat_msg_request *req_msg) +-- +2.33.0 + diff --git a/0115-add-socket-accept-fail-cnt.patch b/0115-add-socket-accept-fail-cnt.patch new file mode 100644 index 0000000..4be8bde --- /dev/null +++ b/0115-add-socket-accept-fail-cnt.patch @@ -0,0 +1,54 @@ +From 53457e3ab329eb944579ffe55ddc4435e0bca0a1 Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Wed, 10 Jan 2024 09:12:34 +0800 +Subject: [PATCH] add socket accept fail cnt + +--- + src/common/gazelle_dfx_msg.h | 1 + + src/lstack/core/lstack_protocol_stack.c | 2 ++ + src/ltran/ltran_dfx.c | 1 + + 3 files changed, 4 insertions(+) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 478c440..1d3249d 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -72,6 +72,7 @@ struct gazelle_stack_stat { + uint64_t tx_drop; + uint64_t tx; + uint64_t tx_prepare_fail; ++ uint64_t accept_fail; + }; + + struct gazelle_wakeup_stat { +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index f849bcd..0d845dd 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -792,9 +792,11 @@ void stack_accept(struct rpc_msg *msg) + { + int32_t fd = msg->args[MSG_ARG_0].i; + msg->result = -1; ++ struct protocol_stack *stack = get_protocol_stack(); + + int32_t accept_fd = lwip_accept4(fd, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].p, msg->args[MSG_ARG_3].i); + if (accept_fd < 0) { ++ stack->stats.accept_fail++; + LSTACK_LOG(ERR, LSTACK, "fd %d ret %d\n", fd, accept_fd); + return; + } +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 5e22e20..461912f 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -646,6 +646,7 @@ static void show_lstack_stats(struct gazelle_stack_dfx_data *lstack_stat) + printf("send_pkts_fail: %-13"PRIu64" ", lstack_stat->data.pkts.stack_stat.send_pkts_fail); + printf("mbuf_pool_freecnt: %-10"PRIu32" ", lstack_stat->data.pkts.mbufpool_avail_cnt); + printf("rpc_pool_freecnt: %-12"PRIu32" \n", lstack_stat->data.pkts.rpcpool_avail_cnt); ++ printf("accpet_fail: %-12"PRIu64" \n", lstack_stat->data.pkts.stack_stat.accept_fail); + } + + static void gazelle_print_lstack_stat_detail(struct gazelle_stack_dfx_data *lstack_stat, +-- +2.33.0 + diff --git a/0116-diff-lstack-and-ltran-dfx-sock.patch b/0116-diff-lstack-and-ltran-dfx-sock.patch new file mode 100644 index 0000000..5a7adaa --- /dev/null +++ b/0116-diff-lstack-and-ltran-dfx-sock.patch @@ -0,0 +1,137 @@ +From db89062f34f8bcccf80a82d6589e5f3b5bc63cfe Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Sat, 13 Jan 2024 17:03:07 +0800 +Subject: [PATCH] diff lstack and ltran dfx sock + +--- + src/common/gazelle_opt.h | 9 +++++++-- + src/lstack/core/lstack_cfg.c | 10 ++++++++-- + src/ltran/ltran_base.h | 3 --- + src/ltran/ltran_dfx.c | 8 ++++---- + src/ltran/ltran_monitor.c | 8 ++++---- + src/ltran/ltran_param.c | 4 ++-- + 6 files changed, 25 insertions(+), 17 deletions(-) + +diff --git a/src/common/gazelle_opt.h b/src/common/gazelle_opt.h +index 36915c6..1d1c5f5 100644 +--- a/src/common/gazelle_opt.h ++++ b/src/common/gazelle_opt.h +@@ -85,8 +85,13 @@ + + #define GAZELLE_MAX_STACK_ARRAY_SIZE GAZELLE_CLIENT_NUM + +-#define GAZELLE_REG_SOCK_PATHNAME "/var/run/gazelle/gazelle_client.sock" +-#define GAZELLE_REG_SOCK_FILENAME "gazelle_client.sock" ++#define LTRAN_REG_SOCK_PATHNAME "/var/run/gazelle/ltran_client.sock" ++#define LTRAN_REG_SOCK_FILENAME "ltran_client.sock" ++#define LTRAN_DFX_SOCK_PATHNAME "/var/run/gazelle/ltran_cmd.sock" ++#define LTRAN_DFX_SOCK_FILENAME "ltran_cmd.sock" ++#define LSTACK_DFX_SOCK_PATHNAME "/var/run/gazelle/lstack_cmd.sock" ++#define LSTACK_DFX_SOCK_FILENAME "lstack_cmd.sock" ++ + #define GAZELLE_SOCK_FILENAME_MAXLEN 128 + + #define GAZELLE_RUN_DIR "/var/run/gazelle/" +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index c1f5680..87df790 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -1043,8 +1043,14 @@ static int32_t parse_unix_prefix(void) + } + } + +- ret = strncat_s(g_config_params.unix_socket_filename, sizeof(g_config_params.unix_socket_filename), +- GAZELLE_REG_SOCK_FILENAME, strlen(GAZELLE_REG_SOCK_FILENAME) + 1); ++ if (g_config_params.use_ltran) { ++ ret = strncat_s(g_config_params.unix_socket_filename, sizeof(g_config_params.unix_socket_filename), ++ LTRAN_REG_SOCK_FILENAME, strlen(LTRAN_REG_SOCK_FILENAME) + 1); ++ } else { ++ ret = strncat_s(g_config_params.unix_socket_filename, sizeof(g_config_params.unix_socket_filename), ++ LSTACK_DFX_SOCK_FILENAME, strlen(LSTACK_DFX_SOCK_FILENAME) + 1); ++ } ++ + if (ret != EOK) { + return ret; + } +diff --git a/src/ltran/ltran_base.h b/src/ltran/ltran_base.h +index 6be9152..f174a40 100644 +--- a/src/ltran/ltran_base.h ++++ b/src/ltran/ltran_base.h +@@ -98,7 +98,4 @@ + + #define GAZELLE_INET_ADDRSTRLEN 16 + +-#define GAZELLE_DFX_SOCK_PATHNAME "/var/run/gazelle/gazelle_cmd.sock" +-#define GAZELLE_DFX_SOCK_FILENAME "gazelle_cmd.sock" +- + #endif /* ifndef __GAZELLE_BASE_H__ */ +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index a64c1d5..05234de 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -254,15 +254,15 @@ static int32_t dfx_connect_ltran(bool use_ltran, bool probe) + + addr.sun_family = AF_UNIX; + if (use_ltran) { +- ret = strncat_s(addr.sun_path, sizeof(addr.sun_path), GAZELLE_DFX_SOCK_FILENAME, +- strlen(GAZELLE_DFX_SOCK_FILENAME) + 1); ++ ret = strncat_s(addr.sun_path, sizeof(addr.sun_path), LTRAN_DFX_SOCK_FILENAME, ++ strlen(LTRAN_DFX_SOCK_FILENAME) + 1); + if (ret != EOK) { + printf("%s:%d strncat_s fail ret=%d\n", __FUNCTION__, __LINE__, ret); + goto END; + } + } else { +- ret = strncat_s(addr.sun_path, sizeof(addr.sun_path), GAZELLE_REG_SOCK_FILENAME, +- strlen(GAZELLE_REG_SOCK_FILENAME) + 1); ++ ret = strncat_s(addr.sun_path, sizeof(addr.sun_path), LSTACK_DFX_SOCK_FILENAME, ++ strlen(LSTACK_DFX_SOCK_FILENAME) + 1); + if (ret != EOK) { + printf("%s:%d strncat_s fail ret=%d\n", __FUNCTION__, __LINE__, ret); + goto END; +diff --git a/src/ltran/ltran_monitor.c b/src/ltran/ltran_monitor.c +index b2bcc07..ea31e84 100644 +--- a/src/ltran/ltran_monitor.c ++++ b/src/ltran/ltran_monitor.c +@@ -238,13 +238,13 @@ static void gazelle_ctl_destroy(void) + close(g_epoll_fd); + g_epoll_fd = -1; + +- ret = unlink(GAZELLE_DFX_SOCK_PATHNAME); ++ ret = unlink(LTRAN_DFX_SOCK_PATHNAME); + if (ret != 0) { +- LTRAN_WARN("unlink %s ERROR. errno: %d. ret=%d\n", GAZELLE_DFX_SOCK_PATHNAME, errno, ret); ++ LTRAN_WARN("unlink %s ERROR. errno: %d. ret=%d\n", LTRAN_DFX_SOCK_PATHNAME, errno, ret); + } +- ret = unlink(GAZELLE_REG_SOCK_PATHNAME); ++ ret = unlink(LTRAN_REG_SOCK_PATHNAME); + if (ret != 0) { +- LTRAN_WARN("unlink %s ERROR. errno: %d. ret=%d\n", GAZELLE_REG_SOCK_PATHNAME, errno, ret); ++ LTRAN_WARN("unlink %s ERROR. errno: %d. ret=%d\n", LTRAN_REG_SOCK_PATHNAME, errno, ret); + } + } + +diff --git a/src/ltran/ltran_param.c b/src/ltran/ltran_param.c +index 1eaace4..bd5a8e1 100644 +--- a/src/ltran/ltran_param.c ++++ b/src/ltran/ltran_param.c +@@ -598,14 +598,14 @@ static int32_t parse_unix_prefix(const config_t *config, const char *key, struct + } + + ret = strncat_s(ltran_config->unix_socket_filename, sizeof(ltran_config->unix_socket_filename), +- GAZELLE_REG_SOCK_FILENAME, strlen(GAZELLE_REG_SOCK_FILENAME) + 1); ++ LTRAN_REG_SOCK_FILENAME, strlen(LTRAN_REG_SOCK_FILENAME) + 1); + if (ret != EOK) { + gazelle_set_errno(GAZELLE_EINETATON); + return GAZELLE_ERR; + } + + ret = strncat_s(ltran_config->dfx_socket_filename, sizeof(ltran_config->dfx_socket_filename), +- GAZELLE_DFX_SOCK_FILENAME, strlen(GAZELLE_DFX_SOCK_FILENAME) + 1); ++ LTRAN_DFX_SOCK_FILENAME, strlen(LTRAN_DFX_SOCK_FILENAME) + 1); + if (ret != EOK) { + gazelle_set_errno(GAZELLE_EINETATON); + return GAZELLE_ERR; +-- +2.33.0 + diff --git a/0117-fix-host_addr6-can-be-assigned-a-multicast-address.patch b/0117-fix-host_addr6-can-be-assigned-a-multicast-address.patch new file mode 100644 index 0000000..a99e7c1 --- /dev/null +++ b/0117-fix-host_addr6-can-be-assigned-a-multicast-address.patch @@ -0,0 +1,29 @@ +From 7c8d80e76f93029437f9a52f04c9d02b0d55dd78 Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Tue, 16 Jan 2024 23:52:23 +0800 +Subject: [PATCH] fix host_addr6 can be assigned a multicast address + +--- + src/lstack/core/lstack_cfg.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 87df790..5e30e89 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -250,6 +250,12 @@ static int32_t parse_host_addr6(void) + if (ip6addr_aton(value, &g_config_params.host_addr6) == 0) { + return -EINVAL; + } ++ ++ if (ip6_addr_ismulticast(&g_config_params.host_addr6)) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: host_addr6 cannot be a multicast address."); ++ return -EINVAL; ++ } ++ + return 0; + } + +-- +2.33.0 + diff --git a/0118-udp-do-not-merge-data-into-last-pbuf.patch b/0118-udp-do-not-merge-data-into-last-pbuf.patch new file mode 100644 index 0000000..a3f557a --- /dev/null +++ b/0118-udp-do-not-merge-data-into-last-pbuf.patch @@ -0,0 +1,45 @@ +From b90801a943f140a62761158a058d1076212dccf3 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Thu, 18 Jan 2024 10:01:52 +0800 +Subject: [PATCH] udp: do not merge data into last pbuf + +--- + src/lstack/core/lstack_lwip.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 87ec1f5..6ebe589 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -542,14 +542,14 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + } + + struct protocol_stack *stack = sock->stack; +- if (!stack|| len == 0) { ++ if (!stack || len == 0) { + return 0; + } + + ssize_t send_len = 0; + + /* merge data into last pbuf */ +- if (sock->remain_len) { ++ if (!NETCONN_IS_UDP(sock) && sock->remain_len) { + send_len = merge_data_lastpbuf(sock, (char *)buf, len); + if (send_len >= len) { + send_len = len; +@@ -1045,6 +1045,11 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ); + } + gazelle_ring_read_over(sock->recv_ring); ++ ++ /* in udp, if pbuf remaining len less than copy_len, discard these packets */ ++ if (recvd > 0 && NETCONN_IS_UDP(sock)) { ++ break; ++ } + } + } + +-- +2.33.0 + diff --git a/0119-adpat-dpdk-23.11.patch b/0119-adpat-dpdk-23.11.patch new file mode 100644 index 0000000..07b81bd --- /dev/null +++ b/0119-adpat-dpdk-23.11.patch @@ -0,0 +1,969 @@ +From bbb97803a36a5de0bb6ca6ce0518a6ef0666a22b Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 15 Jan 2024 09:37:20 +0800 +Subject: [PATCH] adpat dpdk 23.11 + +--- + src/common/dpdk_common.c | 171 +++++++++++---------- + src/common/gazelle_parse_config.c | 1 + + src/lstack/Makefile | 50 +++--- + src/lstack/core/lstack_dpdk.c | 34 ++-- + src/lstack/core/lstack_init.c | 2 + + src/lstack/core/lstack_protocol_stack.c | 12 +- + src/lstack/include/lstack_ethdev.h | 8 + + src/lstack/include/lstack_protocol_stack.h | 1 - + src/lstack/netif/lstack_ethdev.c | 8 + + src/lstack/netif/lstack_vdev.c | 4 +- + src/ltran/CMakeLists.txt | 33 +++- + src/ltran/ltran_dfx.c | 20 +-- + src/ltran/ltran_ethdev.c | 29 +++- + src/ltran/ltran_forward.c | 14 ++ + src/ltran/ltran_stack.c | 1 + + src/ltran/ltran_timer.c | 1 + + src/ltran/main.c | 6 + + 17 files changed, 254 insertions(+), 141 deletions(-) + +diff --git a/src/common/dpdk_common.c b/src/common/dpdk_common.c +index 62278c2..c0c4f63 100644 +--- a/src/common/dpdk_common.c ++++ b/src/common/dpdk_common.c +@@ -10,18 +10,21 @@ + * See the Mulan PSL v2 for more details. + */ + +-#include ++#include + #include + #include + #include + #include + #include +-#include ++#include ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) ++#include ++#endif ++ ++#include + + #include "dpdk_common.h" + +-#define GAZELLE_KNI_IFACES_NUM 1 +-#define GAZELLE_KNI_READ_SIZE 32 + #define GAZELLE_MAX_PKT_SZ 2048 + + #ifdef LTRAN_COMPILE +@@ -34,6 +37,9 @@ + #define COMMON_INFO(fmt, ...) LSTACK_LOG(INFO, LSTACK, fmt, ##__VA_ARGS__) + #endif + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) ++#define GAZELLE_KNI_IFACES_NUM 1 ++#define GAZELLE_KNI_READ_SIZE 32 + struct rte_kni *g_pkni = NULL; + static volatile bool g_kni_started = false; + +@@ -79,84 +85,6 @@ static int32_t kni_config_network_interface(uint16_t port_id, uint8_t if_up) + return ret; + } + +-void eth_params_checksum(struct rte_eth_conf *conf, struct rte_eth_dev_info *dev_info) +-{ +- uint64_t rx_ol = 0; +- uint64_t tx_ol = 0; +- uint64_t rx_ol_capa = dev_info->rx_offload_capa; +- uint64_t tx_ol_capa = dev_info->tx_offload_capa; +- +- // rx ip +- if (rx_ol_capa & DEV_RX_OFFLOAD_IPV4_CKSUM) { +- rx_ol |= DEV_RX_OFFLOAD_IPV4_CKSUM; +- COMMON_INFO("DEV_RX_OFFLOAD_IPV4_CKSUM\n"); +- } +- +- // rx tcp +- if (rx_ol_capa & DEV_RX_OFFLOAD_TCP_CKSUM) { +- rx_ol |= DEV_RX_OFFLOAD_TCP_CKSUM; +- COMMON_INFO("DEV_RX_OFFLOAD_TCP_CKSUM\n"); +- } +- +- // rx udp +- if (rx_ol_capa & DEV_RX_OFFLOAD_UDP_CKSUM) { +- rx_ol |= DEV_RX_OFFLOAD_UDP_CKSUM; +- COMMON_INFO("DEV_RX_OFFLOAD_UDP_CKSUM\n"); +- } +- +- // rx vlan +- if (rx_ol_capa & DEV_RX_OFFLOAD_VLAN_STRIP) { +- rx_ol |= DEV_RX_OFFLOAD_VLAN_STRIP; +- COMMON_INFO("DEV_RX_OFFLOAD_VLAN_STRIP\n"); +- } +- +- // tx ip +- if (tx_ol_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) { +- tx_ol |= DEV_TX_OFFLOAD_IPV4_CKSUM; +- COMMON_INFO("DEV_TX_OFFLOAD_IPV4_CKSUM\n"); +- } +- +- // tx tcp +- if (tx_ol_capa & DEV_TX_OFFLOAD_TCP_CKSUM) { +- tx_ol |= DEV_TX_OFFLOAD_TCP_CKSUM; +- COMMON_INFO("DEV_TX_OFFLOAD_TCP_CKSUM\n"); +- } +- +- // tx udp +- if (tx_ol_capa & DEV_TX_OFFLOAD_UDP_CKSUM) { +- tx_ol |= DEV_TX_OFFLOAD_UDP_CKSUM; +- COMMON_INFO("DEV_TX_OFFLOAD_UDP_CKSUM\n"); +- } +- +- // tx tso +- if (tx_ol_capa & DEV_TX_OFFLOAD_TCP_TSO) { +- tx_ol |= (DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_MULTI_SEGS); +- COMMON_INFO("DEV_TX_OFFLOAD_TCP_TSO\n"); +- } +- +- // tx vlan +- if (tx_ol_capa & DEV_TX_OFFLOAD_VLAN_INSERT) { +- tx_ol |= DEV_TX_OFFLOAD_VLAN_INSERT; +- COMMON_INFO("DEV_TX_OFFLOAD_VLAN_INSERT\n"); +- } +- +- if (!(rx_ol & DEV_RX_OFFLOAD_UDP_CKSUM) || +- !(rx_ol & DEV_RX_OFFLOAD_TCP_CKSUM) || +- !(rx_ol & DEV_RX_OFFLOAD_IPV4_CKSUM)) { +- rx_ol = 0; +- } +- if (!(tx_ol & DEV_TX_OFFLOAD_UDP_CKSUM) || +- !(tx_ol & DEV_TX_OFFLOAD_TCP_CKSUM) || +- !(tx_ol & DEV_TX_OFFLOAD_IPV4_CKSUM)) { +- tx_ol = 0; +- } +- +- conf->rxmode.offloads = rx_ol; +- conf->txmode.offloads = tx_ol; +- +- COMMON_INFO("Set checksum offloads\n"); +-} +- + int32_t dpdk_kni_init(uint16_t port, struct rte_mempool *pool) + { + int32_t ret; +@@ -262,3 +190,82 @@ void kni_process_rx(uint16_t port) + } + } + } ++#endif ++ ++void eth_params_checksum(struct rte_eth_conf *conf, struct rte_eth_dev_info *dev_info) ++{ ++ uint64_t rx_ol = 0; ++ uint64_t tx_ol = 0; ++ uint64_t rx_ol_capa = dev_info->rx_offload_capa; ++ uint64_t tx_ol_capa = dev_info->tx_offload_capa; ++ ++ // rx ip ++ if (rx_ol_capa & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) { ++ rx_ol |= RTE_ETH_RX_OFFLOAD_IPV4_CKSUM; ++ COMMON_INFO("RTE_ETH_RX_OFFLOAD_IPV4_CKSUM\n"); ++ } ++ ++ // rx tcp ++ if (rx_ol_capa & RTE_ETH_RX_OFFLOAD_TCP_CKSUM) { ++ rx_ol |= RTE_ETH_RX_OFFLOAD_TCP_CKSUM; ++ COMMON_INFO("RTE_ETH_RX_OFFLOAD_TCP_CKSUM\n"); ++ } ++ ++ // rx udp ++ if (rx_ol_capa & RTE_ETH_RX_OFFLOAD_UDP_CKSUM) { ++ rx_ol |= RTE_ETH_RX_OFFLOAD_UDP_CKSUM; ++ COMMON_INFO("RTE_ETH_RX_OFFLOAD_UDP_CKSUM\n"); ++ } ++ ++ // rx vlan ++ if (rx_ol_capa & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) { ++ rx_ol |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP; ++ COMMON_INFO("RTE_ETH_RX_OFFLOAD_VLAN_STRIP\n"); ++ } ++ ++ // tx ip ++ if (tx_ol_capa & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { ++ tx_ol |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM; ++ COMMON_INFO("RTE_ETH_TX_OFFLOAD_IPV4_CKSUM\n"); ++ } ++ ++ // tx tcp ++ if (tx_ol_capa & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) { ++ tx_ol |= RTE_ETH_TX_OFFLOAD_TCP_CKSUM; ++ COMMON_INFO("RTE_ETH_TX_OFFLOAD_TCP_CKSUM\n"); ++ } ++ ++ // tx udp ++ if (tx_ol_capa & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) { ++ tx_ol |= RTE_ETH_TX_OFFLOAD_UDP_CKSUM; ++ COMMON_INFO("RTE_ETH_TX_OFFLOAD_UDP_CKSUM\n"); ++ } ++ ++ // tx tso ++ if (tx_ol_capa & RTE_ETH_TX_OFFLOAD_TCP_TSO) { ++ tx_ol |= (RTE_ETH_TX_OFFLOAD_TCP_TSO | RTE_ETH_TX_OFFLOAD_MULTI_SEGS); ++ COMMON_INFO("RTE_ETH_TX_OFFLOAD_TCP_TSO\n"); ++ } ++ ++ // tx vlan ++ if (tx_ol_capa & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) { ++ tx_ol |= RTE_ETH_TX_OFFLOAD_VLAN_INSERT; ++ COMMON_INFO("RTE_ETH_TX_OFFLOAD_VLAN_INSERT\n"); ++ } ++ ++ if (!(rx_ol & RTE_ETH_RX_OFFLOAD_UDP_CKSUM) || ++ !(rx_ol & RTE_ETH_RX_OFFLOAD_TCP_CKSUM) || ++ !(rx_ol & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM)) { ++ rx_ol = 0; ++ } ++ if (!(tx_ol & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) || ++ !(tx_ol & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) || ++ !(tx_ol & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM)) { ++ tx_ol = 0; ++ } ++ ++ conf->rxmode.offloads = rx_ol; ++ conf->txmode.offloads = tx_ol; ++ ++ COMMON_INFO("Set checksum offloads\n"); ++} +diff --git a/src/common/gazelle_parse_config.c b/src/common/gazelle_parse_config.c +index 1adce78..0553f0d 100644 +--- a/src/common/gazelle_parse_config.c ++++ b/src/common/gazelle_parse_config.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + +diff --git a/src/lstack/Makefile b/src/lstack/Makefile +index d585040..df1ddaa 100644 +--- a/src/lstack/Makefile ++++ b/src/lstack/Makefile +@@ -7,17 +7,17 @@ + # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + # PURPOSE. + # See the Mulan PSL v2 for more details. +- + LSTACK_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + ROOT_DIR := $(dir $(abspath $(LSTACK_DIR))) + + LWIP_INCLUDE_FILE ?= /usr/include/lwip + LIB_PATH ?= /usr/lib64 + +-ifeq ($(DPDK_VERSION_1911), 1) +- DPDK_INCLUDE_FILE ?= /usr/include/dpdk ++DPDK_VERSION := $(shell rpm -q --queryformat '%{VERSION}' dpdk) ++ifeq ($(DPDK_VERSION),21.11) ++ DPDK_INCLUDE_FILE := /usr/local/include + else +- DPDK_INCLUDE_FILE ?= /usr/local/include/ ++ DPDK_INCLUDE_FILE := /usr/include/dpdk + endif + + AR = ar +@@ -77,34 +77,36 @@ LIBRTE_LIB = $(LIB_PATH)/librte_pci.so \ + $(LIB_PATH)/librte_gro.so \ + $(LIB_PATH)/librte_ring.so \ + $(LIB_PATH)/librte_mbuf.so \ +- $(LIB_PATH)/librte_kni.so \ + $(LIB_PATH)/librte_kvargs.so \ + $(LIB_PATH)/librte_bus_vdev.so \ + $(LIB_PATH)/librte_net.so \ + $(LIB_PATH)/librte_ethdev.so \ +- $(LIB_PATH)/librte_pdump.so \ ++ $(LIB_PATH)/librte_pdump.so ++ ++ifeq ($(shell expr $(DPDK_VERSION) \< 23.11), 1) ++ LIBRTE_LIB += $(LIB_PATH)/librte_kni.so ++endif + +-ifeq ($(DPDK_VERSION_1911), 1) +- CFLAGS += -DDPDK_VERSION_1911=1 ++ifeq ($(DPDK_VERSION), 19.11) + LIBRTE_LIB += $(LIB_PATH)/librte_pmd_pcap.so \ +- $(LIB_PATH)/librte_pmd_bond.so \ +- $(LIB_PATH)/librte_pmd_hinic.so \ +- $(LIB_PATH)/librte_pmd_ixgbe.so \ +- $(LIB_PATH)/librte_pmd_virtio.so +- ifneq ($(ARCH), loongarch64) +- LIBRTE_LIB += $(LIB_PATH)/librte_pmd_i40e.so +- endif ++ $(LIB_PATH)/librte_pmd_bond.so \ ++ $(LIB_PATH)/librte_pmd_hinic.so \ ++ $(LIB_PATH)/librte_pmd_ixgbe.so \ ++ $(LIB_PATH)/librte_pmd_virtio.so ++ ifneq ($(ARCH), loongarch64) ++ LIBRTE_LIB += $(LIB_PATH)/librte_pmd_i40e.so ++ endif + else + LIBRTE_LIB += $(LIB_PATH)/librte_net_pcap.so \ +- $(LIB_PATH)/librte_net_bond.so \ +- $(LIB_PATH)/librte_net_hinic.so \ +- $(LIB_PATH)/librte_net_ixgbe.so \ +- $(LIB_PATH)/librte_net_virtio.so \ +- $(LIB_PATH)/librte_telemetry.so \ +- $(LIB_PATH)/librte_pcapng.so +- ifneq ($(ARCH), loongarch64) +- LIBRTE_LIB += $(LIB_PATH)/librte_net_i40e.so +- endif ++ $(LIB_PATH)/librte_net_bond.so \ ++ $(LIB_PATH)/librte_net_hinic.so \ ++ $(LIB_PATH)/librte_net_ixgbe.so \ ++ $(LIB_PATH)/librte_net_virtio.so \ ++ $(LIB_PATH)/librte_telemetry.so \ ++ $(LIB_PATH)/librte_pcapng.so ++ ifneq ($(ARCH), loongarch64) ++ LIBRTE_LIB += $(LIB_PATH)/librte_net_i40e.so ++ endif + endif + + DEP_LIBS = $(LWIP_LIB) $(LIBRTE_LIB) +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 630b043..7f1ceb8 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -27,7 +27,10 @@ + #include + #include + #include ++#include ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + #include ++#endif + #include + #include + #include +@@ -35,6 +38,7 @@ + #include + #include + #include ++ + #include + #include + #include +@@ -59,8 +63,10 @@ struct eth_params { + struct rte_eth_rxconf rx_conf; + struct rte_eth_txconf tx_conf; + }; ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + struct rte_kni; + static struct rte_bus *g_pci_bus = NULL; ++#endif + + #define RSS_HASH_KEY_LEN 40 + static uint8_t g_default_rss_key[] = { +@@ -368,9 +374,9 @@ static struct eth_params *alloc_eth_params(uint16_t port_id, uint16_t nb_queues) + eth_params->nb_queues = nb_queues; + eth_params->nb_rx_desc = get_global_cfg_params()->nic.rxqueue_size; + eth_params->nb_tx_desc = get_global_cfg_params()->nic.txqueue_size; +- eth_params->conf.link_speeds = ETH_LINK_SPEED_AUTONEG; +- eth_params->conf.txmode.mq_mode = ETH_MQ_TX_NONE; +- eth_params->conf.rxmode.mq_mode = ETH_MQ_RX_NONE; ++ eth_params->conf.link_speeds = RTE_ETH_LINK_SPEED_AUTONEG; ++ eth_params->conf.txmode.mq_mode = RTE_ETH_MQ_TX_NONE; ++ eth_params->conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE; + + return eth_params; + } +@@ -388,7 +394,7 @@ uint64_t get_eth_params_tx_ol(void) + static int eth_params_rss(struct rte_eth_conf *conf, struct rte_eth_dev_info *dev_info) + { + int rss_enable = 0; +- uint64_t def_rss_hf = ETH_RSS_TCP | ETH_RSS_UDP | ETH_RSS_IP; ++ uint64_t def_rss_hf = RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP | RTE_ETH_RSS_IP; + struct rte_eth_rss_conf rss_conf = { + g_default_rss_key, + RSS_HASH_KEY_LEN, +@@ -404,7 +410,7 @@ static int eth_params_rss(struct rte_eth_conf *conf, struct rte_eth_dev_info *de + if (rss_conf.rss_hf) { + rss_enable = 1; + conf->rx_adv_conf.rss_conf = rss_conf; +- conf->rxmode.mq_mode = ETH_MQ_RX_RSS; ++ conf->rxmode.mq_mode = RTE_ETH_MQ_RX_RSS; + + LSTACK_LOG(INFO, LSTACK, "set rss_hf: %lx\n", rss_conf.rss_hf); + } +@@ -427,8 +433,8 @@ static void rss_setup(const int port_id, const uint16_t nb_queues) + return; + } + +- reta_conf_size = dev_info.reta_size / RTE_RETA_GROUP_SIZE; +- if (dev_info.reta_size % RTE_RETA_GROUP_SIZE) { ++ reta_conf_size = dev_info.reta_size / RTE_ETH_RETA_GROUP_SIZE; ++ if (dev_info.reta_size % RTE_ETH_RETA_GROUP_SIZE) { + reta_conf_size += 1; + } + +@@ -438,8 +444,8 @@ static void rss_setup(const int port_id, const uint16_t nb_queues) + } + for (i = 0; i < dev_info.reta_size; i++) { + struct rte_eth_rss_reta_entry64 *one_reta_conf = +- &reta_conf[i / RTE_RETA_GROUP_SIZE]; +- one_reta_conf->reta[i % RTE_RETA_GROUP_SIZE] = i % nb_queues; ++ &reta_conf[i / RTE_ETH_RETA_GROUP_SIZE]; ++ one_reta_conf->reta[i % RTE_ETH_RETA_GROUP_SIZE] = i % nb_queues; + } + + for (i = 0; i < reta_conf_size; i++) { +@@ -518,7 +524,11 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + return -1; + } + ++#if RTE_VERSION >= RTE_VERSION_NUM(23, 11, 0, 0) ++ ret = rte_eth_bond_member_add(port_id, slave_port_id[i]); ++#else + ret = rte_eth_bond_slave_add(port_id, slave_port_id[i]); ++#endif + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk add slave port failed ret = %d\n", ret); + return -1; +@@ -671,6 +681,7 @@ int32_t dpdk_init_lstack_kni(void) + return 0; + } + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + void dpdk_skip_nic_init(void) + { + /* when lstack init nic again, ltran can't read pkts from nic. unregister pci_bus to avoid init nic in lstack */ +@@ -686,6 +697,7 @@ void dpdk_restore_pci(void) + rte_bus_register(g_pci_bus); + } + } ++#endif + + int32_t init_dpdk_ethdev(void) + { +@@ -849,7 +861,11 @@ void dpdk_nic_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id) + if (strcmp(dev_info.driver_name, "net_bonding") == 0) { + uint16_t slaves[RTE_MAX_ETHPORTS]; + int slave_count; ++#if RTE_VERSION >= RTE_VERSION_NUM(23, 11, 0, 0) ++ slave_count = rte_eth_bond_members_get(port_id, slaves, RTE_MAX_ETHPORTS); ++#else + slave_count = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS); ++#endif + if (slave_count <= 0) { + LSTACK_LOG(ERR, LSTACK, "rte_eth_bond_slaves_get failed.\n"); + return; +diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c +index fef2942..31fd91d 100644 +--- a/src/lstack/core/lstack_init.c ++++ b/src/lstack/core/lstack_init.c +@@ -116,7 +116,9 @@ void gazelle_exit(void) + stack_group_exit(); + } + if (!use_ltran()) { ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + dpdk_kni_release(); ++#endif + } + } + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 1fa7373..a24fc4c 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -13,8 +13,6 @@ + #include + #include + +-#include +- + #include + #include + #include +@@ -38,6 +36,10 @@ + #include "lstack_stack_stat.h" + #include "lstack_protocol_stack.h" + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) ++#include ++#endif ++ + #define KERNEL_EVENT_10us 10 + + static PER_THREAD struct protocol_stack *g_stack_p = NULL; +@@ -453,7 +455,9 @@ int stack_polling(uint32_t wakeup_tick) + int force_quit; + struct cfg_params *cfg = get_global_cfg_params(); + uint8_t use_ltran_flag = cfg->use_ltran; ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + bool kni_switch = cfg->kni_switch; ++#endif + bool use_sockmap = cfg->use_sockmap; + bool stack_mode_rtc = cfg->stack_mode_rtc; + uint32_t rpc_number = cfg->rpc_number; +@@ -486,6 +490,7 @@ int stack_polling(uint32_t wakeup_tick) + } + } + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + /* run to completion mode currently does not support kni */ + /* KNI requests are generally low-rate I/Os, + * so processing KNI requests only in the thread with queue_id No.0 is sufficient. */ +@@ -495,6 +500,7 @@ int stack_polling(uint32_t wakeup_tick) + kni_handle_rx(stack->port_id); + } + } ++#endif + return force_quit; + } + +@@ -950,7 +956,9 @@ void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack + return; + } + copy_mbuf(mbuf_copy, mbuf); ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + kni_handle_tx(mbuf_copy); ++#endif + return; + } + +diff --git a/src/lstack/include/lstack_ethdev.h b/src/lstack/include/lstack_ethdev.h +index 326bd1b..3252906 100644 +--- a/src/lstack/include/lstack_ethdev.h ++++ b/src/lstack/include/lstack_ethdev.h +@@ -13,6 +13,9 @@ + #ifndef __GAZELLE_ETHDEV_H__ + #define __GAZELLE_ETHDEV_H__ + ++#include ++#include ++ + #define INVAILD_PROCESS_IDX 255 + + enum port_type { +@@ -46,7 +49,12 @@ void eth_dev_recv(struct rte_mbuf *mbuf, struct protocol_stack *stack); + + int recv_pkts_from_other_process(int process_index, void* arg); + int32_t check_params_from_primary(void); ++ ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + void kni_handle_rx(uint16_t port_id); ++void kni_handle_tx(struct rte_mbuf *mbuf); ++#endif ++ + void delete_user_process_port(uint16_t dst_port, enum port_type type); + void add_user_process_port(uint16_t dst_port, uint8_t process_idx, enum port_type type); + void delete_flow_director(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index 8e2e807..c681547 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -181,5 +181,4 @@ void stack_recvlist_count(struct rpc_msg *msg); + void stack_exit_by_rpc(struct rpc_msg *msg); + + int stack_polling(uint32_t wakeup_tick); +-void kni_handle_tx(struct rte_mbuf *mbuf); + #endif +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 2e11670..5b0f83e 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -13,7 +13,11 @@ + #include + #include + ++#include ++#include ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + #include ++#endif + #include + #include + #include +@@ -755,6 +759,7 @@ int distribute_pakages(struct rte_mbuf *mbuf) + return TRANSFER_KERNEL; + } + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + void kni_handle_rx(uint16_t port_id) + { + struct rte_mbuf *pkts_burst[PACKET_READ_SIZE]; +@@ -793,6 +798,7 @@ void kni_handle_tx(struct rte_mbuf *mbuf) + rte_pktmbuf_free(mbuf); + } + } ++#endif + + /* optimized eth_dev_poll() in lstack */ + int32_t gazelle_eth_dev_poll(struct protocol_stack *stack, uint8_t use_ltran_flag, uint32_t nic_read_number) +@@ -835,7 +841,9 @@ int32_t gazelle_eth_dev_poll(struct protocol_stack *stack, uint8_t use_ltran_fla + if (likely(transfer_type == TRANSFER_CURRENT_THREAD)) { + eth_dev_recv(stack->pkts[i], stack); + } else if (transfer_type == TRANSFER_KERNEL) { ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + kni_handle_tx(stack->pkts[i]); ++#endif + } else { + /* transfer to other thread */ + } +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index c845f7a..fe17f59 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -22,6 +22,8 @@ + #include + #include + ++#include ++ + #include "lstack_cfg.h" + #include "lstack_dpdk.h" + #include "lstack_ethdev.h" +@@ -85,7 +87,7 @@ static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkt + + /* skip gro when tcp/ip cksum offloads disable */ + if (get_protocol_stack_group()->rx_offload == 0 || (get_global_cfg_params()->nic.vlan_mode >= 0 +- && !(get_protocol_stack_group()->rx_offload & DEV_RX_OFFLOAD_VLAN_STRIP))) { ++ && !(get_protocol_stack_group()->rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_STRIP))) { + return pkt_num; + } + +diff --git a/src/ltran/CMakeLists.txt b/src/ltran/CMakeLists.txt +index e098a77..f739ceb 100644 +--- a/src/ltran/CMakeLists.txt ++++ b/src/ltran/CMakeLists.txt +@@ -27,22 +27,38 @@ if($ENV{GAZELLE_COVERAGE_ENABLE}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs") + endif($ENV{GAZELLE_COVERAGE_ENABLE}) + +-if($ENV{DPDK_VERSION_1911}) ++execute_process( ++ COMMAND rpm -qa dpdk ++ OUTPUT_VARIABLE DPDK_VERSION_FULL ++ OUTPUT_STRIP_TRAILING_WHITESPACE ++) ++string(REGEX MATCH "[0-9]+\\.[0-9]+" DPDK_VERSION ${DPDK_VERSION_FULL}) ++ ++if (DPDK_VERSION STREQUAL "21.11") ++ set(DPDK_DIR /usr/local/include/) ++else() + set(DPDK_DIR /usr/include/dpdk) +- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDPDK_VERSION_1911=1") ++endif() ++ ++if (DPDK_VERSION STREQUAL "19.11") + set(DPDK_LINK_FLAGS "-Wl,-lrte_pmd_bond -Wl,-lrte_pmd_hinic -Wl,-lrte_pmd_ixgbe \ + -Wl,-lrte_pmd_pcap -Wl,-lrte_pmd_virtio") + if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "loongarch64") + set(DPDK_LINK_FLAGS "${DPDK_LINK_FLAGS} -Wl,-lrte_pmd_i40e") + endif() + else() +- set(DPDK_DIR /usr/local/include/) + set(DPDK_LINK_FLAGS "-Wl,-lrte_net_bond -Wl,-lrte_net_hinic -Wl,-lrte_net_ixgbe \ + -Wl,-lpcap -Wl,-lrte_net_pcap -Wl,-lrte_net_virtio -Wl,-lrte_pcapng -Wl,-lrte_telemetry") + if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "loongarch64") + set(DPDK_LINK_FLAGS "${DPDK_LINK_FLAGS} -Wl,-lrte_net_i40e") + endif() +-endif($ENV{DPDK_VERSION_1911}) ++endif() ++ ++if (DPDK_VERSION GREATER_EQUAL 23.11) ++ set(DPDK_LINK_FLAGS "${DPDK_LINK_FLAGS} -lrte_log -larchive -Wl,-lrte_eal") ++else() ++ set(DPDK_LINK_FLAGS "${DPDK_LINK_FLAGS} -lrte_kni -Wl,-Bstatic -lrte_eal -Wl,-Bdynamic") ++endif() + + add_executable(ltran main.c ltran_param.c ltran_config.c ltran_ethdev.c ltran_stat.c ltran_errno.c + ltran_monitor.c ltran_instance.c ltran_stack.c ltran_tcp_conn.c ltran_tcp_sock.c +@@ -55,16 +71,19 @@ target_compile_options(ltran PRIVATE -fno-strict-aliasing -D__ARM_FEATURE_CRC32= + -DRTE_MACHINE_CPUFLAG_SHA1 -DRTE_MACHINE_CPUFLAG_SHA2 -include rte_config.h + -D_GNU_SOURCE -W -Wall -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition + -Wpointer-arith -Wcast-qual -Wnested-externs -Wformat-nonliteral -Wformat-security -Wundef +- -Wdeprecated -Wwrite-strings -Wno-implicit-fallthrough -D_FORTIFY_SOURCE=2) +-if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "sw_64") ++ -Wdeprecated -Wwrite-strings -Wno-implicit-fallthrough -D_FORTIFY_SOURCE=2 -Wno-error=deprecated-declarations) ++ ++# gcc coredump in openEuler-20.03-LTS-XX aarch64 when add -march=native ++if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "sw_64|aarch64" ) + target_compile_options(ltran PRIVATE -march=native -Wcast-align) + endif() + + target_link_libraries(ltran PRIVATE config boundscheck rte_pdump -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wtrampolines) ++ + set_target_properties(ltran PROPERTIES LINK_FLAGS "-L$ENV{DPDK_LIB_PATH} -Wl,--no-whole-archive \ + -Wl,-lrte_meter -Wl,--whole-archive -Wl,-lrte_gro -Wl,-lrte_hash -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_ethdev \ + -Wl,-lrte_net -Wl,-lrte_timer -Wl,-lrte_mempool -Wl,-lrte_mempool_ring -Wl,-lrte_ring -Wl,-lrte_pci \ +- -Wl,-Bstatic -lrte_eal -Wl,-Bdynamic -Wl,-lrte_cmdline -Wl,-lrte_kni -Wl,-lrte_bus_pci \ ++ -Wl,-lrte_cmdline -Wl,-lrte_bus_pci\ + -Wl,-lrte_bus_vdev ${DPDK_LINK_FLAGS} \ + -Wl,--no-whole-archive -Wl,-lm -Wl,-lrt -Wl,-lnuma -Wl,-ldl -Wl,-export-dynamic -Wl,-export-dynamic \ + -Wl,--as-needed -Wl,-export-dynamic -Wl,-Map=ltran.map -Wl,--cref") +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 0d7ea7b..4b246a1 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -26,6 +26,8 @@ + #include + #include + ++#include ++ + #include "ltran_stat.h" + #include "ltran_base.h" + #include "gazelle_dfx_msg.h" +@@ -168,16 +170,16 @@ static void gazelle_print_lstack_nic_features(void *buf, const struct gazelle_st + struct nic_eth_features *f = &(((struct gazelle_stack_dfx_data *)buf)->data.nic_features); + printf("###### NIC offload and other features for port %-2d #########\n", f->port_id); + +- printf("tx-ipv4-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_IPV4_CKSUM) ? "on" : "off"); +- printf("tx-tcp-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_CKSUM) ? "on" : "off"); +- printf("tx-tcp-tso: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_TSO) ? "on" : "off"); +- printf("tx-udp-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_UDP_CKSUM) ? "on" : "off"); +- printf("tx-vlan-insert: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_VLAN_INSERT) ? "on" : "off"); ++ printf("tx-ipv4-checksum: %s\n", (f->tx_offload & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) ? "on" : "off"); ++ printf("tx-tcp-checksum: %s\n", (f->tx_offload & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) ? "on" : "off"); ++ printf("tx-tcp-tso: %s\n", (f->tx_offload & RTE_ETH_TX_OFFLOAD_TCP_TSO) ? "on" : "off"); ++ printf("tx-udp-checksum: %s\n", (f->tx_offload & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) ? "on" : "off"); ++ printf("tx-vlan-insert: %s\n", (f->tx_offload & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) ? "on" : "off"); + +- printf("rx-ipv4-checksum: %s\n", (f->rx_offload & DEV_RX_OFFLOAD_IPV4_CKSUM) ? "on" : "off"); +- printf("rx-tcp-checksum: %s\n", (f->rx_offload & DEV_RX_OFFLOAD_TCP_CKSUM) ? "on" : "off"); +- printf("rx-udp-checksum: %s\n", (f->rx_offload & DEV_RX_OFFLOAD_UDP_CKSUM) ? "on" : "off"); +- printf("rx-vlan-strip: %s\n", (f->rx_offload & DEV_RX_OFFLOAD_VLAN_STRIP) ? "on" : "off"); ++ printf("rx-ipv4-checksum: %s\n", (f->rx_offload & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) ? "on" : "off"); ++ printf("rx-tcp-checksum: %s\n", (f->rx_offload & RTE_ETH_RX_OFFLOAD_TCP_CKSUM) ? "on" : "off"); ++ printf("rx-udp-checksum: %s\n", (f->rx_offload & RTE_ETH_RX_OFFLOAD_UDP_CKSUM) ? "on" : "off"); ++ printf("rx-vlan-strip: %s\n", (f->rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) ? "on" : "off"); + } + + static void gazelle_print_ltran_conn(void *buf, const struct gazelle_stat_msg_request *req_msg) +diff --git a/src/ltran/ltran_ethdev.c b/src/ltran/ltran_ethdev.c +index e2eb4a8..2fb7fab 100644 +--- a/src/ltran/ltran_ethdev.c ++++ b/src/ltran/ltran_ethdev.c +@@ -21,10 +21,15 @@ + #include + #include + #include ++#include ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + #include ++#endif + #include + #include + ++#include ++ + #include "dpdk_common.h" + #include "ltran_param.h" + #include "ltran_log.h" +@@ -85,7 +90,11 @@ static int32_t ltran_mbuf_pool_init(void); + static int32_t ltran_single_slave_port_init(uint16_t port_num, struct rte_mempool *pktmbuf_rxpool); + static int32_t ltran_single_bond_port_init(uint16_t port_num, struct rte_mempool *pktmbuf_rxpool); + static int32_t ltran_slave_port_init(void); ++ ++ ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + static int32_t ltran_kni_init(void); ++#endif + static int32_t ltran_bond_port_init(void); + + static int32_t ltran_eal_init(void) +@@ -248,10 +257,10 @@ static int32_t ltran_single_slave_port_init(uint16_t port_num, struct rte_mempoo + } + + struct rte_eth_conf port_conf = {0}; +- port_conf.txmode.mq_mode = ETH_MQ_TX_NONE; +- port_conf.link_speeds = ETH_LINK_SPEED_AUTONEG; ++ port_conf.txmode.mq_mode = RTE_ETH_MQ_TX_NONE; ++ port_conf.link_speeds = RTE_ETH_LINK_SPEED_AUTONEG; + eth_params_checksum(&port_conf, &dev_info); +- port_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; ++ port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE; + + struct ltran_config *ltran_config = get_ltran_config(); + ltran_config->dpdk.rx_offload = port_conf.rxmode.offloads; +@@ -311,7 +320,11 @@ static int32_t ltran_slave_port_init(void) + static int32_t ltran_eth_bond_slave(const struct port_info *port_info, uint16_t port_num, uint16_t bond_port_id) + { + for (uint32_t i = 0; i < port_info[port_num].num_ports; i++) { ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + int32_t ret = rte_eth_bond_slave_add(bond_port_id, port_info[port_num].id[i]); ++#else ++ int32_t ret = rte_eth_bond_member_add(bond_port_id, port_info[port_num].id[i]); ++#endif + if (ret < 0) { + return ret; + } +@@ -370,9 +383,9 @@ static int32_t ltran_bond_port_attr_set(uint16_t port_num, uint16_t bond_port_id + } + + struct rte_eth_conf port_conf = {0}; +- port_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; +- port_conf.txmode.mq_mode = ETH_MQ_TX_NONE; +- port_conf.link_speeds = ETH_LINK_SPEED_AUTONEG; ++ port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE; ++ port_conf.txmode.mq_mode = RTE_ETH_MQ_TX_NONE; ++ port_conf.link_speeds = RTE_ETH_LINK_SPEED_AUTONEG; + eth_params_checksum(&port_conf, &dev_info); + + ret = rte_eth_dev_configure(bond_port_id, rx_queue_num, tx_queue_num, &port_conf); +@@ -469,6 +482,7 @@ static int32_t ltran_bond_port_init(void) + return GAZELLE_OK; + } + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + static int32_t ltran_kni_init(void) + { + // if not use kni. skip kni init and return +@@ -481,6 +495,7 @@ static int32_t ltran_kni_init(void) + + return dpdk_kni_init(bond_port[0], txpool[0]); + } ++#endif + + typedef int32_t (*ethdev_init_func)(void); + +@@ -492,7 +507,9 @@ static ethdev_init_func g_ltran_ethdev_init_tbl[] = { + ltran_mbuf_pool_init, + ltran_slave_port_init, + ltran_bond_port_init, ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + ltran_kni_init, ++#endif + }; + + int32_t ltran_ethdev_init(void) +diff --git a/src/ltran/ltran_forward.c b/src/ltran/ltran_forward.c +index ee379b5..a5756d7 100644 +--- a/src/ltran/ltran_forward.c ++++ b/src/ltran/ltran_forward.c +@@ -13,7 +13,12 @@ + #include + #include + #include ++#include ++ ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + #include ++#endif ++ + #include + #include + #include +@@ -195,6 +200,7 @@ static __rte_always_inline uint32_t pkt_bufs_enque_rx_ring(struct gazelle_stack + + static __rte_always_inline void flush_rx_ring(struct gazelle_stack *stack) + { ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + if (unlikely(stack == get_kni_stack())) { + // if fail, free mbuf inside + kni_process_tx(stack->pkt_buf, stack->pkt_cnt); +@@ -202,6 +208,7 @@ static __rte_always_inline void flush_rx_ring(struct gazelle_stack *stack) + stack->pkt_cnt = 0; + return; + } ++#endif + + /* first flush backup mbuf pointer avoid packet disorder */ + if (unlikely(stack->backup_pkt_cnt > 0)) { +@@ -414,9 +421,12 @@ static __rte_always_inline void upstream_forward_one(struct rte_mbuf *m) + } + + forward_to_kni: ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + if (get_ltran_config()->dpdk.kni_switch == GAZELLE_ON) { + enqueue_rx_packet(get_kni_stack(), m); + } ++#endif ++ return; + } + + static __rte_always_inline void msg_to_quintuple(struct gazelle_quintuple *transfer_qtuple, +@@ -653,10 +663,12 @@ void upstream_forward(const uint16_t *port) + upstream_forward_loop(port_id, queue_id); + } + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + if (get_ltran_config()->dpdk.kni_switch == GAZELLE_ON) { + flush_rx_ring(get_kni_stack()); + rte_kni_handle_request(get_gazelle_kni()); + } ++#endif + + now_time = get_current_time(); + if (now_time - aging_conn_last_time > GAZELLE_CONN_INTERVAL) { +@@ -755,11 +767,13 @@ int32_t downstream_forward(uint16_t *port) + uint32_t queue_num = get_ltran_config()->bond.tx_queue_num; + + while (get_ltran_stop_flag() != GAZELLE_TRUE) { ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + /* kni rx means read from kni and send to nic */ + if (get_ltran_config()->dpdk.kni_switch == GAZELLE_ON && + get_kni_started()) { + kni_process_rx(g_port_index); + } ++#endif + + for (uint32_t queue_id = 0; queue_id < queue_num; queue_id++) { + downstream_forward_loop(port_id, queue_id); +diff --git a/src/ltran/ltran_stack.c b/src/ltran/ltran_stack.c +index d4e935e..2aed6c9 100644 +--- a/src/ltran/ltran_stack.c ++++ b/src/ltran/ltran_stack.c +@@ -10,6 +10,7 @@ + * See the Mulan PSL v2 for more details. + */ + ++#include + #include + + #include "ltran_instance.h" +diff --git a/src/ltran/ltran_timer.c b/src/ltran/ltran_timer.c +index 96c622e..0832c5f 100644 +--- a/src/ltran/ltran_timer.c ++++ b/src/ltran/ltran_timer.c +@@ -10,6 +10,7 @@ + * See the Mulan PSL v2 for more details. + */ + ++#include + #include + #include + +diff --git a/src/ltran/main.c b/src/ltran/main.c +index c2598a7..6cc8bc9 100644 +--- a/src/ltran/main.c ++++ b/src/ltran/main.c +@@ -17,6 +17,8 @@ + #include + #include + #include ++#include ++#include + + #include "dpdk_common.h" + #include "ltran_log.h" +@@ -57,7 +59,9 @@ static void sig_default_handler(int32_t sig) + { + LTRAN_ERR("ltran dumped, caught signal: %d.\n", sig); + print_stack(); ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + dpdk_kni_release(); ++#endif + int ret = 0; + ret = unlink(get_ltran_config()->unix_socket_filename); + if (ret) { +@@ -143,7 +147,9 @@ static void ltran_core_destroy(void) + gazelle_stack_htable_destroy(); + gazelle_tcp_conn_htable_destroy(); + gazelle_tcp_sock_htable_destroy(); ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + dpdk_kni_release(); ++#endif + } + + static void wait_thread_finish(pthread_t ctrl_thread, uint32_t next_core) +-- +2.33.0 + diff --git a/0120-modify-conf-vlan-default-vlaue.patch b/0120-modify-conf-vlan-default-vlaue.patch new file mode 100644 index 0000000..a679ded --- /dev/null +++ b/0120-modify-conf-vlan-default-vlaue.patch @@ -0,0 +1,24 @@ +From 560eb7939415f3cd8b10bbc829fd57141b757727 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Fri, 19 Jan 2024 01:47:26 +0000 +Subject: [PATCH] modify conf vlan default vlaue + +--- + src/lstack/lstack.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/lstack/lstack.conf b/src/lstack/lstack.conf +index 3eb4685..ce86ec4 100644 +--- a/src/lstack/lstack.conf ++++ b/src/lstack/lstack.conf +@@ -64,5 +64,5 @@ process_idx=0 + #tuple_filer=0, below cfg valid + listen_shadow=0 + +-#vlan mode; only support 0~4094, 0 is disabled +-nic_vlan_mode=0 ++#vlan mode; only support -1~4094, -1 is disabled ++nic_vlan_mode=-1 +-- +2.33.0 + diff --git a/0121-remove-unused-variables-in-pbuf-and-reduce-mbuf-size.patch b/0121-remove-unused-variables-in-pbuf-and-reduce-mbuf-size.patch new file mode 100644 index 0000000..911f70c --- /dev/null +++ b/0121-remove-unused-variables-in-pbuf-and-reduce-mbuf-size.patch @@ -0,0 +1,123 @@ +From 2bfb7f1dcaab4436db7345d6f9fcb6f4a1d27681 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sun, 21 Jan 2024 16:42:46 +0800 +Subject: [PATCH] remove unused variables in pbuf and reduce mbuf size + +--- + src/lstack/core/lstack_lwip.c | 10 ---------- + src/lstack/include/lstack_dpdk.h | 2 +- + src/lstack/netif/lstack_ethdev.c | 11 ----------- + 3 files changed, 1 insertion(+), 22 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 6ebe589..63044c2 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -114,14 +114,7 @@ static struct pbuf *init_mbuf_to_pbuf(struct rte_mbuf *mbuf, pbuf_layer layer, u + void *data = rte_pktmbuf_mtod(mbuf, void *); + struct pbuf *pbuf = pbuf_alloced_custom(layer, length, type, pbuf_custom, data, MAX_PACKET_SZ); + if (pbuf) { +- pbuf->ol_flags = 0; +- pbuf->l2_len = 0; +- pbuf->l3_len = 0; +- pbuf->l4_len = 0; +- pbuf->header_off = 0; +- pbuf->rexmit = 0; + pbuf->allow_in = 1; +- pbuf->head = 0; + pbuf->last = pbuf; + pbuf->addr = *IP_ANY_TYPE; + pbuf->port = 0; +@@ -290,7 +283,6 @@ struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_s + if (pbuf->tot_len > remain_size) { + pthread_spin_unlock(&pbuf->pbuf_lock); + *apiflags &= ~TCP_WRITE_FLAG_MORE; +- pbuf->head = 1; + return NULL; + } + if (pbuf->allow_in == 1) { +@@ -300,7 +292,6 @@ struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_s + } else { + if (pbuf->tot_len > remain_size) { + *apiflags &= ~TCP_WRITE_FLAG_MORE; +- pbuf->head = 1; + return NULL; + } + } +@@ -1354,7 +1345,6 @@ err_t netif_loop_output(struct netif *netif, struct pbuf *p) + LSTACK_LOG(ERR, LSTACK, "netif_loop_output: pbuf_alloc failed\n"); + return ERR_MEM; + } +- head->ol_flags = p->ol_flags; + memcpy_s(head->payload, head->len, p->payload, p->len); + + if ((flags & TCP_SYN) && !(flags & TCP_ACK)) { +diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h +index 2a44c6e..b39d199 100644 +--- a/src/lstack/include/lstack_dpdk.h ++++ b/src/lstack/include/lstack_dpdk.h +@@ -21,7 +21,7 @@ + + #define KNI_NB_MBUF (DEFAULT_RING_SIZE << 4) + +-#define MAX_PACKET_SZ 2048 ++#define MAX_PACKET_SZ 1530 + + #define RING_SIZE(x) ((x) - 1) + +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 5b0f83e..4d6f620 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -103,9 +103,6 @@ void eth_dev_recv(struct rte_mbuf *mbuf, struct protocol_stack *stack) + } + next->tot_len = pkt_len; + pkt_len -= len; +-#if CHECKSUM_CHECK_IP_HW || CHECKSUM_CHECK_TCP_HW +- next->ol_flags = m->ol_flags; +-#endif + + if (head == NULL) { + head = next; +@@ -859,7 +856,6 @@ static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + struct protocol_stack *stack = get_protocol_stack(); + struct rte_mbuf *pre_mbuf = NULL; + struct rte_mbuf *first_mbuf = NULL; +- struct pbuf *first_pbuf = pbuf; + void *buf_addr; + + while (likely(pbuf != NULL)) { +@@ -867,8 +863,6 @@ static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + + mbuf->data_len = pbuf->len; + mbuf->pkt_len = pbuf->tot_len; +- mbuf->ol_flags = pbuf->ol_flags; +- mbuf->vlan_tci = pbuf->vlan_tci; + mbuf->next = NULL; + buf_addr = rte_pktmbuf_mtod(mbuf, void *); + +@@ -882,7 +876,6 @@ static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + + if (first_mbuf == NULL) { + first_mbuf = mbuf; +- first_pbuf = pbuf; + first_mbuf->nb_segs = 1; + } else { + first_mbuf->nb_segs++; +@@ -893,13 +886,9 @@ static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + mbuf->ol_flags |= RTE_MBUF_F_TX_TCP_SEG; + mbuf->tso_segsz = MBUF_MAX_DATA_LEN; + } +- mbuf->l2_len = first_pbuf->l2_len; +- mbuf->l3_len = first_pbuf->l3_len; +- mbuf->l4_len = first_pbuf->l4_len; + + pre_mbuf = mbuf; + rte_mbuf_refcnt_update(mbuf, 1); +- pbuf->rexmit = 1; + pbuf = pbuf->next; + } + +-- +2.33.0 + diff --git a/0122-optimize-recv-exit-process-for-FIN-and-unsupport-SO_.patch b/0122-optimize-recv-exit-process-for-FIN-and-unsupport-SO_.patch new file mode 100644 index 0000000..03af162 --- /dev/null +++ b/0122-optimize-recv-exit-process-for-FIN-and-unsupport-SO_.patch @@ -0,0 +1,38 @@ +From 7499d04834da6c3774923972d927229b10189e62 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 22 Jan 2024 12:52:09 +0800 +Subject: [PATCH] optimize recv exit process for FIN and unsupport SO_RCVBUF + +--- + src/lstack/api/lstack_wrap.c | 1 + + src/lstack/core/lstack_lwip.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 3db62c7..372e102 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -372,6 +372,7 @@ static bool unsupport_optname(int32_t optname) + optname == SO_SNDTIMEO || + optname == SO_RCVTIMEO || + optname == SO_SNDBUF || ++ optname == SO_RCVBUF || + optname == TCP_INFO || + optname == TCP_MAXSEG || + optname == TCP_CONGESTION) { +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 6ebe589..ce218f5 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -1016,7 +1016,7 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + } else { + while (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1 && recvd == 0) { + /* if the connection is disconnected, recv return 0 */ +- if ((sock->errevent > 0 || (sock->conn->pcb.tcp->flags & TF_FIN)) && !NETCONN_IS_DATAIN(sock)) { ++ if (sock->errevent > 0 && !NETCONN_IS_DATAIN(sock)) { + return 0; + } + +-- +2.33.0 + diff --git a/0123-remove-expand_send_ring.patch b/0123-remove-expand_send_ring.patch new file mode 100644 index 0000000..260061f --- /dev/null +++ b/0123-remove-expand_send_ring.patch @@ -0,0 +1,371 @@ +From 744be87c712b7166eb921b2e7d537bea71005966 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 22 Jan 2024 17:08:42 +0800 +Subject: [PATCH] remove expand_send_ring + +--- + src/lstack/core/lstack_cfg.c | 9 -- + src/lstack/core/lstack_lwip.c | 191 ++----------------------------- + src/lstack/include/lstack_cfg.h | 1 - + src/lstack/include/lstack_lwip.h | 2 +- + src/lstack/lstack.conf | 4 - + 5 files changed, 12 insertions(+), 195 deletions(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 5e30e89..028ea26 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -66,7 +66,6 @@ static int32_t parse_nic_read_number(void); + static int32_t parse_tcp_conn_count(void); + static int32_t parse_mbuf_count_per_conn(void); + static int32_t parse_send_ring_size(void); +-static int32_t parse_expand_send_ring(void); + static int32_t parse_num_process(void); + static int32_t parse_process_numa(void); + static int32_t parse_process_index(void); +@@ -130,7 +129,6 @@ static struct config_vector_t g_config_tbl[] = { + { "rpc_number", parse_rpc_number }, + { "nic_read_number", parse_nic_read_number }, + { "send_ring_size", parse_send_ring_size }, +- { "expand_send_ring", parse_expand_send_ring }, + { "num_process", parse_num_process }, + { "process_numa", parse_process_numa }, + { "process_idx", parse_process_index }, +@@ -888,13 +886,6 @@ static int32_t parse_send_ring_size(void) + return ret; + } + +-static int32_t parse_expand_send_ring(void) +-{ +- int32_t ret; +- PARSE_ARG(g_config_params.expand_send_ring, "expand_send_ring", 0, 0, 1, ret); +- return ret; +-} +- + static int32_t parse_mbuf_count_per_conn(void) + { + int32_t ret; +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 6ebe589..33b6abd 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -56,17 +56,6 @@ static void free_ring_pbuf(struct rte_ring *ring) + } while (gazelle_ring_readover_count(ring)); + } + +-static void free_list_pbuf(struct pbuf *pbuf) +-{ +- while (pbuf) { +- struct pbuf *del_pbuf = pbuf; +- pbuf = pbuf->next; +- +- del_pbuf->next = NULL; +- pbuf_free(del_pbuf); +- } +-} +- + static void reset_sock_data(struct lwip_sock *sock) + { + /* check null pointer in ring_free func */ +@@ -82,11 +71,6 @@ static void reset_sock_data(struct lwip_sock *sock) + sock->send_ring = NULL; + } + +- if (sock->send_lastdata) { +- free_list_pbuf(sock->send_lastdata); +- sock->send_lastdata = NULL; +- } +- + if (sock->send_pre_del) { + pbuf_free(sock->send_pre_del); + sock->send_pre_del = NULL; +@@ -160,9 +144,7 @@ static bool replenish_send_idlembuf(struct protocol_stack *stack, struct lwip_so + pbuf_free(pbuf[i]); + } + +- if (!get_global_cfg_params()->expand_send_ring) { +- sem_post(&sock->snd_ring_sem); +- } ++ sem_post(&sock->snd_ring_sem); + + return false; + } +@@ -260,22 +242,6 @@ struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_s + } + pthread_spin_unlock(&pbuf->pbuf_lock); + +- if (pbuf->next) { +- sock->send_lastdata = pbuf->next; +- pbuf->next = NULL; +- } +- return pbuf; +- } +- +- if (sock->send_lastdata) { +- pbuf = sock->send_lastdata; +- if (pbuf->tot_len > remain_size) { +- *apiflags &= ~TCP_WRITE_FLAG_MORE; +- return NULL; +- } +- sock->send_pre_del = pbuf; +- sock->send_lastdata = pbuf->next; +- pbuf->next = NULL; + return pbuf; + } + +@@ -305,8 +271,6 @@ struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_s + } + } + +- sock->send_lastdata = pbuf->next; +- pbuf->next = NULL; + return pbuf; + } + +@@ -320,112 +284,25 @@ static ssize_t do_app_write(struct pbuf *pbufs[], void *buf, size_t len, uint32_ + { + ssize_t send_len = 0; + uint32_t i = 0; +- uint32_t expand_send_ring = get_global_cfg_params()->expand_send_ring; + + for (i = 0; i < write_num - 1; i++) { + rte_prefetch0(pbufs[i + 1]); + rte_prefetch0(pbufs[i + 1]->payload); + rte_prefetch0((char *)buf + send_len + MBUF_MAX_DATA_LEN); +- if (expand_send_ring) { +- pbuf_take(pbufs[i], (char *)buf + send_len, MBUF_MAX_DATA_LEN); +- } else { +- rte_memcpy((char *)pbufs[i]->payload, (char *)buf + send_len, MBUF_MAX_DATA_LEN); +- } ++ rte_memcpy((char *)pbufs[i]->payload, (char *)buf + send_len, MBUF_MAX_DATA_LEN); + pbufs[i]->tot_len = pbufs[i]->len = MBUF_MAX_DATA_LEN; + send_len += MBUF_MAX_DATA_LEN; + } + + /* reduce the branch in loop */ + uint16_t copy_len = len - send_len; +- if (expand_send_ring) { +- pbuf_take(pbufs[i], (char *)buf + send_len, copy_len); +- } else { +- rte_memcpy((char *)pbufs[i]->payload, (char *)buf + send_len, copy_len); +- } ++ rte_memcpy((char *)pbufs[i]->payload, (char *)buf + send_len, copy_len); + pbufs[i]->tot_len = pbufs[i]->len = copy_len; + send_len += copy_len; + + return send_len; + } + +-static inline ssize_t app_direct_write(struct protocol_stack *stack, struct lwip_sock *sock, void *buf, +- size_t len, uint32_t write_num) +-{ +- if (write_num == 0) { +- return 0; +- } +- struct pbuf **pbufs = (struct pbuf **)malloc(write_num * sizeof(struct pbuf *)); +- if (pbufs == NULL) { +- return 0; +- } +- +- /* first pbuf get from send_ring. and malloc pbufs attach to first pbuf */ +- if (dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, (struct rte_mbuf **)&pbufs[1], write_num - 1) != 0) { +- stack->stats.tx_allocmbuf_fail++; +- free(pbufs); +- return 0; +- } +- +- (void)gazelle_ring_read(sock->send_ring, (void **)&pbufs[0], 1); +- +- uint32_t i = 1; +- for (; i < write_num - 1; i++) { +- rte_prefetch0(mbuf_to_pbuf((void *)pbufs[i + 1])); +- pbufs[i] = init_mbuf_to_pbuf((struct rte_mbuf *)pbufs[i], PBUF_TRANSPORT, MBUF_MAX_DATA_LEN, PBUF_RAM); +- pbufs[i - 1]->next = pbufs[i]; +- } +- pbufs[i] = init_mbuf_to_pbuf((struct rte_mbuf *)pbufs[i], PBUF_TRANSPORT, MBUF_MAX_DATA_LEN, PBUF_RAM); +- pbufs[i - 1]->next = pbufs[i]; +- +- ssize_t send_len = do_app_write(pbufs, buf, len, write_num); +- +- gazelle_ring_read_over(sock->send_ring); +- +- pbufs[0]->last = pbufs[write_num - 1]; +- sock->remain_len = 0; +- free(pbufs); +- return send_len; +-} +- +-static inline ssize_t app_direct_attach(struct protocol_stack *stack, struct pbuf *attach_pbuf, void *buf, +- size_t len, uint32_t write_num) +-{ +- if (write_num == 0) { +- return 0; +- } +- struct pbuf **pbufs = (struct pbuf **)malloc(write_num * sizeof(struct pbuf *)); +- if (pbufs == NULL) { +- return 0; +- } +- +- /* first pbuf get from send_ring. and malloc pbufs attach to first pbuf */ +- if (dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, (struct rte_mbuf **)pbufs, write_num) != 0) { +- stack->stats.tx_allocmbuf_fail++; +- free(pbufs); +- return 0; +- } +- +- pbufs[0] = init_mbuf_to_pbuf((struct rte_mbuf *)pbufs[0], PBUF_TRANSPORT, MBUF_MAX_DATA_LEN, PBUF_RAM); +- uint32_t i = 1; +- for (; i < write_num - 1; i++) { +- rte_prefetch0(mbuf_to_pbuf((void *)pbufs[i + 1])); +- pbufs[i] = init_mbuf_to_pbuf((struct rte_mbuf *)pbufs[i], PBUF_TRANSPORT, MBUF_MAX_DATA_LEN, PBUF_RAM); +- pbufs[i - 1]->next = pbufs[i]; +- } +- if (write_num > 1) { +- pbufs[i] = init_mbuf_to_pbuf((struct rte_mbuf *)pbufs[i], PBUF_TRANSPORT, MBUF_MAX_DATA_LEN, PBUF_RAM); +- pbufs[i - 1]->next = pbufs[i]; +- } +- +- ssize_t send_len = do_app_write(pbufs, buf, len, write_num); +- +- attach_pbuf->last->next = pbufs[0]; +- attach_pbuf->last = pbufs[write_num - 1]; +- +- free(pbufs); +- return send_len; +-} +- + static inline ssize_t app_buff_write(struct lwip_sock *sock, void *buf, size_t len, uint32_t write_num, + const struct sockaddr *addr, socklen_t addrlen) + { +@@ -496,12 +373,6 @@ static inline size_t merge_data_lastpbuf(struct lwip_sock *sock, void *buf, size + return 0; + } + +- if (last_pbuf->next || last_pbuf->len >= MBUF_MAX_DATA_LEN) { +- sock->remain_len = 0; +- gazelle_ring_lastover(last_pbuf); +- return 0; +- } +- + size_t send_len = MBUF_MAX_DATA_LEN - last_pbuf->len; + if (send_len >= len) { + sock->remain_len = send_len - len; +@@ -512,11 +383,7 @@ static inline size_t merge_data_lastpbuf(struct lwip_sock *sock, void *buf, size + + uint16_t offset = last_pbuf->len; + last_pbuf->tot_len = last_pbuf->len = offset + send_len; +- if (get_global_cfg_params()->expand_send_ring) { +- pbuf_take_at(last_pbuf, buf, send_len, offset); +- } else { +- rte_memcpy((char *)last_pbuf->payload + offset, buf, send_len); +- } ++ rte_memcpy((char *)last_pbuf->payload + offset, buf, send_len); + + gazelle_ring_lastover(last_pbuf); + +@@ -570,55 +437,19 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + + /* send_ring is full, data attach last pbuf */ + if (write_avail == 0) { +- if (!get_global_cfg_params()->expand_send_ring) { +- sem_timedwait_nsecs(&sock->snd_ring_sem); +- if (likely(sock->send_ring != NULL)) { +- write_avail = gazelle_ring_readable_count(sock->send_ring); +- } +- goto END; ++ sem_timedwait_nsecs(&sock->snd_ring_sem); ++ if (likely(sock->send_ring != NULL)) { ++ write_avail = gazelle_ring_readable_count(sock->send_ring); + } +- if (unlikely(sock->send_ring == NULL)) { +- goto END; +- } +- struct pbuf *last_pbuf = gazelle_ring_readlast(sock->send_ring); +- if (last_pbuf) { +- send_len += app_direct_attach(stack, last_pbuf, (char *)buf + send_len, len - send_len, write_num); +- gazelle_ring_lastover(last_pbuf); +- if (wakeup) { +- wakeup->stat.app_write_cnt += write_num; +- } +- if (addr->sa_family == AF_INET) { +- struct sockaddr_in *saddr = (struct sockaddr_in *)addr; +- last_pbuf->addr.u_addr.ip4.addr = saddr->sin_addr.s_addr; +- last_pbuf->port = lwip_ntohs((saddr)->sin_port); +- } else if (addr->sa_family == AF_INET6) { +- struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)addr; +- memcpy_s(last_pbuf->addr.u_addr.ip6.addr, sizeof(last_pbuf->addr.u_addr.ip6.addr), +- saddr->sin6_addr.s6_addr, sizeof(saddr->sin6_addr.s6_addr)); +- last_pbuf->port = lwip_ntohs((saddr)->sin6_port); +- } +- } else { +- (void)rpc_call_replenish(stack, sock); +- if (wakeup) { +- wakeup->stat.app_write_rpc++; +- } +- } +- sock->remain_len = 0; + goto END; + } + + /* send_ring have idle */ +- if (get_global_cfg_params()->expand_send_ring) { +- send_len += (write_num <= write_avail) ? +- app_buff_write(sock, (char *)buf + send_len, len - send_len, write_num, addr, addrlen) : +- app_direct_write(stack, sock, (char *)buf + send_len, len - send_len, write_num); +- } else { +- if (write_num > write_avail) { +- write_num = write_avail; +- len = write_num * MBUF_MAX_DATA_LEN; +- } +- send_len += app_buff_write(sock, (char *)buf + send_len, len - send_len, write_num, addr, addrlen); ++ if (write_num > write_avail) { ++ write_num = write_avail; ++ len = write_num * MBUF_MAX_DATA_LEN; + } ++ send_len += app_buff_write(sock, (char *)buf + send_len, len - send_len, write_num, addr, addrlen); + + if (wakeup) { + wakeup->stat.app_write_cnt += write_num; +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index c1074f8..01d70fb 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -110,7 +110,6 @@ struct cfg_params { + struct secondary_attach_arg sec_attach_arg; + char unix_socket_filename[NAME_MAX]; + uint16_t send_ring_size; +- bool expand_send_ring; + bool tuple_filter; + int8_t bond_mode; + struct rte_ether_addr bond_slave_mac_addr[GAZELLE_MAX_BOND_NUM]; +diff --git a/src/lstack/include/lstack_lwip.h b/src/lstack/include/lstack_lwip.h +index 0a82781..fa10e3f 100644 +--- a/src/lstack/include/lstack_lwip.h ++++ b/src/lstack/include/lstack_lwip.h +@@ -18,7 +18,7 @@ + + #define NETCONN_IS_ACCEPTIN(sock) (((sock)->conn->acceptmbox != NULL) && !sys_mbox_empty((sock)->conn->acceptmbox)) + #define NETCONN_IS_DATAIN(sock) ((gazelle_ring_readable_count((sock)->recv_ring) || (sock)->recv_lastdata) || (sock->same_node_rx_ring != NULL && same_node_ring_count(sock))) +-#define NETCONN_IS_DATAOUT(sock) (gazelle_ring_readover_count((sock)->send_ring) || (sock)->send_lastdata || (sock)->send_pre_del) ++#define NETCONN_IS_DATAOUT(sock) (gazelle_ring_readover_count((sock)->send_ring) || (sock)->send_pre_del) + #define NETCONN_IS_OUTIDLE(sock) gazelle_ring_readable_count((sock)->send_ring) + #define NETCONN_IS_UDP(sock) (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) == NETCONN_UDP) + +diff --git a/src/lstack/lstack.conf b/src/lstack/lstack.conf +index 3eb4685..7baa38d 100644 +--- a/src/lstack/lstack.conf ++++ b/src/lstack/lstack.conf +@@ -24,10 +24,6 @@ mbuf_count_per_conn = 170 + # send ring size, default is 32, max is 2048 + send_ring_size = 32 + +-# 0: when send ring full, send return +-# 1: when send ring full, alloc mbuf from mempool to send data +-expand_send_ring = 0 +- + #protocol stack thread per loop params + #read data form protocol stack into recv_ring + read_connect_number = 4 +-- +2.33.0 + diff --git a/0124-set-ltran.patch b/0124-set-ltran.patch new file mode 100644 index 0000000..c477d35 --- /dev/null +++ b/0124-set-ltran.patch @@ -0,0 +1,25 @@ +From c565ac1ced3eba745f22cdca849c3d38aaf386f1 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Sat, 27 Jan 2024 02:22:11 +0000 +Subject: [PATCH] set ltran + +--- + src/lstack/lstack.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lstack/lstack.conf b/src/lstack/lstack.conf +index fc49944..60f3ee5 100644 +--- a/src/lstack/lstack.conf ++++ b/src/lstack/lstack.conf +@@ -12,7 +12,7 @@ dpdk_args=["--socket-mem", "2048,0,0,0", "--huge-dir", "/mnt/hugepages-lstack", + + stack_thread_mode="run-to-wakeup" + +-use_ltran=1 ++use_ltran=0 + kni_switch=0 + + low_power_mode=0 +-- +2.33.0 + diff --git a/0125-add-bond-doc.patch b/0125-add-bond-doc.patch new file mode 100644 index 0000000..6f71327 --- /dev/null +++ b/0125-add-bond-doc.patch @@ -0,0 +1,25 @@ +From 44f8b983df75103b1bd3befbabeebe3ef406dbb1 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Sat, 27 Jan 2024 09:16:46 +0000 +Subject: [PATCH] add bond doc + +--- + src/lstack/lstack.conf | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/lstack/lstack.conf b/src/lstack/lstack.conf +index 60f3ee5..a7f4e75 100644 +--- a/src/lstack/lstack.conf ++++ b/src/lstack/lstack.conf +@@ -62,3 +62,8 @@ listen_shadow=0 + + #vlan mode; only support -1~4094, -1 is disabled + nic_vlan_mode=-1 ++ ++#bond mode; only support bond 4 or 6 mode ,-1 is disabled ++bond_mode=-1 ++#bond slave mac, separated by ; , only support 2 slave mac ++#bond_slave_mac="aa:bb:cc:dd:ee:ff;gg:hh:ii:jj:kk:ll" +-- +2.33.0 + diff --git a/0126-cfg-host_addr-is-not-mandatory.patch b/0126-cfg-host_addr-is-not-mandatory.patch new file mode 100644 index 0000000..27a2f71 --- /dev/null +++ b/0126-cfg-host_addr-is-not-mandatory.patch @@ -0,0 +1,61 @@ +From 1ad9802429cc2d2cf8eb90ec84cfed7d3c3d4feb Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Mon, 29 Jan 2024 15:01:05 +0800 +Subject: [PATCH] cfg: host_addr is not mandatory + +--- + src/lstack/core/lstack_cfg.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 028ea26..7e4482f 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -185,6 +185,10 @@ static int32_t parse_gateway_addr(void) + char *value; + bool ok; + ++ if (ip4_addr_isany_val(g_config_params.host_addr)) { ++ return 0; ++ } ++ + ok = config_lookup_string(&g_config, "gateway_addr", (const char **)&value); + if (!ok) { + return -EINVAL; +@@ -202,6 +206,10 @@ static int32_t parse_mask_addr(void) + uint32_t mask; + bool ok; + ++ if (ip4_addr_isany_val(g_config_params.host_addr)) { ++ return 0; ++ } ++ + ok = config_lookup_string(&g_config, "mask_addr", (const char **)&value); + if (!ok) { + return -EINVAL; +@@ -225,7 +233,7 @@ static int32_t parse_host_addr(void) + + ok = config_lookup_string(&g_config, "host_addr", (const char **)&value); + if (!ok) { +- return -EINVAL; ++ return 0; + } + + g_config_params.host_addr.addr = inet_addr(value); +@@ -242,7 +250,12 @@ static int32_t parse_host_addr6(void) + + ok = config_lookup_string(&g_config, "host_addr6", (const char **)&value); + if (!ok) { +- return 0; ++ if (ip4_addr_isany_val(g_config_params.host_addr)) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: host_addr and host_addr6 must have a valid one."); ++ return -EINVAL; ++ } else { ++ return 0; ++ } + } + + if (ip6addr_aton(value, &g_config_params.host_addr6) == 0) { +-- +2.33.0 + diff --git a/0127-add-bond1-support.patch b/0127-add-bond1-support.patch new file mode 100644 index 0000000..e609d70 --- /dev/null +++ b/0127-add-bond1-support.patch @@ -0,0 +1,139 @@ +From cfe5641d29e425c9da54b270b7945d17ab5d594b Mon Sep 17 00:00:00 2001 +From: zhangmengxuan +Date: Mon, 22 Jan 2024 13:52:50 +0800 +Subject: [PATCH] add bond1 support + +--- + src/lstack/core/lstack_cfg.c | 28 ++++++++++++++++++++++++---- + src/lstack/core/lstack_dpdk.c | 24 ++++++++++++++++++++++++ + src/lstack/include/lstack_cfg.h | 1 + + 3 files changed, 49 insertions(+), 4 deletions(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 7e4482f..b533a33 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -40,6 +40,8 @@ + #define NUMA_CPULIST_PATH "/sys/devices/system/node/node%u/cpulist" + #define DEV_MAC_LEN 17 + #define CPUS_MAX_NUM 256 ++#define BOND_MIIMON_MIN 1 ++#define BOND_MIIMON_MAX INT_MAX + + static struct cfg_params g_config_params; + +@@ -72,6 +74,7 @@ static int32_t parse_process_index(void); + static int32_t parse_seperate_sendrecv_args(void); + static int32_t parse_tuple_filter(void); + static int32_t parse_bond_mode(void); ++static int32_t parse_bond_miimon(void); + static int32_t parse_bond_slave_mac(void); + static int32_t parse_use_sockmap(void); + static int32_t parse_udp_enable(void); +@@ -134,6 +137,7 @@ static struct config_vector_t g_config_tbl[] = { + { "process_idx", parse_process_index }, + { "tuple_filter", parse_tuple_filter }, + { "bond_mode", parse_bond_mode }, ++ { "bond_miimon", parse_bond_miimon}, + { "bond_slave_mac", parse_bond_slave_mac }, + { "use_sockmap", parse_use_sockmap }, + { "udp_enable", parse_udp_enable }, +@@ -1181,14 +1185,30 @@ static int32_t parse_bond_mode(void) + if (g_config_params.bond_mode == -1) { + return 0; + } +- if (g_config_params.bond_mode != BONDING_MODE_8023AD && g_config_params.bond_mode != BONDING_MODE_ALB) { +- LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid bond mode = %d. only supports bond mode = 4,6.\n", +- g_config_params.bond_mode); +- return -EINVAL; ++ ++ switch (g_config_params.bond_mode) { ++ case BONDING_MODE_ACTIVE_BACKUP: ++ case BONDING_MODE_8023AD: ++ case BONDING_MODE_ALB: ++ break; ++ default: ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid bond mode = %d. only supports bond mode = 1,4,6.\n", ++ g_config_params.bond_mode); ++ return -EINVAL; // Invalid bond mode + } + return 0; + } + ++static int32_t parse_bond_miimon(void) ++{ ++ int32_t ret; ++ if (g_config_params.bond_mode == -1) { ++ return 0; ++ } ++ PARSE_ARG(g_config_params.bond_miimon, "bond_miimon", 10, BOND_MIIMON_MIN, BOND_MIIMON_MAX, ret); ++ return ret; ++} ++ + static int32_t parse_bond_slave_mac(void) + { + if (g_config_params.bond_mode == -1) { +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 7f1ceb8..e352850 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -462,6 +462,20 @@ static void rss_setup(const int port_id, const uint16_t nb_queues) + free(reta_conf); + } + ++int32_t dpdk_bond_primary_set(int port_id, int slave_port_id) ++{ ++ int32_t primary_port_id = ethdev_port_id(get_global_cfg_params()->mac_addr); ++ if (slave_port_id == primary_port_id) { ++ int32_t ret = rte_eth_bond_primary_set(port_id, primary_port_id); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "dpdk set bond primary port failed ret = %d\n", ret); ++ return -1; ++ } ++ return ret; ++ } ++ return 0; ++} ++ + int32_t dpdk_ethdev_init(int port_id, bool bond_port) + { + uint16_t nb_queues = get_global_cfg_params()->num_cpu; +@@ -533,6 +547,10 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + LSTACK_LOG(ERR, LSTACK, "dpdk add slave port failed ret = %d\n", ret); + return -1; + } ++ ++ if (get_global_cfg_params()->bond_mode == BONDING_MODE_ACTIVE_BACKUP) { ++ dpdk_bond_primary_set(port_id, slave_port_id[i]); ++ } + + ret = rte_eth_dev_start(slave_port_id[i]); + if (ret != 0) { +@@ -736,6 +754,12 @@ int32_t init_dpdk_ethdev(void) + } + } + ++ ret = rte_eth_bond_link_monitoring_set(bond_port_id, get_global_cfg_params()->bond_miimon); ++ if (ret < 0) { ++ LSTACK_LOG(ERR, LSTACK, "dpdk set bond link monitoring failed ret = %d\n", ret); ++ return -1; ++ } ++ + ret = rte_eth_promiscuous_enable(bond_port_id); + if (ret < 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk enable promiscuous failed ret = %d\n", ret); +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index 01d70fb..a00e47a 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -112,6 +112,7 @@ struct cfg_params { + uint16_t send_ring_size; + bool tuple_filter; + int8_t bond_mode; ++ int32_t bond_miimon; + struct rte_ether_addr bond_slave_mac_addr[GAZELLE_MAX_BOND_NUM]; + bool use_sockmap; + bool udp_enable; +-- +2.33.0 + diff --git a/0128-fix-t_params-double-free.patch b/0128-fix-t_params-double-free.patch new file mode 100644 index 0000000..6335292 --- /dev/null +++ b/0128-fix-t_params-double-free.patch @@ -0,0 +1,77 @@ +From 8905d508d754a6d75516bbf26839848f4dfef282 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 29 Jan 2024 19:11:45 +0800 +Subject: [PATCH] fix t_params double free + +--- + src/lstack/core/lstack_protocol_stack.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 800872b..bb7ec17 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -660,7 +660,7 @@ int32_t stack_setup_thread(void) + for (uint32_t i = 0; i < queue_num; ++i) { + t_params[i] = malloc(sizeof(struct thread_params)); + if (t_params[i] == NULL) { +- goto OUT; ++ goto OUT1; + } + } + +@@ -669,18 +669,18 @@ int32_t stack_setup_thread(void) + if (i % 2 == 0) { + ret = sprintf_s(name, sizeof(name), "%s_%d_%d", LSTACK_RECV_THREAD_NAME, process_index, i / 2); + if (ret < 0) { +- goto OUT; ++ goto OUT1; + } + } else { + ret = sprintf_s(name, sizeof(name), "%s_%d_%d", LSTACK_SEND_THREAD_NAME, process_index, i / 2); + if (ret < 0) { +- goto OUT; ++ goto OUT1; + } + } + } else { + ret = sprintf_s(name, sizeof(name), "%s", LSTACK_THREAD_NAME); + if (ret < 0) { +- goto OUT; ++ goto OUT1; + } + } + +@@ -689,24 +689,26 @@ int32_t stack_setup_thread(void) + + ret = create_thread((void *)t_params[i], name, gazelle_stack_thread); + if (ret != 0) { +- goto OUT; ++ goto OUT1; + } + } + + /* 2: wait stack thread and kernel_event thread init finish */ + wait_sem_value(&g_stack_group.sem_stack_setup, queue_num * 2); + if (g_stack_group.stack_setup_fail) { +- goto OUT; ++ /* t_params free by stack thread */ ++ goto OUT2; + } + g_stack_group.stack_num = queue_num; + + return 0; +-OUT: ++OUT1: + for (int32_t i = 0; i < queue_num; ++i) { + if (t_params[i] != NULL) { + free(t_params[i]); + } + } ++OUT2: + return -1; + } + +-- +2.33.0 + diff --git a/0129-fix-receive-fin-packet-process-error.patch b/0129-fix-receive-fin-packet-process-error.patch new file mode 100644 index 0000000..4c8ec0e --- /dev/null +++ b/0129-fix-receive-fin-packet-process-error.patch @@ -0,0 +1,155 @@ +From 517d32ae3467596ca8173ff5f9300aa7d84d2b7f Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 22 Jan 2024 17:30:30 +0800 +Subject: [PATCH] fix receive fin packet process error + +--- + src/lstack/core/lstack_lwip.c | 67 +++++++++++++++++++++++------------ + 1 file changed, 45 insertions(+), 22 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index fe30edf..a7201aa 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -38,6 +38,8 @@ + #include "lstack_cfg.h" + #include "lstack_lwip.h" + ++static const uint8_t fin_packet = 0; ++ + static void free_ring_pbuf(struct rte_ring *ring) + { + void *pbufs[SOCK_RECV_RING_SIZE]; +@@ -509,13 +511,15 @@ static inline struct pbuf *pbuf_last(struct pbuf *pbuf) + ssize_t do_lwip_read_from_lwip(struct lwip_sock *sock, int32_t flags, u8_t apiflags) + { + if (sock->conn->recvmbox == NULL) { +- return 0; ++ sock->conn->pending_err = ERR_CONN; ++ GAZELLE_RETURN(ENOTCONN); + } + + free_recv_ring_readover(sock->recv_ring); + + uint32_t free_count = gazelle_ring_free_count(sock->recv_ring); + if (free_count == 0) { ++ sock->conn->pending_err = ERR_WOULDBLOCK; + GAZELLE_RETURN(EAGAIN); + } + +@@ -534,12 +538,19 @@ ssize_t do_lwip_read_from_lwip(struct lwip_sock *sock, int32_t flags, u8_t apifl + err = netconn_recv_tcp_pbuf_flags(sock->conn, &pbufs[i], apiflags); + } + if (err != ERR_OK) { +- if (recv_len > 0) { +- /* already received data, return that (this trusts in getting the same error from +- netconn layer again next time netconn_recv is called) */ ++ /* fin has been read from recvmbox, put it to recv_ring */ ++ if (!NETCONN_IS_UDP(sock) && ++ (netconn_is_flag_set(sock->conn, NETCONN_FIN_RX_PENDING) || err == ERR_CLSD)) { ++ /* fin has been read, lwip don't need to process fin packet */ ++ netconn_clear_flags(sock->conn, NETCONN_FIN_RX_PENDING); ++ pbufs[i] = NULL; ++ read_count++; + break; + } +- return (err == ERR_CLSD) ? 0 : -1; ++ ++ /* store err to pending_err again, clear it after app read */ ++ sock->conn->pending_err = err; ++ GAZELLE_RETURN(err_to_errno(err)); + } + + recv_len += pbufs[i]->tot_len; +@@ -551,25 +562,17 @@ ssize_t do_lwip_read_from_lwip(struct lwip_sock *sock, int32_t flags, u8_t apifl + } + + uint32_t enqueue_num = gazelle_ring_sp_enqueue(sock->recv_ring, (void **)pbufs, read_count); +- for (uint32_t i = enqueue_num; i < read_count; i++) { +- if (NETCONN_IS_UDP(sock)) { +- pbuf_free(pbufs[i]); +- } else { +- /* update receive window */ +- tcp_recved(sock->conn->pcb.tcp, pbufs[i]->tot_len); +- pbuf_free(pbufs[i]); +- } +- sock->stack->stats.read_lwip_drop++; ++ if (enqueue_num != read_count) { ++ LSTACK_LOG(ERR, LSTACK, "Code shouldn't get here!\n"); + } + + for (uint32_t i = 0; get_protocol_stack_group()->latency_start && i < read_count; i++) { +- calculate_lstack_latency(&sock->stack->latency, pbufs[i], GAZELLE_LATENCY_LWIP); ++ if (pbufs[i] != NULL) { ++ calculate_lstack_latency(&sock->stack->latency, pbufs[i], GAZELLE_LATENCY_LWIP); ++ } + } + + sock->stack->stats.read_lwip_cnt += read_count; +- if (recv_len == 0) { +- GAZELLE_RETURN(EAGAIN); +- } + return recv_len; + } + +@@ -817,7 +820,8 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + bool latency_enable = get_protocol_stack_group()->latency_start; + + if (sock->errevent > 0 && !NETCONN_IS_DATAIN(sock)) { +- return 0; ++ errno = err_to_errno(netconn_err(sock->conn)); ++ return -1; + } + + thread_bind_stack(sock); +@@ -839,7 +843,8 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + while (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1 && recvd == 0) { + /* if the connection is disconnected, recv return 0 */ + if (sock->errevent > 0 && !NETCONN_IS_DATAIN(sock)) { +- return 0; ++ errno = err_to_errno(netconn_err(sock->conn)); ++ return -1; + } + + lstack_block_wait(sock->wakeup); +@@ -847,6 +852,23 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + } + } + ++ /* fin */ ++ if (unlikely(pbuf == NULL)) { ++ if (recvd > 0) { ++ /* read data first, then read fin */ ++ sock->recv_lastdata = (void *)&fin_packet; ++ gazelle_ring_read_over(sock->recv_ring); ++ break; ++ } ++ gazelle_ring_read_over(sock->recv_ring); ++ return 0; ++ } ++ ++ /* pending fin */ ++ if (unlikely(pbuf == (void *)&fin_packet)) { ++ return 0; ++ } ++ + copy_len = (recv_left > pbuf->tot_len) ? pbuf->tot_len : recv_left; + if (copy_len > UINT16_MAX) { + copy_len = UINT16_MAX; +@@ -946,10 +968,11 @@ void do_lwip_read_recvlist(struct protocol_stack *stack, uint32_t max_num) + } else { + len = lwip_recv(sock->conn->socket, NULL, 0, 0); + } +- if (len == 0) { ++ if (len < 0 && errno != EAGAIN) { + sock->errevent = 1; + add_sock_event(sock, EPOLLERR); +- } else if (len > 0) { ++ /* = 0: fin */ ++ } else if (len >= 0) { + add_sock_event(sock, EPOLLIN); + } + } +-- +2.33.0 + diff --git a/0130-support-netperf-UDP_STREAM-and-UDP_RR.patch b/0130-support-netperf-UDP_STREAM-and-UDP_RR.patch new file mode 100644 index 0000000..0d75020 --- /dev/null +++ b/0130-support-netperf-UDP_STREAM-and-UDP_RR.patch @@ -0,0 +1,129 @@ +From abbd69fdbc7b43229093a1ec57ea6d0dd952db8d Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Fri, 26 Jan 2024 17:21:38 +0800 +Subject: [PATCH] support netperf UDP_STREAM and UDP_RR + +--- + src/lstack/api/lstack_rtw_api.c | 7 +++---- + src/lstack/api/lstack_wrap.c | 1 + + src/lstack/core/lstack_lwip.c | 21 +++++++++++++++------ + 3 files changed, 19 insertions(+), 10 deletions(-) + +diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c +index 04944d5..839d320 100644 +--- a/src/lstack/api/lstack_rtw_api.c ++++ b/src/lstack/api/lstack_rtw_api.c +@@ -160,10 +160,10 @@ static ssize_t rtw_udp_recvfrom(int sockfd, void *buf, size_t len, int flags, + + while (1) { + ret = do_lwip_read_from_stack(sockfd, buf, len, flags, addr, addrlen); +- if (ret > 0) { ++ if (ret >= 0) { + return ret; + } +- if (ret <= 0 && errno != EAGAIN) { ++ if (ret < 0 && errno != EAGAIN) { + return -1; + } + sock = sock->listen_next; +@@ -205,7 +205,6 @@ ssize_t rtw_sendto(int sockfd, const void *buf, size_t len, int flags, + return do_lwip_send_to_stack(sockfd, buf, len, flags, addr, addrlen); + } + +- + int rtw_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout) + { + return lstack_rtw_epoll_wait(epfd, events, maxevents, timeout); +@@ -234,7 +233,7 @@ int rtw_shutdown(int fd, int how) + { + struct lwip_sock *sock = get_socket_by_fd(fd); + if (sock && sock->wakeup && sock->wakeup->epollfd == fd) { +- GAZELLE_RETURN(ENOTSOCK); ++ GAZELLE_RETURN(ENOTSOCK); + } + + return stack_broadcast_shutdown(fd, how); +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 372e102..8992e39 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -375,6 +375,7 @@ static bool unsupport_optname(int32_t optname) + optname == SO_RCVBUF || + optname == TCP_INFO || + optname == TCP_MAXSEG || ++ optname == SO_DONTROUTE || + optname == TCP_CONGESTION) { + return true; + } +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index a7201aa..22605dd 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -402,7 +402,7 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + } + + struct protocol_stack *stack = sock->stack; +- if (!stack || len == 0) { ++ if (!stack) { + return 0; + } + +@@ -421,6 +421,11 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + uint32_t write_avail = gazelle_ring_readable_count(sock->send_ring); + struct wakeup_poll *wakeup = sock->wakeup; + ++ /* if udp send 0 packet, set write_num to at least 1 */ ++ if (NETCONN_IS_UDP(sock) && write_num == 0) { ++ write_num = 1; ++ } ++ + while (!netconn_is_nonblocking(sock->conn) && (write_avail < write_num)) { + if (sock->errevent > 0) { + GAZELLE_RETURN(ENOTCONN); +@@ -454,7 +459,7 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + } + + END: +- if (send_len == 0) { ++ if (send_len == 0 && !NETCONN_IS_UDP(sock)) { + errno = EAGAIN; + return -1; + } +@@ -735,19 +740,18 @@ ssize_t do_lwip_send_to_stack(int32_t fd, const void *buf, size_t len, int32_t f + GAZELLE_RETURN(EINVAL); + } + +- if (len == 0) { ++ struct lwip_sock *sock = get_socket_by_fd(fd); ++ if (len == 0 && !NETCONN_IS_UDP(sock)) { + return 0; + } + +- struct lwip_sock *sock = get_socket_by_fd(fd); +- + thread_bind_stack(sock); + + if (sock->same_node_tx_ring != NULL) { + return gazelle_same_node_ring_send(sock, buf, len, flags); + } + ssize_t send = do_lwip_fill_sendring(sock, buf, len, addr, addrlen); +- if (send <= 0) { ++ if (send < 0 || (send == 0 && !NETCONN_IS_UDP(sock))) { + return send; + } + +@@ -852,6 +856,11 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + } + } + ++ /* if udp recv a packet whose len is 0, return 0 */ ++ if (NETCONN_IS_UDP(sock) && pbuf->tot_len == 0) { ++ return 0; ++ } ++ + /* fin */ + if (unlikely(pbuf == NULL)) { + if (recvd > 0) { +-- +2.33.0 + diff --git a/0131-adapt-lwip-2.2.0.patch b/0131-adapt-lwip-2.2.0.patch new file mode 100644 index 0000000..dbbe0ea --- /dev/null +++ b/0131-adapt-lwip-2.2.0.patch @@ -0,0 +1,131 @@ +From feaa11fb77f6134639885c378d87903fc2301331 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Tue, 6 Feb 2024 09:55:23 +0800 +Subject: [PATCH] adapt lwip-2.2.0 + +--- + src/lstack/api/lstack_rtw_api.c | 2 +- + src/lstack/core/lstack_lwip.c | 16 ++++++++-------- + src/lstack/core/lstack_protocol_stack.c | 8 ++++---- + 3 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c +index 839d320..10bc613 100644 +--- a/src/lstack/api/lstack_rtw_api.c ++++ b/src/lstack/api/lstack_rtw_api.c +@@ -168,7 +168,7 @@ static ssize_t rtw_udp_recvfrom(int sockfd, void *buf, size_t len, int flags, + } + sock = sock->listen_next; + if (sock != NULL && sock->conn != NULL) { +- sockfd = sock->conn->socket; ++ sockfd = sock->conn->callback_arg.socket; + } else { + if (sock == NULL) { + errno = EAGAIN; +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 22605dd..2ba18e2 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -973,9 +973,9 @@ void do_lwip_read_recvlist(struct protocol_stack *stack, uint32_t max_num) + + ssize_t len = 0; + if (NETCONN_IS_UDP(sock)) { +- len = lwip_recv(sock->conn->socket, NULL, SSIZE_MAX, 0); ++ len = lwip_recv(sock->conn->callback_arg.socket, NULL, SSIZE_MAX, 0); + } else { +- len = lwip_recv(sock->conn->socket, NULL, 0, 0); ++ len = lwip_recv(sock->conn->callback_arg.socket, NULL, 0, 0); + } + if (len < 0 && errno != EAGAIN) { + sock->errevent = 1; +@@ -993,7 +993,7 @@ void do_lwip_connected_callback(struct netconn *conn) + return; + } + +- int32_t fd = conn->socket; ++ int32_t fd = conn->callback_arg.socket; + struct lwip_sock *sock = get_socket_by_fd(fd); + if (sock == NULL || sock->conn == NULL) { + return; +@@ -1033,9 +1033,9 @@ static void copy_pcb_to_conn(struct gazelle_stat_lstack_conn_info *conn, const s + conn->keep_cnt = pcb->keep_cnt; + + if (netconn != NULL) { +- conn->fd = netconn->socket; ++ conn->fd = netconn->callback_arg.socket; + conn->recv_cnt = (netconn->recvmbox == NULL) ? 0 : rte_ring_count(netconn->recvmbox->ring); +- struct lwip_sock *sock = get_socket(netconn->socket); ++ struct lwip_sock *sock = get_socket(netconn->callback_arg.socket); + if (sock != NULL) { + conn->recv_ring_cnt = (sock->recv_ring == NULL) ? 0 : gazelle_ring_readable_count(sock->recv_ring); + conn->recv_ring_cnt += (sock->recv_lastdata) ? 1 : 0; +@@ -1121,7 +1121,7 @@ uint32_t do_lwip_get_conntable(struct gazelle_stat_lstack_conn_info *conn, + conn[conn_num].l_port = pcbl->local_port; + conn[conn_num].tcp_sub_state = pcbl->state; + struct netconn *netconn = (struct netconn *)pcbl->callback_arg; +- conn[conn_num].fd = netconn != NULL ? netconn->socket : -1; ++ conn[conn_num].fd = netconn != NULL ? netconn->callback_arg.socket : -1; + if (netconn != NULL && netconn->acceptmbox != NULL) { + conn[conn_num].recv_cnt = rte_ring_count(netconn->acceptmbox->ring); + } +@@ -1319,7 +1319,7 @@ err_t same_node_ring_create(struct rte_ring **ring, int size, int port, char *na + static void init_same_node_ring(struct tcp_pcb *pcb) + { + struct netconn *netconn = (struct netconn *)pcb->callback_arg; +- struct lwip_sock *sock = get_socket(netconn->socket); ++ struct lwip_sock *sock = get_socket(netconn->callback_arg.socket); + + pcb->client_rx_ring = NULL; + pcb->client_tx_ring = NULL; +@@ -1334,7 +1334,7 @@ static void init_same_node_ring(struct tcp_pcb *pcb) + err_t create_same_node_ring(struct tcp_pcb *pcb) + { + struct netconn *netconn = (struct netconn *)pcb->callback_arg; +- struct lwip_sock *sock = get_socket(netconn->socket); ++ struct lwip_sock *sock = get_socket(netconn->callback_arg.socket); + + if (same_node_ring_create(&pcb->client_rx_ring, CLIENT_RING_SIZE, pcb->local_port, "client", "rx") != 0) { + goto END; +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 9e2197c..8b99e82 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -903,7 +903,7 @@ void stack_send(struct rpc_msg *msg) + return; + } + +- replenish_again = do_lwip_send(stack, sock->conn->socket, sock, len, 0); ++ replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0); + if (replenish_again < 0) { + __sync_fetch_and_sub(&sock->call_num, 1); + return; +@@ -1102,7 +1102,7 @@ int32_t stack_broadcast_close(int32_t fd) + if (sock == NULL || sock->conn == NULL) { + break; + } +- fd = sock->conn->socket; ++ fd = sock->conn->callback_arg.socket; + } while (sock); + + return ret; +@@ -1125,7 +1125,7 @@ int stack_broadcast_shutdown(int fd, int how) + if (sock == NULL || sock->conn == NULL) { + break; + } +- fd = sock->conn->socket; ++ fd = sock->conn->callback_arg.socket; + } while (sock); + + return ret; +@@ -1290,7 +1290,7 @@ int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *ad + } + + if (min_sock && min_sock->conn) { +- ret = rpc_call_accept(min_sock->conn->socket, addr, addrlen, flags); ++ ret = rpc_call_accept(min_sock->conn->callback_arg.socket, addr, addrlen, flags); + } + + if (min_sock && min_sock->wakeup && min_sock->wakeup->type == WAKEUP_EPOLL) { +-- +2.33.0 + diff --git a/0132-add-observable-method-of-data-aggregation.patch b/0132-add-observable-method-of-data-aggregation.patch new file mode 100644 index 0000000..b46fc91 --- /dev/null +++ b/0132-add-observable-method-of-data-aggregation.patch @@ -0,0 +1,62 @@ +From 36d2ddc58cd0f467d6d7682689cc10947a8a1973 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Tue, 6 Feb 2024 11:29:26 +0800 +Subject: [PATCH] add observable method of data aggregation + +--- + src/common/gazelle_dfx_msg.h | 2 ++ + src/lstack/core/lstack_lwip.c | 2 ++ + src/ltran/ltran_dfx.c | 4 +++- + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index d465efa..1ca210b 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -73,6 +73,8 @@ struct gazelle_stack_stat { + uint64_t tx; + uint64_t tx_prepare_fail; + uint64_t accept_fail; ++ uint64_t sock_rx_drop; ++ uint64_t sock_tx_merge; + }; + + struct gazelle_wakeup_stat { +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 63044c2..4523907 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -541,6 +541,7 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + + /* merge data into last pbuf */ + if (!NETCONN_IS_UDP(sock) && sock->remain_len) { ++ sock->stack->stats.sock_tx_merge++; + send_len = merge_data_lastpbuf(sock, (char *)buf, len); + if (send_len >= len) { + send_len = len; +@@ -1039,6 +1040,7 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + + /* in udp, if pbuf remaining len less than copy_len, discard these packets */ + if (recvd > 0 && NETCONN_IS_UDP(sock)) { ++ sock->stack->stats.sock_rx_drop++; + break; + } + } +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 4b246a1..9f12096 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -648,7 +648,9 @@ static void show_lstack_stats(struct gazelle_stack_dfx_data *lstack_stat) + printf("send_pkts_fail: %-13"PRIu64" ", lstack_stat->data.pkts.stack_stat.send_pkts_fail); + printf("mbuf_pool_freecnt: %-10"PRIu32" ", lstack_stat->data.pkts.mbufpool_avail_cnt); + printf("rpc_pool_freecnt: %-12"PRIu32" \n", lstack_stat->data.pkts.rpcpool_avail_cnt); +- printf("accpet_fail: %-12"PRIu64" \n", lstack_stat->data.pkts.stack_stat.accept_fail); ++ printf("accpet_fail: %-16"PRIu64" ", lstack_stat->data.pkts.stack_stat.accept_fail); ++ printf("sock_rx_drop: %-15"PRIu64" ", lstack_stat->data.pkts.stack_stat.sock_rx_drop); ++ printf("sock_tx_merge: %-16"PRIu64" \n", lstack_stat->data.pkts.stack_stat.sock_tx_merge); + } + + static void gazelle_print_lstack_stat_detail(struct gazelle_stack_dfx_data *lstack_stat, +-- +2.27.0 + diff --git a/0133-try-to-ensure-arp-packet-can-be-sent.patch b/0133-try-to-ensure-arp-packet-can-be-sent.patch new file mode 100644 index 0000000..ef48dd5 --- /dev/null +++ b/0133-try-to-ensure-arp-packet-can-be-sent.patch @@ -0,0 +1,191 @@ +From 1a7bb2f60a459c2cca6646ccbe04a52fcd8272f6 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Wed, 31 Jan 2024 14:49:40 +0800 +Subject: [PATCH] try to ensure arp packet can be sent + +--- + src/lstack/core/lstack_dpdk.c | 18 ++++++++++-------- + src/lstack/core/lstack_lwip.c | 13 ++++++++++--- + src/lstack/core/lstack_protocol_stack.c | 4 ++-- + src/lstack/include/lstack_dpdk.h | 2 +- + src/lstack/include/lstack_protocol_stack.h | 2 +- + src/lstack/netif/lstack_ethdev.c | 8 ++++---- + src/lstack/netif/lstack_vdev.c | 2 +- + 7 files changed, 29 insertions(+), 20 deletions(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index e352850..74e033b 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -280,14 +280,16 @@ int32_t create_shared_ring(struct protocol_stack *stack) + return 0; + } + +-int32_t dpdk_alloc_pktmbuf(struct rte_mempool *pool, struct rte_mbuf **mbufs, uint32_t num) ++int32_t dpdk_alloc_pktmbuf(struct rte_mempool *pool, struct rte_mbuf **mbufs, uint32_t num, bool reserve) + { +- /* +- * don't use rte_mempool_avail_count, it traverse cpu local cache, +- * when RTE_MAX_LCORE is too large, it's time-consuming +- */ +- if (rte_ring_count(pool->pool_data) < MBUFPOOL_RESERVE_NUM + num) { +- return -ENOMEM; ++ if (reserve) { ++ /* ++ * don't use rte_mempool_avail_count, it traverse cpu local cache, ++ * when RTE_MAX_LCORE is too large, it's time-consuming ++ */ ++ if (rte_ring_count(pool->pool_data) < MBUFPOOL_RESERVE_NUM + num) { ++ return -ENOMEM; ++ } + } + + int32_t ret = rte_pktmbuf_alloc_bulk(pool, mbufs, num); +@@ -310,7 +312,7 @@ int32_t fill_mbuf_to_ring(struct rte_mempool *mempool, struct rte_ring *ring, ui + while (remain > 0) { + batch = LWIP_MIN(remain, RING_SIZE(FREE_RX_QUEUE_SZ)); + +- ret = dpdk_alloc_pktmbuf(mempool, free_buf, batch); ++ ret = dpdk_alloc_pktmbuf(mempool, free_buf, batch, true); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "cannot alloc mbuf for ring, count: %u ret=%d\n", batch, ret); + return -1; +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 3f76424..da50fec 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -101,7 +102,6 @@ static struct pbuf *init_mbuf_to_pbuf(struct rte_mbuf *mbuf, pbuf_layer layer, u + struct pbuf *pbuf = pbuf_alloced_custom(layer, length, type, pbuf_custom, data, MAX_PACKET_SZ); + if (pbuf) { + pbuf->allow_in = 1; +- pbuf->last = pbuf; + pbuf->addr = *IP_ANY_TYPE; + pbuf->port = 0; + pthread_spin_init(&pbuf->pbuf_lock, PTHREAD_PROCESS_SHARED); +@@ -122,7 +122,7 @@ static bool replenish_send_idlembuf(struct protocol_stack *stack, struct lwip_so + return false; + } + +- if (dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, (struct rte_mbuf **)pbuf, replenish_cnt) != 0) { ++ if (dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, (struct rte_mbuf **)pbuf, replenish_cnt, true) != 0) { + stack->stats.tx_allocmbuf_fail++; + return true; + } +@@ -209,10 +209,17 @@ void do_lwip_free_pbuf(struct pbuf *pbuf) + + struct pbuf *do_lwip_alloc_pbuf(pbuf_layer layer, uint16_t length, pbuf_type type) + { ++ int ret; + struct rte_mbuf *mbuf; + struct protocol_stack *stack = get_protocol_stack(); + +- if (dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf, 1) != 0) { ++ /* ensure arp packet can be sent */ ++ if (layer == PBUF_LINK && length == SIZEOF_ETHARP_HDR) { ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf, 1, false); ++ } else { ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf, 1, true); ++ } ++ if (ret != 0) { + stack->stats.tx_allocmbuf_fail++; + return NULL; + } +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 8b99e82..cb39928 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -940,7 +940,7 @@ void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack + continue; + } + +- ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1); ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + if (ret != 0) { + stack->stats.rx_allocmbuf_fail++; + return; +@@ -952,7 +952,7 @@ void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack + return; + } + } +- ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1); ++ ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + if (ret != 0) { + cur_stack->stats.rx_allocmbuf_fail++; + return; +diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h +index b39d199..c40f3c0 100644 +--- a/src/lstack/include/lstack_dpdk.h ++++ b/src/lstack/include/lstack_dpdk.h +@@ -56,6 +56,6 @@ struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_mbuf, + uint32_t mbuf_cache_size, uint16_t queue_id, unsigned numa_id); + + void dpdk_nic_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id); +-int32_t dpdk_alloc_pktmbuf(struct rte_mempool *pool, struct rte_mbuf **mbufs, uint32_t num); ++int32_t dpdk_alloc_pktmbuf(struct rte_mempool *pool, struct rte_mbuf **mbufs, uint32_t num, bool reserve); + void dpdk_nic_features_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id); + #endif /* GAZELLE_DPDK_H */ +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index c681547..0a523b7 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -31,7 +31,7 @@ + #define SOCK_SEND_REPLENISH_THRES (16) + #define WAKEUP_MAX_NUM (32) + +-#define MBUFPOOL_RESERVE_NUM 5000 ++#define MBUFPOOL_RESERVE_NUM (get_global_cfg_params()->nic.rxqueue_size + 1024) + + struct rte_mempool; + struct rte_ring; +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 4d6f620..acf3c10 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -543,9 +543,9 @@ void parse_arp_and_transefer(char* buf) + int32_t ret; + for (int32_t i = 0; i < stack_group->stack_num; i++) { + stack = stack_group->stacks[i]; +- ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1); ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + while (ret != 0) { +- ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1); ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + stack->stats.rx_allocmbuf_fail++; + } + copy_mbuf(mbuf_copy, mbuf); +@@ -572,9 +572,9 @@ void parse_tcp_and_transefer(char* buf) + struct rte_mbuf *mbuf_copy = NULL; + struct protocol_stack *stack = stack_group->stacks[stk_index]; + +- int32_t ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1); ++ int32_t ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + while (ret != 0) { +- ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1); ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + stack->stats.rx_allocmbuf_fail++; + } + +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index fe17f59..f78e48a 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -59,7 +59,7 @@ static uint32_t ltran_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pk + stack->rx_ring_used += rcvd_pkts; + if (unlikely(stack->rx_ring_used >= USED_RX_PKTS_WATERMARK)) { + uint32_t free_cnt = LWIP_MIN(stack->rx_ring_used, RING_SIZE(DPDK_PKT_BURST_SIZE)); +- int32_t ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, (struct rte_mbuf **)free_buf, free_cnt); ++ int32_t ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, (struct rte_mbuf **)free_buf, free_cnt, true); + if (likely(ret == 0)) { + nr_pkts = gazelle_ring_sp_enqueue(stack->rx_ring, (void **)free_buf, free_cnt); + stack->rx_ring_used -= nr_pkts; +-- +2.27.0 + diff --git a/0134-gazellectl-support-send-latency-show.patch b/0134-gazellectl-support-send-latency-show.patch new file mode 100644 index 0000000..5950ca7 --- /dev/null +++ b/0134-gazellectl-support-send-latency-show.patch @@ -0,0 +1,345 @@ +From 03eabf12b7d486278598ad44d2b7d8e310ff0abf Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Sun, 4 Feb 2024 13:29:15 +0800 +Subject: [PATCH] gazellectl: support send latency show + +--- + src/common/dpdk_common.h | 10 +++ + src/common/gazelle_dfx_msg.h | 20 ++++- + src/lstack/core/lstack_lwip.c | 14 +++- + src/lstack/core/lstack_stack_stat.c | 15 ++-- + src/lstack/netif/lstack_ethdev.c | 4 + + src/ltran/ltran_dfx.c | 110 +++++++++++++++------------- + 6 files changed, 111 insertions(+), 62 deletions(-) + +diff --git a/src/common/dpdk_common.h b/src/common/dpdk_common.h +index 38f09ae..a79a0f2 100644 +--- a/src/common/dpdk_common.h ++++ b/src/common/dpdk_common.h +@@ -95,6 +95,16 @@ static __rte_always_inline void time_stamp_into_mbuf(uint32_t rx_count, struct r + } + } + ++static __rte_always_inline void time_stamp_into_pbuf(uint32_t tx_count, struct pbuf *buf[], uint64_t time_stamp) ++{ ++ struct latency_timestamp *lt; ++ for (uint32_t i = 0; i < tx_count; i++) { ++ lt = &pbuf_to_private(buf[i])->lt; ++ lt->stamp = time_stamp; ++ lt->check = ~(time_stamp); ++ } ++} ++ + bool get_kni_started(void); + struct rte_kni* get_gazelle_kni(void); + int32_t dpdk_kni_init(uint16_t port, struct rte_mempool *pool); +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index d465efa..d47ed9a 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -24,6 +24,10 @@ + /* maybe it should be consistent with MEMP_NUM_TCP_PCB */ + #define GAZELLE_LSTACK_MAX_CONN (20000 + 2000) // same as MAX_CLIENTS + RESERVED_CLIENTS in lwipopts.h + ++#define GAZELLE_RESULT_LEN 4096 ++#define GAZELLE_MAX_LATENCY_TIME 1800 // max latency time 30mins ++#define GAZELLE_RESULT_LINE_LEN 80 // for a single row, the max len of result is 80 ++ + enum GAZELLE_STAT_MODE { + GAZELLE_STAT_LTRAN_SHOW = 0, + GAZELLE_STAT_LTRAN_SHOW_RATE, +@@ -54,8 +58,11 @@ enum GAZELLE_STAT_MODE { + }; + + enum GAZELLE_LATENCY_TYPE { +- GAZELLE_LATENCY_LWIP, +- GAZELLE_LATENCY_READ, ++ GAZELLE_LATENCY_READ_LWIP, ++ GAZELLE_LATENCY_READ_LSTACK, ++ GAZELLE_LATENCY_WRITE_LWIP, ++ GAZELLE_LATENCY_WRITE_LSTACK, ++ GAZELLE_LATENCY_MAX, + }; + + struct gazelle_stack_stat { +@@ -216,9 +223,14 @@ struct stack_latency { + uint64_t latency_total; + }; + ++struct gazelle_latency_result { ++ int latency_stat_index; ++ struct stack_latency latency_stat_record; ++ char latency_stat_result[GAZELLE_RESULT_LEN]; ++}; ++ + struct gazelle_stack_latency { +- struct stack_latency read_latency; +- struct stack_latency lwip_latency; ++ struct stack_latency latency[GAZELLE_LATENCY_MAX]; + uint64_t start_time; + uint64_t g_cycles_per_us; + }; +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 22605dd..be2c6de 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -244,6 +244,11 @@ struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_s + if (pbuf == NULL) { + return NULL; + } ++ ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_WRITE_LWIP); ++ } ++ + sock->send_pre_del = pbuf; + + if (!gazelle_ring_readover_count(sock->send_ring)) { +@@ -303,6 +308,11 @@ static inline ssize_t app_buff_write(struct lwip_sock *sock, void *buf, size_t l + + (void)gazelle_ring_read(sock->send_ring, (void **)pbufs, write_num); + ++ if (get_protocol_stack_group()->latency_start) { ++ uint64_t time_stamp = get_current_time(); ++ time_stamp_into_pbuf(write_num, pbufs, time_stamp); ++ } ++ + ssize_t send_len = do_app_write(pbufs, buf, len, write_num); + + if (addr) { +@@ -573,7 +583,7 @@ ssize_t do_lwip_read_from_lwip(struct lwip_sock *sock, int32_t flags, u8_t apifl + + for (uint32_t i = 0; get_protocol_stack_group()->latency_start && i < read_count; i++) { + if (pbufs[i] != NULL) { +- calculate_lstack_latency(&sock->stack->latency, pbufs[i], GAZELLE_LATENCY_LWIP); ++ calculate_lstack_latency(&sock->stack->latency, pbufs[i], GAZELLE_LATENCY_READ_LWIP); + } + } + +@@ -895,7 +905,7 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + sock->wakeup->stat.app_read_cnt += 1; + } + if (latency_enable) { +- calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ); ++ calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK); + } + gazelle_ring_read_over(sock->recv_ring); + +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index 23571b4..cb11dc3 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -53,8 +53,9 @@ void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const + { + uint64_t latency; + const struct latency_timestamp *lt; ++ struct stack_latency *latency_stat; + +- if (pbuf == NULL) { ++ if (pbuf == NULL || type >= GAZELLE_LATENCY_MAX) { + return; + } + +@@ -62,10 +63,9 @@ void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const + if (lt->stamp != ~(lt->check) || lt->stamp < stack_latency->start_time) { + return; + } +- latency = get_current_time() - lt->stamp; + +- struct stack_latency *latency_stat = (type == GAZELLE_LATENCY_LWIP) ? +- &stack_latency->lwip_latency : &stack_latency->read_latency; ++ latency = get_current_time() - lt->stamp; ++ latency_stat = &stack_latency->latency[type]; + + latency_stat->latency_total += latency; + latency_stat->latency_max = (latency_stat->latency_max > latency) ? latency_stat->latency_max : latency; +@@ -118,8 +118,11 @@ static void set_latency_start_flag(bool start) + LSTACK_LOG(ERR, LSTACK, "memset_s faile\n"); + } + stack->latency.start_time = get_current_time(); +- stack->latency.lwip_latency.latency_min = ~((uint64_t)0); +- stack->latency.read_latency.latency_min = ~((uint64_t)0); ++ ++ for (uint32_t j = 0; j < GAZELLE_LATENCY_MAX; j++) { ++ stack->latency.latency[j].latency_min = ~((uint64_t)0); ++ } ++ + memset_s(&stack->aggregate_stats, sizeof(struct gazelle_stack_aggregate_stats), + 0, sizeof(stack->aggregate_stats)); + } +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 4d6f620..94ecffc 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -889,6 +889,10 @@ static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + + pre_mbuf = mbuf; + rte_mbuf_refcnt_update(mbuf, 1); ++ ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_lstack_latency(&stack->latency, pbuf, GAZELLE_LATENCY_WRITE_LSTACK); ++ } + pbuf = pbuf->next; + } + +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 4b246a1..ecdb5f9 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -50,9 +50,6 @@ + #define GAZELLE_CMD_MAX 5 + #define CMD_WAIT_TIME 1 // sec + +-#define GAZELLE_RESULT_LEN 8291 +-#define GAZELLE_MAX_LATENCY_TIME 1800 // max latency time 30mins +- + #define GAZELLE_DECIMAL 10 + #define GAZELLE_KEEPALIVE_STR_LEN 35 + #define GAZELLE_TIME_STR_LEN 25 +@@ -702,8 +699,8 @@ static void parse_thread_latency_result(const struct stack_latency *latency, cha + { + if (latency->latency_pkts > 0) { + *pos += sprintf_s(result + *pos, max_len, "%-8"PRIu64" ", latency->latency_pkts); +- *pos += sprintf_s(result + *pos, max_len, "%-6"PRIu64" ", latency->latency_min); +- *pos += sprintf_s(result + *pos, max_len, "%-6"PRIu64" ", latency->latency_max); ++ *pos += sprintf_s(result + *pos, max_len, "%-8"PRIu64" ", latency->latency_min); ++ *pos += sprintf_s(result + *pos, max_len, "%-8"PRIu64" ", latency->latency_max); + *pos += sprintf_s(result + *pos, max_len, "%-6.2f \n", + (double)latency->latency_total / latency->latency_pkts); + } else { +@@ -719,52 +716,53 @@ static void parse_thread_latency_result(const struct stack_latency *latency, cha + static void parse_latency_total_result(char *result, size_t max_len, int32_t *pos, + const struct stack_latency *record) + { ++ if (max_len < GAZELLE_RESULT_LINE_LEN) { ++ printf("total latency result show failed, out of memory bounds\n"); ++ return; ++ } ++ + if (record->latency_pkts > 0) { +- *pos += sprintf_s(result + *pos, max_len, " total: "); ++ *pos += sprintf_s(result + *pos, max_len, " total: "); + *pos += sprintf_s(result + *pos, max_len, "%-8"PRIu64" ", record->latency_pkts); +- *pos += sprintf_s(result + *pos, max_len, "%-6"PRIu64" ", record->latency_min); +- *pos += sprintf_s(result + *pos, max_len, "%-6"PRIu64" ", record->latency_max); +- *pos += sprintf_s(result + *pos, max_len, "%-6.2f \n\n\n", ++ *pos += sprintf_s(result + *pos, max_len, "%-8"PRIu64" ", record->latency_min); ++ *pos += sprintf_s(result + *pos, max_len, "%-8"PRIu64" ", record->latency_max); ++ *pos += sprintf_s(result + *pos, max_len, "%-6.2f \n\n", + (double)record->latency_total / record->latency_pkts); + } else { +- *pos += sprintf_s(result + *pos, max_len, " total: 0\n\n\n"); ++ *pos += sprintf_s(result + *pos, max_len, " total: 0\n\n"); + } + } + +-static void gazelle_print_lstack_stat_latency(void *buf, const struct gazelle_stat_msg_request *req_msg) ++static void gazelle_show_latency_result(const struct gazelle_stat_msg_request *req_msg, ++ struct gazelle_stack_dfx_data *stat, struct stack_latency *latency, ++ struct gazelle_latency_result *res) + { +- struct gazelle_stack_dfx_data *stat = (struct gazelle_stack_dfx_data *)buf; +- struct gazelle_stack_latency *latency = &stat->data.latency; +- int32_t ret = GAZELLE_OK; +- int32_t lwip_index = 0; +- int32_t read_index = 0; +- struct stack_latency lwip_record = {0}; +- struct stack_latency read_record = {0}; +- char str_ip[GAZELLE_SUBNET_LENGTH_MAX] = {0}; ++ char str_ip[GAZELLE_SUBNET_LENGTH_MAX] = { 0 }; + +- read_record.latency_min = ~((uint64_t)0); +- lwip_record.latency_min = ~((uint64_t)0); +- +- char *lwip_result = calloc(GAZELLE_RESULT_LEN, sizeof(char)); +- if (lwip_result == NULL) { +- return; +- } +- char *read_result = calloc(GAZELLE_RESULT_LEN, sizeof(char)); +- if (read_result == NULL) { +- free(lwip_result); ++ if (GAZELLE_RESULT_LEN - res->latency_stat_index < GAZELLE_RESULT_LINE_LEN) { ++ printf("too many threads show latency result, out of memory bounds\n"); + return; + } + +- do { +- lwip_index += sprintf_s(lwip_result + lwip_index, (size_t)(GAZELLE_RESULT_LEN - lwip_index), +- "ip: %-15s tid: %-8u ", inet_ntop(AF_INET, &req_msg->ip, str_ip, sizeof(str_ip)), stat->tid); +- parse_thread_latency_result(&latency->lwip_latency, lwip_result, (size_t)(GAZELLE_RESULT_LEN - lwip_index), +- &lwip_index, &lwip_record); ++ res->latency_stat_index += sprintf_s(res->latency_stat_result + res->latency_stat_index, ++ (size_t)(GAZELLE_RESULT_LEN - res->latency_stat_index), "ip: %-15s tid: %-8u ", ++ inet_ntop(AF_INET, &req_msg->ip, str_ip, sizeof(str_ip)), stat->tid); + +- read_index += sprintf_s(read_result + read_index, (size_t)(GAZELLE_RESULT_LEN - read_index), +- "ip: %-15s tid: %-8u ", inet_ntop(AF_INET, &req_msg->ip, str_ip, sizeof(str_ip)), stat->tid); +- parse_thread_latency_result(&latency->read_latency, read_result, (size_t)(GAZELLE_RESULT_LEN - read_index), +- &read_index, &read_record); ++ parse_thread_latency_result(latency, res->latency_stat_result, ++ (size_t)(GAZELLE_RESULT_LEN - res->latency_stat_index), &res->latency_stat_index, &res->latency_stat_record); ++} ++ ++static void gazelle_show_latency_result_total(void *buf, const struct gazelle_stat_msg_request *req_msg, ++ struct gazelle_latency_result *res) ++{ ++ int ret = GAZELLE_OK; ++ struct gazelle_stack_dfx_data *stat = (struct gazelle_stack_dfx_data *)buf; ++ struct gazelle_stack_latency *latency = &stat->data.latency; ++ ++ do { ++ for (int i = 0; i < GAZELLE_LATENCY_MAX; i++) { ++ gazelle_show_latency_result(req_msg, stat, &latency->latency[i], &res[i]); ++ } + + if ((stat->eof != 0) || (ret != GAZELLE_OK)) { + break; +@@ -772,21 +770,33 @@ static void gazelle_print_lstack_stat_latency(void *buf, const struct gazelle_st + ret = dfx_stat_read_from_ltran(buf, sizeof(struct gazelle_stack_dfx_data), req_msg->stat_mode); + } while (true); + +- parse_latency_total_result(lwip_result, (size_t)(GAZELLE_RESULT_LEN - lwip_index), &lwip_index, &lwip_record); +- parse_latency_total_result(read_result, (size_t)(GAZELLE_RESULT_LEN - read_index), &read_index, &read_record); ++ for (int i = 0; i < GAZELLE_LATENCY_MAX; i++) { ++ parse_latency_total_result(res[i].latency_stat_result, (size_t)(GAZELLE_RESULT_LEN - res[i].latency_stat_index), ++ &res[i].latency_stat_index, &res[i].latency_stat_record); ++ } ++} ++ ++static void gazelle_print_lstack_stat_latency(void *buf, const struct gazelle_stat_msg_request *req_msg) ++{ ++ struct gazelle_latency_result *res = calloc(GAZELLE_LATENCY_MAX, sizeof(struct gazelle_latency_result)); ++ if (res == NULL) { ++ return; ++ } ++ ++ for (int i = 0; i < GAZELLE_LATENCY_MAX; i++) { ++ res[i].latency_stat_record.latency_min = ~((uint64_t)0); ++ } + +- printf("Statistics of lstack latency: t0--->t3 \ +- (t0:read form nic t1:into lstask queue t2:into app queue t3:app read)\n"); +- printf(" pkts min(us) max(us) average(us)\n%s", +- read_result); ++ gazelle_show_latency_result_total(buf, req_msg, res); + +- printf("Statistics of lstack latency: t0--->t2 \ +- (t0:read form nic t1:into lstask queue t2:into app queue t3:app read)\n"); +- printf(" pkts min(us) max(us) average(us)\n%s", +- lwip_result); ++ printf("Statistics of lstack latency pkts min(us) max(us) average(us)\n"); ++ printf("range: t0--->t3\n%s", res[GAZELLE_LATENCY_READ_LSTACK].latency_stat_result); ++ printf("range: t0--->t2\n%s", res[GAZELLE_LATENCY_READ_LWIP].latency_stat_result); ++ printf("range: t3--->t0\n%s", res[GAZELLE_LATENCY_WRITE_LSTACK].latency_stat_result); ++ printf("range: t2--->t0\n%s", res[GAZELLE_LATENCY_WRITE_LWIP].latency_stat_result); ++ printf("t0:read form/send to nic t1:into/out of lstask queue t2:into/out of app queue t3:app read/send\n"); + +- free(read_result); +- free(lwip_result); ++ free(res); + } + + static void gazelle_print_lstack_stat_lpm(void *buf, const struct gazelle_stat_msg_request *req_msg) +-- +2.27.0 + diff --git a/0135-rpc-function-does-not-depend-on-protocol-stack.patch b/0135-rpc-function-does-not-depend-on-protocol-stack.patch new file mode 100644 index 0000000..1ca8ca5 --- /dev/null +++ b/0135-rpc-function-does-not-depend-on-protocol-stack.patch @@ -0,0 +1,1336 @@ +From fe39b43f897be7d29f9b51e79d51395e43b83e23 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sun, 4 Feb 2024 19:46:17 +0800 +Subject: [PATCH] rpc function does not depend on protocol stack diff rpc queue + and dfx rpc queue + +--- + src/common/gazelle_dfx_msg.h | 1 - + src/lstack/api/lstack_rtw_api.c | 36 ++- + src/lstack/core/lstack_control_plane.c | 10 +- + src/lstack/core/lstack_dpdk.c | 4 +- + src/lstack/core/lstack_lwip.c | 2 +- + src/lstack/core/lstack_protocol_stack.c | 92 ++++---- + src/lstack/core/lstack_stack_stat.c | 18 +- + src/lstack/core/lstack_thread_rpc.c | 241 ++++++++------------- + src/lstack/include/lstack_control_plane.h | 3 - + src/lstack/include/lstack_protocol_stack.h | 36 +-- + src/lstack/include/lstack_rpc_proc.h | 46 ++++ + src/lstack/include/lstack_thread_rpc.h | 79 +++---- + src/lstack/netif/lstack_ethdev.c | 6 +- + src/ltran/ltran_dfx.c | 3 +- + 14 files changed, 292 insertions(+), 285 deletions(-) + create mode 100644 src/lstack/include/lstack_rpc_proc.h + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 1ca210b..a91a30f 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -101,7 +101,6 @@ struct gazelle_stack_aggregate_stats { + struct gazelle_stat_pkts { + uint16_t conn_num; + uint32_t mbufpool_avail_cnt; +- uint32_t rpcpool_avail_cnt; + uint64_t call_msg_cnt; + uint64_t recv_list_cnt; + uint64_t call_alloc_fail; +diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c +index 10bc613..8498b8e 100644 +--- a/src/lstack/api/lstack_rtw_api.c ++++ b/src/lstack/api/lstack_rtw_api.c +@@ -28,7 +28,11 @@ + + int rtw_socket(int domain, int type, int protocol) + { +- return rpc_call_socket(domain, type, protocol); ++ struct protocol_stack *stack = get_bind_protocol_stack(); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EINVAL); ++ } ++ return rpc_call_socket(&stack->rpc_queue, domain, type, protocol); + } + + int rtw_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +@@ -64,27 +68,47 @@ int rtw_listen(int s, int backlog) + + int rtw_connect(int s, const struct sockaddr *name, socklen_t namelen) + { +- return rpc_call_connect(s, name, namelen); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(s); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_connect(&stack->rpc_queue, s, name, namelen); + } + + int rtw_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) + { +- return rpc_call_setsockopt(s, level, optname, optval, optlen); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(s); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_setsockopt(&stack->rpc_queue, s, level, optname, optval, optlen); + } + + int rtw_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) + { +- return rpc_call_getsockopt(s, level, optname, optval, optlen); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(s); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_getsockopt(&stack->rpc_queue, s, level, optname, optval, optlen); + } + + int rtw_getpeername(int s, struct sockaddr *name, socklen_t *namelen) + { +- return rpc_call_getpeername(s, name, namelen); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(s); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_getpeername(&stack->rpc_queue, s, name, namelen); + } + + int rtw_getsockname(int s, struct sockaddr *name, socklen_t *namelen) + { +- return rpc_call_getsockname(s, name, namelen); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(s); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_getsockname(&stack->rpc_queue, s, name, namelen); + } + + ssize_t rtw_read(int s, void *mem, size_t len) +diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c +index a9a3814..025291d 100644 +--- a/src/lstack/core/lstack_control_plane.c ++++ b/src/lstack/core/lstack_control_plane.c +@@ -611,9 +611,10 @@ static int32_t thread_register(void) + /* register all connected conn before listen conn, avoid creating new conn */ + struct protocol_stack_group *stack_group = get_protocol_stack_group(); + for (int32_t i = 0; i < stack_group->stack_num; i++) { +- conn->conn_num = rpc_call_conntable(stack_group->stacks[i], conn->conn_list, GAZELLE_LSTACK_MAX_CONN); ++ conn->conn_num = rpc_call_conntable(&stack_group->stacks[i]->rpc_queue, ++ conn->conn_list, GAZELLE_LSTACK_MAX_CONN); + +- ret = rpc_call_thread_regphase1(stack_group->stacks[i], conn); ++ ret = rpc_call_thread_regphase1(&stack_group->stacks[i]->rpc_queue, conn); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "thread_register_phase1 failed ret=%d!\n", ret); + free(conn); +@@ -622,9 +623,10 @@ static int32_t thread_register(void) + } + + for (int32_t i = 0; i < stack_group->stack_num; i++) { +- conn->conn_num = rpc_call_conntable(stack_group->stacks[i], conn->conn_list, GAZELLE_LSTACK_MAX_CONN); ++ conn->conn_num = rpc_call_conntable(&stack_group->stacks[i]->rpc_queue, ++ conn->conn_list, GAZELLE_LSTACK_MAX_CONN); + +- ret = rpc_call_thread_regphase2(stack_group->stacks[i], conn); ++ ret = rpc_call_thread_regphase2(&stack_group->stacks[i]->rpc_queue, conn); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "thread_register_phase2 failed ret=%d!\n", ret); + free(conn); +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index e352850..985f1a5 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -45,7 +45,6 @@ + + #include "lstack_log.h" + #include "dpdk_common.h" +-#include "lstack_lockless_queue.h" + #include "lstack_protocol_stack.h" + #include "lstack_thread_rpc.h" + #include "lstack_lwip.h" +@@ -258,7 +257,8 @@ struct rte_mempool *create_mempool(const char *name, uint32_t count, uint32_t si + + int32_t create_shared_ring(struct protocol_stack *stack) + { +- lockless_queue_init(&stack->rpc_queue); ++ rpc_queue_init(&stack->rpc_queue); ++ rpc_queue_init(&stack->dfx_rpc_queue); + + if (use_ltran()) { + stack->rx_ring = gazelle_ring_create_fast("RING_RX", VDEV_RX_QUEUE_SZ, RING_F_SP_ENQ | RING_F_SC_DEQ); +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 3f76424..b79cdef 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -636,7 +636,7 @@ static inline void notice_stack_send(struct lwip_sock *sock, int32_t fd, int32_t + { + // 2: call_num >= 2, don't need add new rpc send + if (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) < 2) { +- while (rpc_call_send(fd, NULL, len, flags) < 0) { ++ while (rpc_call_send(&sock->stack->rpc_queue, fd, NULL, len, flags) < 0) { + usleep(1000); // 1000: wait 1ms to exec again + } + __sync_fetch_and_add(&sock->call_num, 1); +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 8b99e82..f63fcb0 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -465,7 +465,10 @@ int stack_polling(uint32_t wakeup_tick) + uint32_t read_connect_number = cfg->read_connect_number; + struct protocol_stack *stack = get_protocol_stack(); + +- force_quit = poll_rpc_msg(stack, rpc_number); ++ /* 2: one dfx consumes two rpc */ ++ rpc_poll_msg(&stack->dfx_rpc_queue, 2); ++ force_quit = rpc_poll_msg(&stack->rpc_queue, rpc_number); ++ + gazelle_eth_dev_poll(stack, use_ltran_flag, nic_read_number); + sys_timer_run(); + if (cfg->low_power_mod != 0) { +@@ -715,7 +718,7 @@ OUT2: + void stack_arp(struct rpc_msg *msg) + { + struct rte_mbuf *mbuf = (struct rte_mbuf *)msg->args[MSG_ARG_0].p; +- struct protocol_stack *stack = (struct protocol_stack*)msg->args[MSG_ARG_1].p; ++ struct protocol_stack *stack = get_protocol_stack(); + + eth_dev_recv(mbuf, stack); + } +@@ -893,7 +896,7 @@ void stack_send(struct rpc_msg *msg) + { + int32_t fd = msg->args[MSG_ARG_0].i; + size_t len = msg->args[MSG_ARG_1].size; +- struct protocol_stack *stack = (struct protocol_stack *)msg->args[MSG_ARG_3].p; ++ struct protocol_stack *stack = get_protocol_stack(); + int replenish_again; + + struct lwip_sock *sock = get_socket(fd); +@@ -947,7 +950,7 @@ void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack + } + copy_mbuf(mbuf_copy, mbuf); + +- ret = rpc_call_arp(stack, mbuf_copy); ++ ret = rpc_call_arp(&stack->rpc_queue, mbuf_copy); + if (ret != 0) { + return; + } +@@ -971,7 +974,7 @@ void stack_broadcast_clean_epoll(struct wakeup_poll *wakeup) + + for (int32_t i = 0; i < stack_group->stack_num; i++) { + stack = stack_group->stacks[i]; +- rpc_call_clean_epoll(stack, wakeup); ++ rpc_call_clean_epoll(&stack->rpc_queue, wakeup); + } + } + +@@ -985,17 +988,11 @@ void stack_clean_epoll(struct rpc_msg *msg) + + void stack_mempool_size(struct rpc_msg *msg) + { +- struct protocol_stack *stack = (struct protocol_stack*)msg->args[MSG_ARG_0].p; ++ struct protocol_stack *stack = get_protocol_stack(); + + msg->result = rte_mempool_avail_count(stack->rxtx_mbuf_pool); + } + +-void stack_rpcpool_size(struct rpc_msg *msg) +-{ +- struct rpc_msg_pool *rpc_mem_pool = (struct rpc_msg_pool*)msg->args[MSG_ARG_0].p; +- msg->result = rte_mempool_avail_count(rpc_mem_pool->mempool); +-} +- + void stack_create_shadow_fd(struct rpc_msg *msg) + { + int32_t fd = msg->args[MSG_ARG_0].i; +@@ -1049,8 +1046,8 @@ void stack_create_shadow_fd(struct rpc_msg *msg) + + void stack_replenish_sendring(struct rpc_msg *msg) + { +- struct protocol_stack *stack = (struct protocol_stack *)msg->args[MSG_ARG_0].p; +- struct lwip_sock *sock = (struct lwip_sock *)msg->args[MSG_ARG_1].p; ++ struct protocol_stack *stack = get_protocol_stack(); ++ struct lwip_sock *sock = (struct lwip_sock *)msg->args[MSG_ARG_0].p; + + msg->result = do_lwip_replenish_sendring(stack, sock); + } +@@ -1070,7 +1067,7 @@ void stack_get_connnum(struct rpc_msg *msg) + + void stack_recvlist_count(struct rpc_msg *msg) + { +- struct protocol_stack *stack = (struct protocol_stack *)msg->args[MSG_ARG_0].p; ++ struct protocol_stack *stack = get_protocol_stack(); + struct list_node *list = &stack->recv_list; + uint32_t count = 0; + struct list_node *node; +@@ -1086,16 +1083,16 @@ void stack_recvlist_count(struct rpc_msg *msg) + /* when fd is listenfd, listenfd of all protocol stack thread will be closed */ + int32_t stack_broadcast_close(int32_t fd) + { +- struct lwip_sock *sock = get_socket(fd); + int32_t ret = 0; +- ++ struct lwip_sock *sock = get_socket(fd); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); + if (sock == NULL) { +- return -1; ++ GAZELLE_RETURN(EBADF); + } + + do { + sock = sock->listen_next; +- if (rpc_call_close(fd)) { ++ if (stack == NULL || rpc_call_close(&stack->rpc_queue, fd)) { + ret = -1; + } + +@@ -1103,7 +1100,8 @@ int32_t stack_broadcast_close(int32_t fd) + break; + } + fd = sock->conn->callback_arg.socket; +- } while (sock); ++ stack = get_protocol_stack_by_fd(fd); ++ } while (1); + + return ret; + } +@@ -1112,13 +1110,14 @@ int stack_broadcast_shutdown(int fd, int how) + { + int32_t ret = 0; + struct lwip_sock *sock = get_socket(fd); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); + if (sock == NULL) { +- return -1; ++ GAZELLE_RETURN(EBADF); + } + + do { + sock = sock->listen_next; +- if (rpc_call_shutdown(fd, how)) { ++ if (stack == NULL || rpc_call_shutdown(&stack->rpc_queue, fd, how)) { + ret = -1; + } + +@@ -1126,7 +1125,8 @@ int stack_broadcast_shutdown(int fd, int how) + break; + } + fd = sock->conn->callback_arg.socket; +- } while (sock); ++ stack = get_protocol_stack_by_fd(fd); ++ } while (1); + + return ret; + } +@@ -1134,7 +1134,11 @@ int stack_broadcast_shutdown(int fd, int how) + /* choice one stack listen */ + int32_t stack_single_listen(int32_t fd, int32_t backlog) + { +- return rpc_call_listen(fd, backlog); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_listen(&stack->rpc_queue, fd, backlog); + } + + /* listen sync to all protocol stack thread, so that any protocol stack thread can build connect */ +@@ -1153,12 +1157,12 @@ int32_t stack_broadcast_listen(int32_t fd, int32_t backlog) + int32_t ret, clone_fd; + + struct lwip_sock *sock = get_socket(fd); +- if (sock == NULL) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, %d get sock null\n", get_stack_tid(), fd); +- GAZELLE_RETURN(EINVAL); ++ if (sock == NULL || cur_stack == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, %d get sock null or stack null\n", get_stack_tid(), fd); ++ GAZELLE_RETURN(EBADF); + } + +- ret = rpc_call_getsockname(fd, (struct sockaddr *)&addr, &addr_len); ++ ret = rpc_call_getsockname(&cur_stack->rpc_queue, fd, (struct sockaddr *)&addr, &addr_len); + if (ret != 0) { + return ret; + } +@@ -1172,7 +1176,7 @@ int32_t stack_broadcast_listen(int32_t fd, int32_t backlog) + continue; + } + if (stack != cur_stack) { +- clone_fd = rpc_call_shadow_fd(stack, fd, (struct sockaddr *)&addr, addr_len); ++ clone_fd = rpc_call_shadow_fd(&stack->rpc_queue, fd, (struct sockaddr *)&addr, addr_len); + if (clone_fd < 0) { + stack_broadcast_close(fd); + return clone_fd; +@@ -1187,7 +1191,7 @@ int32_t stack_broadcast_listen(int32_t fd, int32_t backlog) + get_socket_by_fd(clone_fd)->conn->is_master_fd = 0; + } + +- ret = rpc_call_listen(clone_fd, backlog); ++ ret = rpc_call_listen(&stack->rpc_queue, clone_fd, backlog); + if (ret < 0) { + stack_broadcast_close(fd); + return ret; +@@ -1234,7 +1238,11 @@ static void inline del_accept_in_event(struct lwip_sock *sock) + /* choice one stack bind */ + int32_t stack_single_bind(int32_t fd, const struct sockaddr *name, socklen_t namelen) + { +- return rpc_call_bind(fd, name, namelen); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_bind(&stack->rpc_queue, fd, name, namelen); + } + + /* bind sync to all protocol stack thread, so that any protocol stack thread can build connect */ +@@ -1245,12 +1253,12 @@ int32_t stack_broadcast_bind(int32_t fd, const struct sockaddr *name, socklen_t + int32_t ret, clone_fd; + + struct lwip_sock *sock = get_socket(fd); +- if (sock == NULL) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, %d get sock null\n", get_stack_tid(), fd); +- GAZELLE_RETURN(EINVAL); ++ if (sock == NULL || cur_stack == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, %d get sock null or stack null\n", get_stack_tid(), fd); ++ GAZELLE_RETURN(EBADF); + } + +- ret = rpc_call_bind(fd, name, namelen); ++ ret = rpc_call_bind(&cur_stack->rpc_queue, fd, name, namelen); + if (ret < 0) { + close(fd); + return ret; +@@ -1260,7 +1268,7 @@ int32_t stack_broadcast_bind(int32_t fd, const struct sockaddr *name, socklen_t + for (int32_t i = 0; i < stack_group->stack_num; ++i) { + stack = stack_group->stacks[i]; + if (stack != cur_stack) { +- clone_fd = rpc_call_shadow_fd(stack, fd, name, namelen); ++ clone_fd = rpc_call_shadow_fd(&stack->rpc_queue, fd, name, namelen); + if (clone_fd < 0) { + stack_broadcast_close(fd); + return clone_fd; +@@ -1276,9 +1284,9 @@ int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *ad + int32_t ret = -1; + struct lwip_sock *min_sock = NULL; + struct lwip_sock *sock = get_socket(fd); ++ struct protocol_stack *stack = NULL; + if (sock == NULL) { +- errno = EINVAL; +- return -1; ++ GAZELLE_RETURN(EBADF); + } + + if (netconn_is_nonblocking(sock->conn)) { +@@ -1290,7 +1298,11 @@ int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *ad + } + + if (min_sock && min_sock->conn) { +- ret = rpc_call_accept(min_sock->conn->callback_arg.socket, addr, addrlen, flags); ++ stack = get_protocol_stack_by_fd(min_sock->conn->callback_arg.socket); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ ret = rpc_call_accept(&stack->rpc_queue, min_sock->conn->callback_arg.socket, addr, addrlen, flags); + } + + if (min_sock && min_sock->wakeup && min_sock->wakeup->type == WAKEUP_EPOLL) { +@@ -1344,7 +1356,7 @@ void stack_group_exit(void) + } + + if (stack != stack_group->stacks[i]) { +- rpc_call_stack_exit(stack_group->stacks[i]); ++ rpc_call_stack_exit(&stack_group->stacks[i]->rpc_queue); + } + } + +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index 23571b4..01ac6fb 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -175,20 +175,17 @@ static void get_stack_stats(struct gazelle_stack_dfx_data *dfx, struct protocol_ + + get_wakeup_stat(stack_group, stack, &dfx->data.pkts.wakeup_stat); + +- dfx->data.pkts.call_alloc_fail = stack_group->call_alloc_fail; ++ dfx->data.pkts.call_alloc_fail = rpc_stats_get()->call_alloc_fail; + +- int32_t rpc_call_result = rpc_call_msgcnt(stack); ++ int32_t rpc_call_result = rpc_msgcnt(&stack->rpc_queue); + dfx->data.pkts.call_msg_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result; + +- rpc_call_result = rpc_call_mbufpoolsize(stack); ++ rpc_call_result = rpc_call_mbufpoolsize(&stack->dfx_rpc_queue); + dfx->data.pkts.mbufpool_avail_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result; + +- rpc_call_result = rpc_call_recvlistcnt(stack); ++ rpc_call_result = rpc_call_recvlistcnt(&stack->dfx_rpc_queue); + dfx->data.pkts.recv_list_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result; + +- rpc_call_result = rpc_call_rpcpool_size(stack); +- dfx->data.pkts.rpcpool_avail_cnt = (rpc_call_result < 0) ? 0 : rpc_call_result; +- + dfx->data.pkts.conn_num = stack->conn_num; + } + +@@ -219,9 +216,10 @@ static void get_stack_dfx_data(struct gazelle_stack_dfx_data *dfx, struct protoc + } + break; + case GAZELLE_STAT_LSTACK_SHOW_CONN: +- rpc_call_result = rpc_call_conntable(stack, dfx->data.conn.conn_list, GAZELLE_LSTACK_MAX_CONN); ++ rpc_call_result = rpc_call_conntable(&stack->dfx_rpc_queue, dfx->data.conn.conn_list, ++ GAZELLE_LSTACK_MAX_CONN); + dfx->data.conn.conn_num = (rpc_call_result < 0) ? 0 : rpc_call_result; +- rpc_call_result = rpc_call_connnum(stack); ++ rpc_call_result = rpc_call_connnum(&stack->dfx_rpc_queue); + dfx->data.conn.total_conn_num = (rpc_call_result < 0) ? 0 : rpc_call_result; + break; + case GAZELLE_STAT_LSTACK_SHOW_LATENCY: +@@ -296,7 +294,7 @@ int handle_stack_cmd(int fd, enum GAZELLE_STAT_MODE stat_mode) + } + + dfx.tid = stack->tid; +- dfx.stack_id = i; ++ dfx.stack_id = i; + if (i == stack_group->stack_num - 1) { + dfx.eof = 1; + } +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index 2af30d7..1fdb037 100644 +--- a/src/lstack/core/lstack_thread_rpc.c ++++ b/src/lstack/core/lstack_thread_rpc.c +@@ -9,21 +9,20 @@ + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ +-#include +-#include + #include +-#include + #include + + #include "lstack_log.h" +-#include "lstack_lwip.h" +-#include "lstack_protocol_stack.h" +-#include "lstack_control_plane.h" +-#include "gazelle_base_func.h" + #include "lstack_dpdk.h" ++#include "lstack_rpc_proc.h" + #include "lstack_thread_rpc.h" + + static PER_THREAD struct rpc_msg_pool *g_rpc_pool = NULL; ++static struct rpc_stats g_rpc_stats; ++struct rpc_stats *rpc_stats_get(void) ++{ ++ return &g_rpc_stats; ++} + + static inline __attribute__((always_inline)) struct rpc_msg *get_rpc_msg(struct rpc_msg_pool *rpc_pool) + { +@@ -37,33 +36,29 @@ static inline __attribute__((always_inline)) struct rpc_msg *get_rpc_msg(struct + return msg; + } + +-static struct rpc_msg *rpc_msg_alloc(struct protocol_stack *stack, rpc_msg_func func) ++static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) + { + struct rpc_msg *msg = NULL; + +- if (stack == NULL) { +- return NULL; +- } +- + if (g_rpc_pool == NULL) { + g_rpc_pool = calloc(1, sizeof(struct rpc_msg_pool)); + if (g_rpc_pool == NULL) { + LSTACK_LOG(INFO, LSTACK, "g_rpc_pool calloc failed\n"); +- get_protocol_stack_group()->call_alloc_fail++; ++ g_rpc_stats.call_alloc_fail++; + return NULL; + } + + g_rpc_pool->mempool = create_mempool("rpc_pool", RPC_MSG_MAX, sizeof(struct rpc_msg), + 0, rte_gettid()); + if (g_rpc_pool->mempool == NULL) { +- get_protocol_stack_group()->call_alloc_fail++; ++ g_rpc_stats.call_alloc_fail++; + return NULL; + } + } + + msg = get_rpc_msg(g_rpc_pool); + if (msg == NULL) { +- get_protocol_stack_group()->call_alloc_fail++; ++ g_rpc_stats.call_alloc_fail++; + return NULL; + } + msg->rpcpool = g_rpc_pool; +@@ -75,7 +70,7 @@ static struct rpc_msg *rpc_msg_alloc(struct protocol_stack *stack, rpc_msg_func + return msg; + } + +-static inline __attribute__((always_inline)) int32_t rpc_sync_call(lockless_queue *queue, struct rpc_msg *msg) ++static inline __attribute__((always_inline)) int32_t rpc_sync_call(rpc_queue *queue, struct rpc_msg *msg) + { + int32_t ret; + +@@ -90,13 +85,18 @@ static inline __attribute__((always_inline)) int32_t rpc_sync_call(lockless_queu + return ret; + } + +-int poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num) ++int32_t rpc_msgcnt(rpc_queue *queue) ++{ ++ return lockless_queue_count(queue); ++} ++ ++int rpc_poll_msg(rpc_queue *queue, uint32_t max_num) + { + int force_quit = 0; + struct rpc_msg *msg = NULL; + + while (max_num--) { +- lockless_queue_node *node = lockless_queue_mpsc_pop(&stack->rpc_queue); ++ lockless_queue_node *node = lockless_queue_mpsc_pop(queue); + if (node == NULL) { + break; + } +@@ -106,7 +106,7 @@ int poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num) + if (msg->func) { + msg->func(msg); + } else { +- stack->stats.call_null++; ++ g_rpc_stats.call_null++; + } + + if (msg->func == stack_exit_by_rpc) { +@@ -127,9 +127,9 @@ int poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num) + return force_quit; + } + +-int32_t rpc_call_conntable(struct protocol_stack *stack, void *conn_table, uint32_t max_conn) ++int32_t rpc_call_conntable(rpc_queue *queue, void *conn_table, uint32_t max_conn) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_get_conntable); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_get_conntable); + if (msg == NULL) { + return -1; + } +@@ -137,22 +137,22 @@ int32_t rpc_call_conntable(struct protocol_stack *stack, void *conn_table, uint3 + msg->args[MSG_ARG_0].p = conn_table; + msg->args[MSG_ARG_1].u = max_conn; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_connnum(struct protocol_stack *stack) ++int32_t rpc_call_connnum(rpc_queue *queue) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_get_connnum); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_get_connnum); + if (msg == NULL) { + return -1; + } + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_shadow_fd(struct protocol_stack *stack, int32_t fd, const struct sockaddr *addr, socklen_t addrlen) ++int32_t rpc_call_shadow_fd(rpc_queue *queue, int32_t fd, const struct sockaddr *addr, socklen_t addrlen) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_create_shadow_fd); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_create_shadow_fd); + if (msg == NULL) { + return -1; + } +@@ -161,100 +161,67 @@ int32_t rpc_call_shadow_fd(struct protocol_stack *stack, int32_t fd, const struc + msg->args[MSG_ARG_1].cp = addr; + msg->args[MSG_ARG_2].socklen = addrlen; + +- return rpc_sync_call(&stack->rpc_queue, msg); +-} +- +-static void rpc_msgcnt(struct rpc_msg *msg) +-{ +- struct protocol_stack *stack = get_protocol_stack(); +- msg->result = lockless_queue_count(&stack->rpc_queue); +-} +- +-int32_t rpc_call_msgcnt(struct protocol_stack *stack) +-{ +- struct rpc_msg *msg = rpc_msg_alloc(stack, rpc_msgcnt); +- if (msg == NULL) { +- return -1; +- } +- +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_thread_regphase1(struct protocol_stack *stack, void *conn) ++int32_t rpc_call_thread_regphase1(rpc_queue *queue, void *conn) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, thread_register_phase1); ++ struct rpc_msg *msg = rpc_msg_alloc(thread_register_phase1); + if (msg == NULL) { + return -1; + } + msg->args[MSG_ARG_0].p = conn; +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_thread_regphase2(struct protocol_stack *stack, void *conn) ++int32_t rpc_call_thread_regphase2(rpc_queue *queue, void *conn) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, thread_register_phase2); ++ struct rpc_msg *msg = rpc_msg_alloc(thread_register_phase2); + if (msg == NULL) { + return -1; + } + msg->args[MSG_ARG_0].p = conn; +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_mbufpoolsize(struct protocol_stack *stack) ++int32_t rpc_call_mbufpoolsize(rpc_queue *queue) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_mempool_size); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_mempool_size); + if (msg == NULL) { + return -1; + } + +- msg->args[MSG_ARG_0].p = stack; +- +- return rpc_sync_call(&stack->rpc_queue, msg); +-} +- +-int32_t rpc_call_rpcpool_size(struct protocol_stack *stack) +-{ +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_rpcpool_size); +- if (msg == NULL) { +- return -1; +- } +- msg->args[MSG_ARG_0].p = g_rpc_pool; +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_recvlistcnt(struct protocol_stack *stack) ++int32_t rpc_call_recvlistcnt(rpc_queue *queue) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_recvlist_count); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_recvlist_count); + if (msg == NULL) { + return -1; + } + +- msg->args[MSG_ARG_0].p = stack; +- +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_arp(struct protocol_stack *stack, struct rte_mbuf *mbuf) ++int32_t rpc_call_arp(rpc_queue *queue, void *mbuf) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_arp); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_arp); + if (msg == NULL) { + return -1; + } + + msg->sync_flag = 0; + msg->args[MSG_ARG_0].p = mbuf; +- msg->args[MSG_ARG_1].p = stack; + +- rpc_call(&stack->rpc_queue, msg); ++ rpc_call(queue, msg); + + return 0; + } + +-int32_t rpc_call_socket(int32_t domain, int32_t type, int32_t protocol) ++int32_t rpc_call_socket(rpc_queue *queue, int32_t domain, int32_t type, int32_t protocol) + { +- struct protocol_stack *stack = get_bind_protocol_stack(); +- +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_socket); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_socket); + if (msg == NULL) { + return -1; + } +@@ -263,39 +230,35 @@ int32_t rpc_call_socket(int32_t domain, int32_t type, int32_t protocol) + msg->args[MSG_ARG_1].i = type; + msg->args[MSG_ARG_2].i = protocol; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_close(int fd) ++int32_t rpc_call_close(rpc_queue *queue, int fd) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_close); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_close); + if (msg == NULL) { + return -1; + } + + msg->args[MSG_ARG_0].i = fd; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_stack_exit(struct protocol_stack *stack) ++int32_t rpc_call_stack_exit(rpc_queue *queue) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_exit_by_rpc); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_exit_by_rpc); + if (msg == NULL) { +- LSTACK_LOG(INFO, LSTACK, "rpc msg alloc failed\n"); + return -1; + } + +- rpc_call(&stack->rpc_queue, msg); ++ rpc_call(queue, msg); + return 0; + } + +-int32_t rpc_call_shutdown(int fd, int how) ++int32_t rpc_call_shutdown(rpc_queue *queue, int fd, int how) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_shutdown); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_shutdown); + if (msg == NULL) { + return -1; + } +@@ -303,25 +266,24 @@ int32_t rpc_call_shutdown(int fd, int how) + msg->args[MSG_ARG_0].i = fd; + msg->args[MSG_ARG_1].i = how; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-void rpc_call_clean_epoll(struct protocol_stack *stack, struct wakeup_poll *wakeup) ++void rpc_call_clean_epoll(rpc_queue *queue, void *wakeup) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_clean_epoll); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_clean_epoll); + if (msg == NULL) { + return; + } + + msg->args[MSG_ARG_0].p = wakeup; + +- rpc_sync_call(&stack->rpc_queue, msg); ++ rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_bind(int32_t fd, const struct sockaddr *addr, socklen_t addrlen) ++int32_t rpc_call_bind(rpc_queue *queue, int32_t fd, const struct sockaddr *addr, socklen_t addrlen) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_bind); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_bind); + if (msg == NULL) { + return -1; + } +@@ -330,13 +292,12 @@ int32_t rpc_call_bind(int32_t fd, const struct sockaddr *addr, socklen_t addrlen + msg->args[MSG_ARG_1].cp = addr; + msg->args[MSG_ARG_2].socklen = addrlen; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_listen(int s, int backlog) ++int32_t rpc_call_listen(rpc_queue *queue, int s, int backlog) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(s); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_listen); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_listen); + if (msg == NULL) { + return -1; + } +@@ -344,13 +305,12 @@ int32_t rpc_call_listen(int s, int backlog) + msg->args[MSG_ARG_0].i = s; + msg->args[MSG_ARG_1].i = backlog; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags) ++int32_t rpc_call_accept(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_accept); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_accept); + if (msg == NULL) { + return -1; + } +@@ -360,13 +320,12 @@ int32_t rpc_call_accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int f + msg->args[MSG_ARG_2].p = addrlen; + msg->args[MSG_ARG_3].i = flags; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_connect(int fd, const struct sockaddr *addr, socklen_t addrlen) ++int32_t rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_connect); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_connect); + if (msg == NULL) { + return -1; + } +@@ -375,7 +334,7 @@ int32_t rpc_call_connect(int fd, const struct sockaddr *addr, socklen_t addrlen) + msg->args[MSG_ARG_1].cp = addr; + msg->args[MSG_ARG_2].socklen = addrlen; + +- int32_t ret = rpc_sync_call(&stack->rpc_queue, msg); ++ int32_t ret = rpc_sync_call(queue, msg); + if (ret < 0) { + errno = -ret; + return -1; +@@ -383,10 +342,9 @@ int32_t rpc_call_connect(int fd, const struct sockaddr *addr, socklen_t addrlen) + return ret; + } + +-int32_t rpc_call_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen) ++int32_t rpc_call_getpeername(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_getpeername); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_getpeername); + if (msg == NULL) { + return -1; + } +@@ -395,13 +353,12 @@ int32_t rpc_call_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen) + msg->args[MSG_ARG_1].p = addr; + msg->args[MSG_ARG_2].p = addrlen; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen) ++int32_t rpc_call_getsockname(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_getsockname); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_getsockname); + if (msg == NULL) { + return -1; + } +@@ -410,13 +367,12 @@ int32_t rpc_call_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen) + msg->args[MSG_ARG_1].p = addr; + msg->args[MSG_ARG_2].p = addrlen; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen) ++int32_t rpc_call_getsockopt(rpc_queue *queue, int fd, int level, int optname, void *optval, socklen_t *optlen) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_getsockopt); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_getsockopt); + if (msg == NULL) { + return -1; + } +@@ -427,13 +383,12 @@ int32_t rpc_call_getsockopt(int fd, int level, int optname, void *optval, sockle + msg->args[MSG_ARG_3].p = optval; + msg->args[MSG_ARG_4].p = optlen; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen) ++int32_t rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, const void *optval, socklen_t optlen) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_setsockopt); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_setsockopt); + if (msg == NULL) { + return -1; + } +@@ -444,13 +399,12 @@ int32_t rpc_call_setsockopt(int fd, int level, int optname, const void *optval, + msg->args[MSG_ARG_3].cp = optval; + msg->args[MSG_ARG_4].socklen = optlen; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_fcntl(int fd, int cmd, long val) ++int32_t rpc_call_fcntl(rpc_queue *queue, int fd, int cmd, long val) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_fcntl); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_fcntl); + if (msg == NULL) { + return -1; + } +@@ -459,13 +413,12 @@ int32_t rpc_call_fcntl(int fd, int cmd, long val) + msg->args[MSG_ARG_1].i = cmd; + msg->args[MSG_ARG_2].l = val; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_ioctl(int fd, long cmd, void *argp) ++int32_t rpc_call_ioctl(rpc_queue *queue, int fd, long cmd, void *argp) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_ioctl); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_ioctl); + if (msg == NULL) { + return -1; + } +@@ -474,27 +427,24 @@ int32_t rpc_call_ioctl(int fd, long cmd, void *argp) + msg->args[MSG_ARG_1].l = cmd; + msg->args[MSG_ARG_2].p = argp; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_replenish(struct protocol_stack *stack, struct lwip_sock *sock) ++int32_t rpc_call_replenish(rpc_queue *queue, void *sock) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_replenish_sendring); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_replenish_sendring); + if (msg == NULL) { + return -1; + } + +- msg->args[MSG_ARG_0].p = stack; +- msg->args[MSG_ARG_1].p = sock; ++ msg->args[MSG_ARG_0].p = sock; + +- return rpc_sync_call(&stack->rpc_queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_send(int fd, const void *buf, size_t len, int flags) ++int32_t rpc_call_send(rpc_queue *queue, int fd, const void *buf, size_t len, int flags) + { +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- +- struct rpc_msg *msg = rpc_msg_alloc(stack, stack_send); ++ struct rpc_msg *msg = rpc_msg_alloc(stack_send); + if (msg == NULL) { + return -1; + } +@@ -502,10 +452,9 @@ int32_t rpc_call_send(int fd, const void *buf, size_t len, int flags) + msg->args[MSG_ARG_0].i = fd; + msg->args[MSG_ARG_1].size = len; + msg->args[MSG_ARG_2].i = flags; +- msg->args[MSG_ARG_3].p = stack; + msg->sync_flag = 0; + +- rpc_call(&stack->rpc_queue, msg); ++ rpc_call(queue, msg); + + return 0; + } +diff --git a/src/lstack/include/lstack_control_plane.h b/src/lstack/include/lstack_control_plane.h +index aed5443..548d725 100644 +--- a/src/lstack/include/lstack_control_plane.h ++++ b/src/lstack/include/lstack_control_plane.h +@@ -23,14 +23,11 @@ enum vdev_request { + VDEV_NONE, + }; + +-struct rpc_msg; + int client_reg_thrd_ring(void); + int32_t control_init_client(bool is_reconnect); + void control_client_thread(void *arg); + void control_server_thread(void *arg); + bool get_register_state(void); +-void thread_register_phase1(struct rpc_msg *msg); +-void thread_register_phase2(struct rpc_msg *msg); + void control_fd_close(void); + void delete_primary_path(void); + +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index c681547..7489f2a 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -21,7 +21,7 @@ + #include + + #include "gazelle_dfx_msg.h" +-#include "lstack_lockless_queue.h" ++#include "lstack_thread_rpc.h" + #include "lstack_ethdev.h" + #include "gazelle_opt.h" + +@@ -59,13 +59,15 @@ struct protocol_stack { + volatile bool low_power; + bool is_send_thread; + +- lockless_queue rpc_queue __rte_cache_aligned; +- char pad __rte_cache_aligned; ++ char pad1 __rte_cache_aligned; ++ rpc_queue dfx_rpc_queue; ++ rpc_queue rpc_queue; ++ char pad2 __rte_cache_aligned; + + /* kernel event thread read/write frequently */ + struct epoll_event kernel_events[KERNEL_EPOLL_MAX]; + int32_t kernel_event_num; +- char pad1 __rte_cache_aligned; ++ char pad3 __rte_cache_aligned; + + struct netif netif; + struct lstack_dev_ops dev_ops; +@@ -149,36 +151,10 @@ void stack_broadcast_clean_epoll(struct wakeup_poll *wakeup); + + void stack_send_pkts(struct protocol_stack *stack); + +-struct rpc_msg; + struct thread_params { + uint16_t queue_id; + uint16_t idx; + }; +-void stack_clean_epoll(struct rpc_msg *msg); +-void stack_arp(struct rpc_msg *msg); +-void stack_socket(struct rpc_msg *msg); +-void stack_close(struct rpc_msg *msg); +-void stack_shutdown(struct rpc_msg *msg); +-void stack_bind(struct rpc_msg *msg); +-void stack_listen(struct rpc_msg *msg); +-void stack_accept(struct rpc_msg *msg); +-void stack_connect(struct rpc_msg *msg); +-void stack_recv(struct rpc_msg *msg); +-void stack_getpeername(struct rpc_msg *msg); +-void stack_getsockname(struct rpc_msg *msg); +-void stack_getsockopt(struct rpc_msg *msg); +-void stack_setsockopt(struct rpc_msg *msg); +-void stack_fcntl(struct rpc_msg *msg); +-void stack_ioctl(struct rpc_msg *msg); +-void stack_send(struct rpc_msg *msg); +-void stack_mempool_size(struct rpc_msg *msg); +-void stack_rpcpool_size(struct rpc_msg *msg); +-void stack_create_shadow_fd(struct rpc_msg *msg); +-void stack_replenish_sendring(struct rpc_msg *msg); +-void stack_get_conntable(struct rpc_msg *msg); +-void stack_get_connnum(struct rpc_msg *msg); +-void stack_recvlist_count(struct rpc_msg *msg); +-void stack_exit_by_rpc(struct rpc_msg *msg); + + int stack_polling(uint32_t wakeup_tick); + #endif +diff --git a/src/lstack/include/lstack_rpc_proc.h b/src/lstack/include/lstack_rpc_proc.h +new file mode 100644 +index 0000000..71f0c58 +--- /dev/null ++++ b/src/lstack/include/lstack_rpc_proc.h +@@ -0,0 +1,46 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++ ++#ifndef __GAZELLE_RPC_PROC_H__ ++#define __GAZELLE_RPC_PROC_H__ ++#include "lstack_thread_rpc.h" ++ ++void stack_clean_epoll(struct rpc_msg *msg); ++void stack_arp(struct rpc_msg *msg); ++void stack_socket(struct rpc_msg *msg); ++void stack_close(struct rpc_msg *msg); ++void stack_shutdown(struct rpc_msg *msg); ++void stack_bind(struct rpc_msg *msg); ++void stack_listen(struct rpc_msg *msg); ++void stack_accept(struct rpc_msg *msg); ++void stack_connect(struct rpc_msg *msg); ++void stack_recv(struct rpc_msg *msg); ++void stack_getpeername(struct rpc_msg *msg); ++void stack_getsockname(struct rpc_msg *msg); ++void stack_getsockopt(struct rpc_msg *msg); ++void stack_setsockopt(struct rpc_msg *msg); ++void stack_fcntl(struct rpc_msg *msg); ++void stack_ioctl(struct rpc_msg *msg); ++void stack_send(struct rpc_msg *msg); ++void stack_mempool_size(struct rpc_msg *msg); ++void stack_rpcpool_size(struct rpc_msg *msg); ++void stack_create_shadow_fd(struct rpc_msg *msg); ++void stack_replenish_sendring(struct rpc_msg *msg); ++void stack_get_conntable(struct rpc_msg *msg); ++void stack_get_connnum(struct rpc_msg *msg); ++void stack_recvlist_count(struct rpc_msg *msg); ++void stack_exit_by_rpc(struct rpc_msg *msg); ++ ++void thread_register_phase1(struct rpc_msg *msg); ++void thread_register_phase2(struct rpc_msg *msg); ++ ++#endif +diff --git a/src/lstack/include/lstack_thread_rpc.h b/src/lstack/include/lstack_thread_rpc.h +index 633ef93..30caa66 100644 +--- a/src/lstack/include/lstack_thread_rpc.h ++++ b/src/lstack/include/lstack_thread_rpc.h +@@ -28,6 +28,12 @@ + + #define RPC_MSG_MAX 4096 + #define RPC_MSG_MASK (RPC_MSG_MAX - 1) ++typedef struct lockless_queue rpc_queue; ++ ++struct rpc_stats { ++ uint16_t call_null; ++ uint64_t call_alloc_fail; ++}; + + struct rpc_msg; + typedef void (*rpc_msg_func)(struct rpc_msg *msg); +@@ -41,7 +47,9 @@ union rpc_msg_arg { + socklen_t socklen; + size_t size; + }; +-struct rpc_msg_pool; ++struct rpc_msg_pool { ++ struct rte_mempool *mempool; ++}; + struct rpc_msg { + pthread_spinlock_t lock; /* msg handler unlock notice sender msg process done */ + int8_t sync_flag : 1; +@@ -54,44 +62,41 @@ struct rpc_msg { + union rpc_msg_arg args[RPM_MSG_ARG_SIZE]; /* resolve by type */ + }; + +-struct rpc_msg_pool { +- struct rte_mempool *mempool; +-}; ++static inline void rpc_queue_init(rpc_queue *queue) ++{ ++ lockless_queue_init(queue); ++} + +-struct protocol_stack; +-struct rte_mbuf; +-struct wakeup_poll; +-struct lwip_sock; +-int poll_rpc_msg(struct protocol_stack *stack, uint32_t max_num); +-void rpc_call_clean_epoll(struct protocol_stack *stack, struct wakeup_poll *wakeup); +-int32_t rpc_call_msgcnt(struct protocol_stack *stack); +-int32_t rpc_call_shadow_fd(struct protocol_stack *stack, int32_t fd, const struct sockaddr *addr, socklen_t addrlen); +-int32_t rpc_call_recvlistcnt(struct protocol_stack *stack); +-int32_t rpc_call_thread_regphase1(struct protocol_stack *stack, void *conn); +-int32_t rpc_call_thread_regphase2(struct protocol_stack *stack, void *conn); +-int32_t rpc_call_conntable(struct protocol_stack *stack, void *conn_table, uint32_t max_conn); +-int32_t rpc_call_connnum(struct protocol_stack *stack); +-int32_t rpc_call_arp(struct protocol_stack *stack, struct rte_mbuf *mbuf); +-int32_t rpc_call_socket(int32_t domain, int32_t type, int32_t protocol); +-int32_t rpc_call_close(int32_t fd); +-int32_t rpc_call_shutdown(int fd, int how); +-int32_t rpc_call_bind(int32_t fd, const struct sockaddr *addr, socklen_t addrlen); +-int32_t rpc_call_listen(int s, int backlog); +-int32_t rpc_call_accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); +-int32_t rpc_call_connect(int fd, const struct sockaddr *addr, socklen_t addrlen); +-int32_t rpc_call_send(int fd, const void *buf, size_t len, int flags); +-int32_t rpc_call_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen); +-int32_t rpc_call_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen); +-int32_t rpc_call_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen); +-int32_t rpc_call_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen); +-int32_t rpc_call_fcntl(int fd, int cmd, long val); +-int32_t rpc_call_ioctl(int fd, long cmd, void *argp); +-int32_t rpc_call_replenish(struct protocol_stack *stack, struct lwip_sock *sock); +-int32_t rpc_call_mbufpoolsize(struct protocol_stack *stack); +-int32_t rpc_call_rpcpool_size(struct protocol_stack *stack); +-int32_t rpc_call_stack_exit(struct protocol_stack *stack); ++struct rpc_stats *rpc_stats_get(void); ++int32_t rpc_msgcnt(rpc_queue *queue); ++int rpc_poll_msg(rpc_queue *queue, uint32_t max_num); ++void rpc_call_clean_epoll(rpc_queue *queue, void *wakeup); ++int32_t rpc_call_shadow_fd(rpc_queue *queue, int32_t fd, const struct sockaddr *addr, socklen_t addrlen); ++int32_t rpc_call_recvlistcnt(rpc_queue *queue); ++int32_t rpc_call_thread_regphase1(rpc_queue *queue, void *conn); ++int32_t rpc_call_thread_regphase2(rpc_queue *queue, void *conn); ++int32_t rpc_call_conntable(rpc_queue *queue, void *conn_table, uint32_t max_conn); ++int32_t rpc_call_connnum(rpc_queue *queue); ++int32_t rpc_call_arp(rpc_queue *queue, void *mbuf); ++int32_t rpc_call_socket(rpc_queue *queue, int32_t domain, int32_t type, int32_t protocol); ++int32_t rpc_call_close(rpc_queue *queue, int32_t fd); ++int32_t rpc_call_shutdown(rpc_queue *queue, int fd, int how); ++int32_t rpc_call_bind(rpc_queue *queue, int32_t fd, const struct sockaddr *addr, socklen_t addrlen); ++int32_t rpc_call_listen(rpc_queue *queue, int s, int backlog); ++int32_t rpc_call_accept(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); ++int32_t rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen); ++int32_t rpc_call_send(rpc_queue *queue, int fd, const void *buf, size_t len, int flags); ++int32_t rpc_call_getpeername(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen); ++int32_t rpc_call_getsockname(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen); ++int32_t rpc_call_getsockopt(rpc_queue *queue, int fd, int level, int optname, void *optval, socklen_t *optlen); ++int32_t rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, const void *optval, socklen_t optlen); ++int32_t rpc_call_fcntl(rpc_queue *queue, int fd, int cmd, long val); ++int32_t rpc_call_ioctl(rpc_queue *queue, int fd, long cmd, void *argp); ++int32_t rpc_call_replenish(rpc_queue *queue, void *sock); ++int32_t rpc_call_mbufpoolsize(rpc_queue *queue); ++int32_t rpc_call_stack_exit(rpc_queue *queue); + +-static inline __attribute__((always_inline)) void rpc_call(lockless_queue *queue, struct rpc_msg *msg) ++static inline __attribute__((always_inline)) void rpc_call(rpc_queue *queue, struct rpc_msg *msg) + { + lockless_queue_mpsc_push(queue, &msg->queue_node); + } +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 4d6f620..965de58 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -529,7 +529,7 @@ void transfer_tcp_to_thread(struct rte_mbuf *mbuf, uint16_t stk_idx) + struct protocol_stack *stack = get_protocol_stack_group()->stacks[stk_idx]; + int ret = -1; + while(ret != 0) { +- ret = rpc_call_arp(stack, mbuf); ++ ret = rpc_call_arp(&stack->rpc_queue, mbuf); + printf("transfer_tcp_to_thread, ret : %d \n", ret); + } + } +@@ -550,10 +550,10 @@ void parse_arp_and_transefer(char* buf) + } + copy_mbuf(mbuf_copy, mbuf); + +- ret = rpc_call_arp(stack, mbuf_copy); ++ ret = rpc_call_arp(&stack->rpc_queue, mbuf_copy); + + while (ret != 0) { +- rpc_call_arp(stack, mbuf_copy);; ++ rpc_call_arp(&stack->rpc_queue, mbuf_copy); + } + } + } +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 9f12096..bea0dc7 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -646,8 +646,7 @@ static void show_lstack_stats(struct gazelle_stack_dfx_data *lstack_stat) + printf("call_alloc_fail: %-12"PRIu64" ", lstack_stat->data.pkts.call_alloc_fail); + printf("call_null: %-18"PRIu64" \n", lstack_stat->data.pkts.stack_stat.call_null); + printf("send_pkts_fail: %-13"PRIu64" ", lstack_stat->data.pkts.stack_stat.send_pkts_fail); +- printf("mbuf_pool_freecnt: %-10"PRIu32" ", lstack_stat->data.pkts.mbufpool_avail_cnt); +- printf("rpc_pool_freecnt: %-12"PRIu32" \n", lstack_stat->data.pkts.rpcpool_avail_cnt); ++ printf("mbuf_pool_freecnt: %-10"PRIu32" \n", lstack_stat->data.pkts.mbufpool_avail_cnt); + printf("accpet_fail: %-16"PRIu64" ", lstack_stat->data.pkts.stack_stat.accept_fail); + printf("sock_rx_drop: %-15"PRIu64" ", lstack_stat->data.pkts.stack_stat.sock_rx_drop); + printf("sock_tx_merge: %-16"PRIu64" \n", lstack_stat->data.pkts.stack_stat.sock_tx_merge); +-- +2.27.0 + diff --git a/0136-readv-return-1-errno-is-EAGAIN-when-recvring-no-data.patch b/0136-readv-return-1-errno-is-EAGAIN-when-recvring-no-data.patch new file mode 100644 index 0000000..0d311c8 --- /dev/null +++ b/0136-readv-return-1-errno-is-EAGAIN-when-recvring-no-data.patch @@ -0,0 +1,30 @@ +From 61888e1e0d4810d3f0dbe5aa1d43a2dbcf2ad0f5 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Wed, 21 Feb 2024 07:44:59 +0800 +Subject: [PATCH] readv return -1, errno is EAGAIN when recvring no data + +--- + src/lstack/api/lstack_rtw_api.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c +index 8498b8e..e50fe37 100644 +--- a/src/lstack/api/lstack_rtw_api.c ++++ b/src/lstack/api/lstack_rtw_api.c +@@ -127,12 +127,7 @@ ssize_t rtw_readv(int s, const struct iovec *iov, int iovcnt) + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; +- ssize_t result = do_lwip_recvmsg_from_stack(s, &msg, 0); +- if (result == -1 && errno == EAGAIN) { +- errno = 0; +- return 0; +- } +- return result; ++ return do_lwip_recvmsg_from_stack(s, &msg, 0); + } + + ssize_t rtw_write(int s, const void *mem, size_t size) +-- +2.27.0 + diff --git a/0137-split-the-flow-fules-related-functions-into-separate.patch b/0137-split-the-flow-fules-related-functions-into-separate.patch new file mode 100644 index 0000000..1bf499d --- /dev/null +++ b/0137-split-the-flow-fules-related-functions-into-separate.patch @@ -0,0 +1,1707 @@ +From 409b6155a1ec9324bd68aae97a07e33560c19028 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Wed, 21 Feb 2024 08:05:03 +0800 +Subject: [PATCH] split the flow fules related functions into separate file + +--- + src/lstack/core/lstack_init.c | 1 + + src/lstack/core/lstack_protocol_stack.c | 25 +- + src/lstack/include/lstack_ethdev.h | 27 - + src/lstack/include/lstack_flow.h | 51 ++ + src/lstack/include/lstack_vdev.h | 9 - + src/lstack/netif/dir.mk | 2 +- + src/lstack/netif/lstack_ethdev.c | 687 +----------------------- + src/lstack/netif/lstack_flow.c | 680 +++++++++++++++++++++++ + src/lstack/netif/lstack_vdev.c | 1 + + 9 files changed, 747 insertions(+), 736 deletions(-) + create mode 100644 src/lstack/include/lstack_flow.h + create mode 100644 src/lstack/netif/lstack_flow.c + +diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c +index 31fd91d..d22a295 100644 +--- a/src/lstack/core/lstack_init.c ++++ b/src/lstack/core/lstack_init.c +@@ -48,6 +48,7 @@ + #include "lstack_protocol_stack.h" + #include "lstack_preload.h" + #include "lstack_wrap.h" ++#include "lstack_flow.h" + + static void check_process_start(void) + { +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 18e5df7..a545b73 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -454,14 +454,12 @@ int stack_polling(uint32_t wakeup_tick) + { + int force_quit; + struct cfg_params *cfg = get_global_cfg_params(); +- uint8_t use_ltran_flag = cfg->use_ltran; + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + bool kni_switch = cfg->kni_switch; + #endif + bool use_sockmap = cfg->use_sockmap; + bool stack_mode_rtc = cfg->stack_mode_rtc; + uint32_t rpc_number = cfg->rpc_number; +- uint32_t nic_read_number = cfg->nic_read_number; + uint32_t read_connect_number = cfg->read_connect_number; + struct protocol_stack *stack = get_protocol_stack(); + +@@ -469,7 +467,7 @@ int stack_polling(uint32_t wakeup_tick) + rpc_poll_msg(&stack->dfx_rpc_queue, 2); + force_quit = rpc_poll_msg(&stack->rpc_queue, rpc_number); + +- gazelle_eth_dev_poll(stack, use_ltran_flag, nic_read_number); ++ eth_dev_poll(); + sys_timer_run(); + if (cfg->low_power_mod != 0) { + low_power_idling(stack); +@@ -525,10 +523,6 @@ static void* gazelle_stack_thread(void *arg) + } + sem_post(&g_stack_group.sem_stack_setup); + +- if (!use_ltran() && queue_id == 0) { +- init_listen_and_user_ports(); +- } +- + LSTACK_LOG(INFO, LSTACK, "stack_%02hu init success\n", queue_id); + if (get_global_cfg_params()->stack_mode_rtc) { + return NULL; +@@ -545,12 +539,6 @@ static void* gazelle_stack_thread(void *arg) + return NULL; + } + +-static void gazelle_listen_thread(void *arg) +-{ +- struct cfg_params *cfg_param = get_global_cfg_params(); +- recv_pkts_from_other_process(cfg_param->process_idx, arg); +-} +- + int32_t stack_group_init_mempool(void) + { + struct cfg_params *global_cfg_parmas = get_global_cfg_params(); +@@ -611,17 +599,6 @@ int32_t stack_group_init(void) + } + } + +- /* run to completion mode does not currently support multiple process */ +- if (!use_ltran() && !get_global_cfg_params()->stack_mode_rtc) { +- char name[PATH_MAX]; +- sem_init(&stack_group->sem_listen_thread, 0, 0); +- sprintf_s(name, sizeof(name), "%s", "listen_thread"); +- struct sys_thread *thread = sys_thread_new(name, gazelle_listen_thread, +- (void*)(&stack_group->sem_listen_thread), 0, 0); +- free(thread); +- sem_wait(&stack_group->sem_listen_thread); +- } +- + return 0; + } + +diff --git a/src/lstack/include/lstack_ethdev.h b/src/lstack/include/lstack_ethdev.h +index 3252906..0c3d906 100644 +--- a/src/lstack/include/lstack_ethdev.h ++++ b/src/lstack/include/lstack_ethdev.h +@@ -16,25 +16,6 @@ + #include + #include + +-#define INVAILD_PROCESS_IDX 255 +- +-enum port_type { +- PORT_LISTEN, +- PORT_CONNECT, +-}; +- +-enum PACKET_TRANSFER_TYPE { +- TRANSFER_KERNEL = -1, +- TRANSFER_OTHER_THREAD, +- TRANSFER_CURRENT_THREAD, +-}; +- +-enum TRANSFER_MESSAGE_RESULT { +- CONNECT_ERROR = -2, +- REPLY_ERROR = -1, +- TRANSFER_SUCESS = 0, +-}; +- + struct protocol_stack; + struct rte_mbuf; + struct lstack_dev_ops { +@@ -44,21 +25,13 @@ struct lstack_dev_ops { + + int32_t ethdev_init(struct protocol_stack *stack); + int32_t eth_dev_poll(void); +-int32_t gazelle_eth_dev_poll(struct protocol_stack *stack, uint8_t use_ltran_flag, uint32_t nic_read_number); + void eth_dev_recv(struct rte_mbuf *mbuf, struct protocol_stack *stack); + +-int recv_pkts_from_other_process(int process_index, void* arg); +-int32_t check_params_from_primary(void); +- + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + void kni_handle_rx(uint16_t port_id); + void kni_handle_tx(struct rte_mbuf *mbuf); + #endif + +-void delete_user_process_port(uint16_t dst_port, enum port_type type); +-void add_user_process_port(uint16_t dst_port, uint8_t process_idx, enum port_type type); +-void delete_flow_director(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); +-void config_flow_director(uint16_t queue_id, uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); + void netif_poll(struct netif *netif); + + #endif /* __GAZELLE_ETHDEV_H__ */ +diff --git a/src/lstack/include/lstack_flow.h b/src/lstack/include/lstack_flow.h +new file mode 100644 +index 0000000..ad35cdf +--- /dev/null ++++ b/src/lstack/include/lstack_flow.h +@@ -0,0 +1,51 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++ ++#ifndef __LSTACK_FLOW_H__ ++#define __LSTACK_FLOW_H__ ++ ++#include ++ ++enum port_type { ++ PORT_LISTEN, ++ PORT_CONNECT, ++}; ++ ++enum PACKET_TRANSFER_TYPE { ++ TRANSFER_KERNEL = -1, ++ TRANSFER_OTHER_THREAD, ++ TRANSFER_CURRENT_THREAD, ++}; ++ ++enum TRANSFER_MESSAGE_RESULT { ++ CONNECT_ERROR = -2, ++ REPLY_ERROR = -1, ++ TRANSFER_SUCESS = 0, ++}; ++ ++int distribute_pakages(struct rte_mbuf *mbuf); ++void flow_init(void); ++int32_t check_params_from_primary(void); ++ ++int recv_pkts_from_other_process(int process_index, void* arg); ++void transfer_delete_rule_info_to_process0(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); ++void transfer_create_rule_info_to_process0(uint16_t queue_id, uint32_t src_ip, ++ uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); ++void transfer_add_or_delete_listen_port_to_process0(uint16_t listen_port, uint8_t process_idx, uint8_t is_add); ++void transfer_arp_to_other_process(struct rte_mbuf *mbuf); ++ ++void add_user_process_port(uint16_t dst_port, uint8_t process_idx, enum port_type type); ++void delete_user_process_port(uint16_t dst_port, enum port_type type); ++ ++void gazelle_listen_thread(void *arg); ++ ++#endif +diff --git a/src/lstack/include/lstack_vdev.h b/src/lstack/include/lstack_vdev.h +index 007eec7..4e5d191 100644 +--- a/src/lstack/include/lstack_vdev.h ++++ b/src/lstack/include/lstack_vdev.h +@@ -13,19 +13,10 @@ + #ifndef _GAZELLE_VDEV_H_ + #define _GAZELLE_VDEV_H_ + +-#include +- + struct lstack_dev_ops; + struct gazelle_quintuple; + enum reg_ring_type; + void vdev_dev_ops_init(struct lstack_dev_ops *dev_ops); + int vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple); + +-int recv_pkts_from_other_process(int process_index, void* arg); +-void transfer_delete_rule_info_to_process0(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); +-void transfer_create_rule_info_to_process0(uint16_t queue_id, uint32_t src_ip, +- uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); +-void transfer_add_or_delete_listen_port_to_process0(uint16_t listen_port, uint8_t process_idx, uint8_t is_add); +-void init_listen_and_user_ports(); +- + #endif /* _GAZELLE_VDEV_H_ */ +diff --git a/src/lstack/netif/dir.mk b/src/lstack/netif/dir.mk +index ec7c4ad..20fb5d6 100644 +--- a/src/lstack/netif/dir.mk ++++ b/src/lstack/netif/dir.mk +@@ -8,5 +8,5 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + +-SRC = lstack_ethdev.c lstack_vdev.c ++SRC = lstack_ethdev.c lstack_vdev.c lstack_flow.c + $(eval $(call register_dir, netif, $(SRC))) +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 25c94eb..2e938b0 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -10,74 +10,36 @@ + * See the Mulan PSL v2 for more details. + */ + +-#include +-#include +- + #include + #include + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + #include + #endif + #include +-#include +-#include + +-#include + #include + #include + #include + #include +-#include +-#include + + #include +-#include +-#include + ++#include "dpdk_common.h" + #include "lstack_cfg.h" + #include "lstack_vdev.h" + #include "lstack_stack_stat.h" + #include "lstack_log.h" + #include "lstack_dpdk.h" + #include "lstack_lwip.h" +-#include "dpdk_common.h" + #include "lstack_protocol_stack.h" + #include "lstack_thread_rpc.h" ++#include "lstack_flow.h" + #include "lstack_ethdev.h" + + /* FRAME_MTU + 14byte header */ + #define MBUF_MAX_LEN 1514 +-#define MAX_PATTERN_NUM 4 +-#define MAX_ACTION_NUM 2 +-#define FULL_MASK 0xffffffff /* full mask */ +-#define EMPTY_MASK 0x0 /* empty mask */ +-#define LSTACK_MBUF_LEN 64 +-#define TRANSFER_TCP_MUBF_LEN (LSTACK_MBUF_LEN + 3) +-#define DELETE_FLOWS_PARAMS_NUM 3 +-#define DELETE_FLOWS_PARAMS_LENGTH 30 +-#define CREATE_FLOWS_PARAMS_NUM 6 +-#define CREATE_FLOWS_PARAMS_LENGTH 60 +-#define ADD_OR_DELETE_LISTEN_PORT_PARAMS_LENGTH 25 +-#define ADD_OR_DELETE_LISTEN_PORT_PARAMS_NUM 3 +-#define REPLY_LEN 10 +-#define SUCCESS_REPLY "success" +-#define ERROR_REPLY "error" + #define PACKET_READ_SIZE 32 + +-#define GET_LSTACK_NUM 14 +-#define GET_LSTACK_NUM_STRING "get_lstack_num" +- +-#define SERVER_PATH "/var/run/gazelle/server.socket" +-#define SPLIT_DELIM "," +- +-#define UNIX_TCP_PORT_MAX 65535 +- +-#define IPV4_VERSION_OFFSET 4 +-#define IPV4_VERSION 4 +- +-static uint8_t g_user_ports[UNIX_TCP_PORT_MAX] = {INVAILD_PROCESS_IDX, }; +-static uint8_t g_listen_ports[UNIX_TCP_PORT_MAX] = {INVAILD_PROCESS_IDX, }; +- + void eth_dev_recv(struct rte_mbuf *mbuf, struct protocol_stack *stack) + { + int32_t ret; +@@ -126,636 +88,6 @@ void eth_dev_recv(struct rte_mbuf *mbuf, struct protocol_stack *stack) + } + } + +-int32_t eth_dev_poll(void) +-{ +- uint32_t nr_pkts; +- struct cfg_params *cfg = get_global_cfg_params(); +- struct protocol_stack *stack = get_protocol_stack(); +- +- nr_pkts = stack->dev_ops.rx_poll(stack, stack->pkts, cfg->nic_read_number); +- if (nr_pkts == 0) { +- return 0; +- } +- +- if (!cfg->use_ltran && get_protocol_stack_group()->latency_start) { +- uint64_t time_stamp = get_current_time(); +- time_stamp_into_mbuf(nr_pkts, stack->pkts, time_stamp); +- } +- +- for (uint32_t i = 0; i < nr_pkts; i++) { +- /* copy arp into other stack */ +- if (!cfg->use_ltran) { +- struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(stack->pkts[i], struct rte_ether_hdr *); +- if (unlikely(RTE_BE16(RTE_ETHER_TYPE_ARP) == ethh->ether_type)) { +- stack_broadcast_arp(stack->pkts[i], stack); +- } +- } +- +- eth_dev_recv(stack->pkts[i], stack); +- } +- +- stack->stats.rx += nr_pkts; +- +- return nr_pkts; +-} +- +-/* flow rule map */ +-#define RULE_KEY_LEN 23 +-struct flow_rule { +- char rule_key[RULE_KEY_LEN]; +- struct rte_flow *flow; +- UT_hash_handle hh; +-}; +- +-static uint16_t g_flow_num = 0; +-struct flow_rule *g_flow_rules = NULL; +-struct flow_rule *find_rule(char *rule_key) +-{ +- struct flow_rule *fl; +- HASH_FIND_STR(g_flow_rules, rule_key, fl); +- return fl; +-} +- +-void add_rule(char* rule_key, struct rte_flow *flow) +-{ +- struct flow_rule *rule; +- HASH_FIND_STR(g_flow_rules, rule_key, rule); +- if (rule == NULL) { +- rule = (struct flow_rule*)malloc(sizeof(struct flow_rule)); +- strcpy_s(rule->rule_key, RULE_KEY_LEN, rule_key); +- HASH_ADD_STR(g_flow_rules, rule_key, rule); +- } +- rule->flow = flow; +-} +- +-void delete_rule(char* rule_key) +-{ +- struct flow_rule *rule = NULL; +- HASH_FIND_STR(g_flow_rules, rule_key, rule); +- if (rule != NULL) { +- HASH_DEL(g_flow_rules, rule); +- free(rule); +- } +-} +- +-void init_listen_and_user_ports(void) +-{ +- memset_s(g_user_ports, sizeof(g_user_ports), INVAILD_PROCESS_IDX, sizeof(g_user_ports)); +- memset_s(g_listen_ports, sizeof(g_listen_ports), INVAILD_PROCESS_IDX, sizeof(g_listen_ports)); +-} +- +-int transfer_pkt_to_other_process(char *buf, int process_index, int write_len, bool need_reply) +-{ +- /* other process queue_id */ +- struct sockaddr_un serun; +- int sockfd; +- int ret = 0; +- +- sockfd = posix_api->socket_fn(AF_UNIX, SOCK_STREAM, 0); +- memset_s(&serun, sizeof(serun), 0, sizeof(serun)); +- serun.sun_family = AF_UNIX; +- sprintf_s(serun.sun_path, PATH_MAX, "%s%d", SERVER_PATH, process_index); +- int32_t len = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); +- if (posix_api->connect_fn(sockfd, (struct sockaddr *)&serun, len) < 0) { +- return CONNECT_ERROR; +- } +- posix_api->write_fn(sockfd, buf, write_len); +- if (need_reply) { +- char reply_message[REPLY_LEN]; +- int32_t read_result = posix_api->read_fn(sockfd, reply_message, REPLY_LEN); +- if (read_result > 0) { +- if (strcmp(reply_message, SUCCESS_REPLY) == 0) { +- ret = TRANSFER_SUCESS; +- } else if (strcmp(reply_message, ERROR_REPLY) == 0) { +- ret = REPLY_ERROR; +- } else { +- ret = atoi(reply_message); +- } +- } else { +- ret = REPLY_ERROR; +- } +- } +- posix_api->close_fn(sockfd); +- +- return ret; +-} +- +-int32_t check_params_from_primary(void) +-{ +- struct cfg_params *cfg = get_global_cfg_params(); +- if (cfg->is_primary) { +- return 0; +- } +- // check lstack num +- char get_lstack_num[GET_LSTACK_NUM]; +- sprintf_s(get_lstack_num, GET_LSTACK_NUM, "%s", GET_LSTACK_NUM_STRING); +- int32_t ret = transfer_pkt_to_other_process(get_lstack_num, 0, GET_LSTACK_NUM, true); +- if (ret != cfg->num_cpu) { +- return -1; +- } +- return 0; +-} +- +-struct rte_flow *create_flow_director(uint16_t port_id, uint16_t queue_id, +- uint32_t src_ip, uint32_t dst_ip, +- uint16_t src_port, uint16_t dst_port, +- struct rte_flow_error *error) +-{ +- struct rte_flow_attr attr; +- struct rte_flow_item pattern[MAX_PATTERN_NUM]; +- struct rte_flow_action action[MAX_ACTION_NUM]; +- struct rte_flow *flow = NULL; +- struct rte_flow_action_queue queue = { .index = queue_id }; +- struct rte_flow_item_ipv4 ip_spec; +- struct rte_flow_item_ipv4 ip_mask; +- +- struct rte_flow_item_tcp tcp_spec; +- struct rte_flow_item_tcp tcp_mask; +- int res; +- +- memset_s(pattern, sizeof(pattern), 0, sizeof(pattern)); +- memset_s(action, sizeof(action), 0, sizeof(action)); +- +- /* +- * set the rule attribute. +- * in this case only ingress packets will be checked. +- */ +- memset_s(&attr, sizeof(struct rte_flow_attr), 0, sizeof(struct rte_flow_attr)); +- attr.ingress = 1; +- +- /* +- * create the action sequence. +- * one action only, move packet to queue +- */ +- action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; +- action[0].conf = &queue; +- action[1].type = RTE_FLOW_ACTION_TYPE_END; +- +- // not limit eth header +- pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; +- +- // ip header +- memset_s(&ip_spec, sizeof(struct rte_flow_item_ipv4), 0, sizeof(struct rte_flow_item_ipv4)); +- memset_s(&ip_mask, sizeof(struct rte_flow_item_ipv4), 0, sizeof(struct rte_flow_item_ipv4)); +- ip_spec.hdr.dst_addr = dst_ip; +- ip_mask.hdr.dst_addr = FULL_MASK; +- ip_spec.hdr.src_addr = src_ip; +- ip_mask.hdr.src_addr = FULL_MASK; +- pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; +- pattern[1].spec = &ip_spec; +- pattern[1].mask = &ip_mask; +- +- // tcp header, full mask 0xffff +- memset_s(&tcp_spec, sizeof(struct rte_flow_item_tcp), 0, sizeof(struct rte_flow_item_tcp)); +- memset_s(&tcp_mask, sizeof(struct rte_flow_item_tcp), 0, sizeof(struct rte_flow_item_tcp)); +- pattern[2].type = RTE_FLOW_ITEM_TYPE_TCP; // 2: pattern 2 is tcp header +- tcp_spec.hdr.src_port = src_port; +- tcp_spec.hdr.dst_port = dst_port; +- tcp_mask.hdr.src_port = rte_flow_item_tcp_mask.hdr.src_port; +- tcp_mask.hdr.dst_port = rte_flow_item_tcp_mask.hdr.dst_port; +- pattern[2].spec = &tcp_spec; +- pattern[2].mask = &tcp_mask; +- +- /* the final level must be always type end */ +- pattern[3].type = RTE_FLOW_ITEM_TYPE_END; +- res = rte_flow_validate(port_id, &attr, pattern, action, error); +- if (!res) { +- flow = rte_flow_create(port_id, &attr, pattern, action, error); +- } else { +- LSTACK_LOG(ERR, LSTACK, "rte_flow_create.rte_flow_validate error, res %d \n", res); +- } +- +- return flow; +-} +- +-void config_flow_director(uint16_t queue_id, uint32_t src_ip, +- uint32_t dst_ip, uint16_t src_port, uint16_t dst_port) +-{ +- uint16_t port_id = get_protocol_stack_group()->port_id; +- char rule_key[RULE_KEY_LEN] = {0}; +- sprintf_s(rule_key, sizeof(rule_key), "%u_%u_%u", src_ip, src_port, dst_port); +- struct flow_rule *fl_exist = find_rule(rule_key); +- if (fl_exist != NULL) { +- return; +- } +- +- LSTACK_LOG(INFO, LSTACK, +- "config_flow_director, flow queue_id %u, src_ip %u,src_port_ntohs:%u, dst_port_ntohs:%u\n", +- queue_id, src_ip, ntohs(src_port), ntohs(dst_port)); +- +- struct rte_flow_error error; +- struct rte_flow *flow = create_flow_director(port_id, queue_id, src_ip, dst_ip, src_port, dst_port, &error); +- if (!flow) { +- LSTACK_LOG(ERR, LSTACK,"flow can not be created. queue_id %u, src_ip %u, src_port %u," +- "dst_port %u, dst_port_ntohs :%u, type %d. message: %s\n", +- queue_id, src_ip, src_port, dst_port, ntohs(dst_port), +- error.type, error.message ? error.message : "(no stated reason)"); +- return; +- } +- __sync_fetch_and_add(&g_flow_num, 1); +- add_rule(rule_key, flow); +-} +- +-void delete_flow_director(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port) +-{ +- uint16_t port_id = get_protocol_stack_group()->port_id; +- char rule_key[RULE_KEY_LEN] = {0}; +- sprintf_s(rule_key, RULE_KEY_LEN, "%u_%u_%u",dst_ip, dst_port, src_port); +- struct flow_rule *fl = find_rule(rule_key); +- +- if(fl != NULL){ +- struct rte_flow_error error; +- int ret = rte_flow_destroy(port_id, fl->flow, &error); +- if(ret != 0){ +- LSTACK_LOG(ERR, LSTACK, "Flow can't be delete %d message: %s\n", +- error.type, error.message ? error.message : "(no stated reason)"); +- } +- delete_rule(rule_key); +- __sync_fetch_and_sub(&g_flow_num, 1); +- } +-} +- +-/* if process 0, delete directly, else transfer 'dst_ip,src_port,dst_port' to process 0. */ +-void transfer_delete_rule_info_to_process0(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port) +-{ +- if (get_global_cfg_params()->is_primary) { +- delete_flow_director(dst_ip, src_port, dst_port); +- } else { +- char process_server_path[DELETE_FLOWS_PARAMS_LENGTH]; +- sprintf_s(process_server_path, DELETE_FLOWS_PARAMS_LENGTH, "%u%s%u%s%u", +- dst_ip, SPLIT_DELIM, src_port, SPLIT_DELIM, dst_port); +- int ret = transfer_pkt_to_other_process(process_server_path, 0, DELETE_FLOWS_PARAMS_LENGTH, false); +- if(ret != TRANSFER_SUCESS){ +- LSTACK_LOG(ERR, LSTACK, "error. tid %d. dst_ip %u, src_port: %u, dst_port %u\n", +- rte_gettid(), dst_ip, src_port, dst_port); +- } +- } +-} +- +-// if process 0, add directly, else transfer 'src_ip,dst_ip,src_port,dst_port,queue_id' to process 0. +-void transfer_create_rule_info_to_process0(uint16_t queue_id, uint32_t src_ip, +- uint32_t dst_ip, uint16_t src_port, +- uint16_t dst_port) +-{ +- char process_server_path[CREATE_FLOWS_PARAMS_LENGTH]; +- /* exchage src_ip and dst_ip, src_port and dst_port */ +- uint8_t process_idx = get_global_cfg_params()->process_idx; +- sprintf_s(process_server_path, CREATE_FLOWS_PARAMS_LENGTH, "%u%s%u%s%u%s%u%s%u%s%u", +- dst_ip, SPLIT_DELIM, src_ip, SPLIT_DELIM, +- dst_port, SPLIT_DELIM, src_port, SPLIT_DELIM, +- queue_id, SPLIT_DELIM, process_idx); +- int ret = transfer_pkt_to_other_process(process_server_path, 0, CREATE_FLOWS_PARAMS_LENGTH, true); +- if (ret != TRANSFER_SUCESS) { +- LSTACK_LOG(ERR, LSTACK, "error. tid %d. src_ip %u, dst_ip %u, src_port: %u, dst_port %u," +- "queue_id %u, process_idx %u\n", +- rte_gettid(), src_ip, dst_ip, src_port, dst_port, queue_id, process_idx); +- } +-} +- +-void transfer_add_or_delete_listen_port_to_process0(uint16_t listen_port, uint8_t process_idx, uint8_t is_add) +-{ +- char process_server_path[ADD_OR_DELETE_LISTEN_PORT_PARAMS_LENGTH]; +- sprintf_s(process_server_path, ADD_OR_DELETE_LISTEN_PORT_PARAMS_LENGTH, +- "%u%s%u%s%u", listen_port, SPLIT_DELIM, process_idx, SPLIT_DELIM, is_add); +- int ret = transfer_pkt_to_other_process(process_server_path, 0, ADD_OR_DELETE_LISTEN_PORT_PARAMS_LENGTH, true); +- if(ret != TRANSFER_SUCESS) { +- LSTACK_LOG(ERR, LSTACK, "error. tid %d. listen_port %u, process_idx %u\n", +- rte_gettid(), listen_port, process_idx); +- } +-} +- +-static int str_to_array(char *args, uint32_t *array, int size) +-{ +- int val; +- uint16_t cnt = 0; +- char *elem = NULL; +- char *next_token = NULL; +- +- memset_s(array, sizeof(*array) * size, 0, sizeof(*array) * size); +- elem = strtok_s((char *)args, SPLIT_DELIM, &next_token); +- while (elem != NULL) { +- if (cnt >= size) { +- return -1; +- } +- val = atoi(elem); +- if (val < 0) { +- return -1; +- } +- array[cnt] = (uint32_t)val; +- cnt++; +- +- elem = strtok_s(NULL, SPLIT_DELIM, &next_token); +- } +- +- return cnt; +-} +- +-void parse_and_delete_rule(char* buf) +-{ +- uint32_t array[DELETE_FLOWS_PARAMS_NUM]; +- str_to_array(buf, array, DELETE_FLOWS_PARAMS_NUM); +- uint32_t dst_ip = array[0]; +- uint16_t src_port = array[1]; +- uint16_t dst_port = array[2]; +- delete_flow_director(dst_ip, src_port, dst_port); +-} +- +-void add_user_process_port(uint16_t dst_port, uint8_t process_idx, enum port_type type) +-{ +- if (type == PORT_LISTEN) { +- g_listen_ports[dst_port] = process_idx; +- } else { +- g_user_ports[dst_port] = process_idx; +- } +-} +- +-void delete_user_process_port(uint16_t dst_port, enum port_type type) +-{ +- if (type == PORT_LISTEN) { +- g_listen_ports[dst_port] = INVAILD_PROCESS_IDX; +- } else { +- g_user_ports[dst_port] = INVAILD_PROCESS_IDX; +- } +-} +- +-void parse_and_create_rule(char* buf) +-{ +- uint32_t array[CREATE_FLOWS_PARAMS_NUM]; +- str_to_array(buf, array, CREATE_FLOWS_PARAMS_NUM); +- uint32_t src_ip = array[0]; +- uint32_t dst_ip = array[1]; +- uint16_t src_port = array[2]; +- uint16_t dst_port = array[3]; +- uint16_t queue_id = array[4]; +- uint8_t process_idx = array[5]; +- config_flow_director(queue_id, src_ip, dst_ip, src_port, dst_port); +- add_user_process_port(dst_port, process_idx, PORT_CONNECT); +-} +- +-void parse_and_add_or_delete_listen_port(char* buf) +-{ +- uint32_t array[ADD_OR_DELETE_LISTEN_PORT_PARAMS_NUM]; +- str_to_array(buf, array, ADD_OR_DELETE_LISTEN_PORT_PARAMS_NUM); +- uint16_t listen_port = array[0]; +- uint8_t process_idx = array[1]; +- uint8_t is_add = array[2]; +- if (is_add == 1) { +- add_user_process_port(listen_port, process_idx, PORT_LISTEN); +- } else { +- delete_user_process_port(listen_port, PORT_LISTEN); +- } +- +-} +- +-void transfer_arp_to_other_process(struct rte_mbuf *mbuf) +-{ +- struct cfg_params *cfgs = get_global_cfg_params(); +- +- for(int i = 1; i < cfgs->num_process; i++){ +- char arp_mbuf[LSTACK_MBUF_LEN] = {0}; +- sprintf_s(arp_mbuf, sizeof(arp_mbuf), "%lu", mbuf); +- int result = transfer_pkt_to_other_process(arp_mbuf, i, LSTACK_MBUF_LEN, false); +- if (result == CONNECT_ERROR) { +- LSTACK_LOG(INFO, LSTACK,"connect process %d failed, ensure the process is started.\n", i); +- } else if (result == REPLY_ERROR) { +- LSTACK_LOG(ERR, LSTACK,"transfer arp pakages to process %d error. %m\n", i); +- } +- } +-} +- +-void transfer_tcp_to_thread(struct rte_mbuf *mbuf, uint16_t stk_idx) +-{ +- /* current process queue_id */ +- struct protocol_stack *stack = get_protocol_stack_group()->stacks[stk_idx]; +- int ret = -1; +- while(ret != 0) { +- ret = rpc_call_arp(&stack->rpc_queue, mbuf); +- printf("transfer_tcp_to_thread, ret : %d \n", ret); +- } +-} +- +-void parse_arp_and_transefer(char* buf) +-{ +- struct rte_mbuf *mbuf = (struct rte_mbuf *)atoll(buf); +- struct protocol_stack_group *stack_group = get_protocol_stack_group(); +- struct rte_mbuf *mbuf_copy = NULL; +- struct protocol_stack *stack = NULL; +- int32_t ret; +- for (int32_t i = 0; i < stack_group->stack_num; i++) { +- stack = stack_group->stacks[i]; +- ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); +- while (ret != 0) { +- ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); +- stack->stats.rx_allocmbuf_fail++; +- } +- copy_mbuf(mbuf_copy, mbuf); +- +- ret = rpc_call_arp(&stack->rpc_queue, mbuf_copy); +- +- while (ret != 0) { +- rpc_call_arp(&stack->rpc_queue, mbuf_copy); +- } +- } +-} +- +-void parse_tcp_and_transefer(char* buf) +-{ +- char *next_token = NULL; +- char *elem = strtok_s(buf, SPLIT_DELIM, &next_token); +- struct rte_mbuf *mbuf = (struct rte_mbuf *) atoll(elem); +- elem = strtok_s(NULL, SPLIT_DELIM, &next_token); +- uint16_t queue_id = atoll(elem); +- +- struct protocol_stack_group *stack_group = get_protocol_stack_group(); +- uint16_t num_queue = get_global_cfg_params()->num_queue; +- uint16_t stk_index = queue_id % num_queue; +- struct rte_mbuf *mbuf_copy = NULL; +- struct protocol_stack *stack = stack_group->stacks[stk_index]; +- +- int32_t ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); +- while (ret != 0) { +- ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); +- stack->stats.rx_allocmbuf_fail++; +- } +- +- copy_mbuf(mbuf_copy,mbuf); +- +- transfer_tcp_to_thread(mbuf_copy, stk_index); +-} +- +-int recv_pkts_from_other_process(int process_index, void* arg) +-{ +- struct sockaddr_un serun, cliun; +- socklen_t cliun_len; +- int listenfd, connfd, size; +- char buf[132]; +- /* socket */ +- if ((listenfd = posix_api->socket_fn(AF_UNIX, SOCK_STREAM, 0)) < 0) { +- perror("socket error"); +- return -1; +- } +- /* bind */ +- memset_s(&serun, sizeof(serun), 0, sizeof(serun)); +- serun.sun_family = AF_UNIX; +- char process_server_path[PATH_MAX]; +- sprintf_s(process_server_path, sizeof(process_server_path), "%s%d", SERVER_PATH, process_index); +- strcpy_s(serun.sun_path, sizeof(serun.sun_path), process_server_path); +- size = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); +- unlink(process_server_path); +- if (posix_api->bind_fn(listenfd, (struct sockaddr *)&serun, size) < 0) { +- perror("bind error"); +- return -1; +- } +- if (posix_api->listen_fn(listenfd, 20) < 0) { /* 20: max backlog */ +- perror("listen error"); +- return -1; +- } +- sem_post((sem_t *)arg); +- /* block */ +- while(1) { +- cliun_len = sizeof(cliun); +- if ((connfd = posix_api->accept_fn(listenfd, (struct sockaddr *)&cliun, &cliun_len)) < 0) { +- perror("accept error"); +- continue; +- } +- while(1) { +- int n = posix_api->read_fn(connfd, buf, sizeof(buf)); +- if (n < 0) { +- perror("read error"); +- break; +- } else if (n == 0) { +- break; +- } +- +- if(n == LSTACK_MBUF_LEN) { +- /* arp */ +- parse_arp_and_transefer(buf); +- } else if (n == TRANSFER_TCP_MUBF_LEN) { +- /* tcp. lstack_mbuf_queue_id */ +- parse_tcp_and_transefer(buf); +- } else if (n == DELETE_FLOWS_PARAMS_LENGTH) { +- /* delete rule */ +- parse_and_delete_rule(buf); +- } else if(n == CREATE_FLOWS_PARAMS_LENGTH) { +- /* add rule */ +- parse_and_create_rule(buf); +- char reply_buf[REPLY_LEN]; +- sprintf_s(reply_buf, sizeof(reply_buf), "%s", SUCCESS_REPLY); +- posix_api->write_fn(connfd, reply_buf, REPLY_LEN); +- } else if (n == GET_LSTACK_NUM) { +- char reply_buf[REPLY_LEN]; +- sprintf_s(reply_buf, sizeof(reply_buf), "%d", get_global_cfg_params()->num_cpu); +- posix_api->write_fn(connfd, reply_buf, REPLY_LEN); +- } else { +- /* add port */ +- parse_and_add_or_delete_listen_port(buf); +- char reply_buf[REPLY_LEN]; +- sprintf_s(reply_buf, sizeof(reply_buf), "%s", SUCCESS_REPLY); +- posix_api->write_fn(connfd, reply_buf, REPLY_LEN); +- } +- +- } +- posix_api->close_fn(connfd); +- } +- posix_api->close_fn(listenfd); +- return 0; +-} +- +-void concat_mbuf_and_queue_id(struct rte_mbuf *mbuf, uint16_t queue_id, +- char* mbuf_and_queue_id, int write_len) +-{ +- sprintf_s(mbuf_and_queue_id, write_len, "%lu%s%u", mbuf, SPLIT_DELIM, queue_id); +-} +- +-static int mbuf_to_idx(struct rte_mbuf *mbuf, uint16_t *dst_port) +-{ +- struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *); +- u16_t type = rte_be_to_cpu_16(ethh->ether_type); +- uint32_t index = 0; +- if (type == RTE_ETHER_TYPE_IPV4) { +- struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr)); +- uint8_t ip_version = (iph->version_ihl & 0xf0) >> IPV4_VERSION_OFFSET; +- if (likely(ip_version == IPV4_VERSION)) { +- if (likely(iph->next_proto_id == IPPROTO_TCP)) { +- struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr *, +- sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)); +- *dst_port = tcp_hdr->dst_port; +- +- if (unlikely(tcp_hdr->tcp_flags == TCP_SYN)) { +- uint32_t src_ip = iph->src_addr; +- uint16_t src_port = tcp_hdr->src_port; +- index = rte_jhash_3words(src_ip, src_port | ((*dst_port) << 16), 0, 0); +- } else { +- return -1; +- } +- } +- } +- } else if (type == RTE_ETHER_TYPE_IPV6) { +- struct rte_ipv6_hdr *iph = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv6_hdr *, sizeof(struct rte_ether_hdr)); +- if (likely(iph->proto == IPPROTO_TCP)) { +- struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr *, +- sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv6_hdr)); +- *dst_port = tcp_hdr->dst_port; +- +- if (unlikely(tcp_hdr->tcp_flags == TCP_SYN)) { +- uint32_t *src_ip = (uint32_t *) &iph->src_addr; +- uint16_t src_port = tcp_hdr->src_port; +- uint32_t v = rte_jhash_3words(src_ip[0], src_ip[1], src_ip[2], 0); +- index = rte_jhash_3words(src_ip[3], src_port | ((*dst_port) << 16), v, 0); +- } else { +- return -1; +- } +- } +- } else { +- return -1; +- } +- return index; +-} +- +-int distribute_pakages(struct rte_mbuf *mbuf) +-{ +- uint16_t dst_port = 0; +- uint32_t index = mbuf_to_idx(mbuf, &dst_port); +- if (index == -1) { +- return TRANSFER_CURRENT_THREAD; +- } +- +- uint16_t queue_id = 0; +- uint32_t user_process_idx = 0; +- int each_process_queue_num = get_global_cfg_params()->num_queue; +- index = index % each_process_queue_num; +- if (g_listen_ports[dst_port] != INVAILD_PROCESS_IDX) { +- user_process_idx = g_listen_ports[dst_port]; +- } else { +- user_process_idx = g_user_ports[dst_port]; +- } +- +- if (user_process_idx == INVAILD_PROCESS_IDX) { +- return TRANSFER_KERNEL; +- } +- +- if (get_global_cfg_params()->seperate_send_recv) { +- queue_id = user_process_idx * each_process_queue_num + (index / 2) * 2; +- } else { +- queue_id = user_process_idx * each_process_queue_num + index; +- } +- if (queue_id != 0) { +- if (user_process_idx == 0) { +- transfer_tcp_to_thread(mbuf, queue_id); +- } else { +- char mbuf_and_queue_id[TRANSFER_TCP_MUBF_LEN]; +- concat_mbuf_and_queue_id(mbuf, queue_id, mbuf_and_queue_id, TRANSFER_TCP_MUBF_LEN); +- transfer_pkt_to_other_process(mbuf_and_queue_id, user_process_idx, +- TRANSFER_TCP_MUBF_LEN, false); +- } +- return TRANSFER_OTHER_THREAD; +- } else { +- return TRANSFER_CURRENT_THREAD; +- } +- +- return TRANSFER_KERNEL; +-} +- + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + void kni_handle_rx(uint16_t port_id) + { +@@ -797,17 +129,18 @@ void kni_handle_tx(struct rte_mbuf *mbuf) + } + #endif + +-/* optimized eth_dev_poll() in lstack */ +-int32_t gazelle_eth_dev_poll(struct protocol_stack *stack, uint8_t use_ltran_flag, uint32_t nic_read_number) ++int32_t eth_dev_poll(void) + { + uint32_t nr_pkts; ++ struct cfg_params *cfg = get_global_cfg_params(); ++ struct protocol_stack *stack = get_protocol_stack(); + +- nr_pkts = stack->dev_ops.rx_poll(stack, stack->pkts, nic_read_number); ++ nr_pkts = stack->dev_ops.rx_poll(stack, stack->pkts, cfg->nic_read_number); + if (nr_pkts == 0) { + return 0; + } + +- if (!use_ltran_flag && get_protocol_stack_group()->latency_start) { ++ if (!use_ltran() && get_protocol_stack_group()->latency_start) { + uint64_t time_stamp = get_current_time(); + time_stamp_into_mbuf(nr_pkts, stack->pkts, time_stamp); + } +@@ -816,7 +149,7 @@ int32_t gazelle_eth_dev_poll(struct protocol_stack *stack, uint8_t use_ltran_fla + /* 1 current thread recv; 0 other thread recv; -1 kni recv; */ + int transfer_type = TRANSFER_CURRENT_THREAD; + /* copy arp into other stack */ +- if (!use_ltran_flag) { ++ if (!use_ltran()) { + struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(stack->pkts[i], struct rte_ether_hdr *); + u16_t type; + type = ethh->ether_type; +@@ -946,6 +279,10 @@ int32_t ethdev_init(struct protocol_stack *stack) + LSTACK_LOG(ERR, LSTACK, "fill mbuf to rx_ring failed ret=%d\n", ret); + return ret; + } ++ } else { ++ if (cfg->tuple_filter && stack->queue_id == 0) { ++ flow_init(); ++ } + } + + netif_set_default(&stack->netif); +diff --git a/src/lstack/netif/lstack_flow.c b/src/lstack/netif/lstack_flow.c +new file mode 100644 +index 0000000..4e04209 +--- /dev/null ++++ b/src/lstack/netif/lstack_flow.c +@@ -0,0 +1,680 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "dpdk_common.h" ++#include "lstack_log.h" ++#include "lstack_dpdk.h" ++#include "lstack_cfg.h" ++#include "lstack_protocol_stack.h" ++#include "lstack_flow.h" ++ ++#define MAX_PATTERN_NUM 4 ++#define MAX_ACTION_NUM 2 ++#define FULL_MASK 0xffffffff /* full mask */ ++#define EMPTY_MASK 0x0 /* empty mask */ ++#define LSTACK_MBUF_LEN 64 ++#define TRANSFER_TCP_MUBF_LEN (LSTACK_MBUF_LEN + 3) ++#define DELETE_FLOWS_PARAMS_NUM 3 ++#define DELETE_FLOWS_PARAMS_LENGTH 30 ++#define CREATE_FLOWS_PARAMS_NUM 6 ++#define CREATE_FLOWS_PARAMS_LENGTH 60 ++#define ADD_OR_DELETE_LISTEN_PORT_PARAMS_LENGTH 25 ++#define ADD_OR_DELETE_LISTEN_PORT_PARAMS_NUM 3 ++#define REPLY_LEN 10 ++#define SUCCESS_REPLY "success" ++#define ERROR_REPLY "error" ++ ++#define GET_LSTACK_NUM 14 ++#define GET_LSTACK_NUM_STRING "get_lstack_num" ++ ++#define SERVER_PATH "/var/run/gazelle/server.socket" ++#define SPLIT_DELIM "," ++ ++#define UNIX_TCP_PORT_MAX 65535 ++ ++#define INVAILD_PROCESS_IDX 255 ++ ++#define IPV4_VERSION_OFFSET 4 ++#define IPV4_VERSION 4 ++ ++static uint8_t g_user_ports[UNIX_TCP_PORT_MAX] = {INVAILD_PROCESS_IDX, }; ++static uint8_t g_listen_ports[UNIX_TCP_PORT_MAX] = {INVAILD_PROCESS_IDX, }; ++ ++/* flow rule map */ ++#define RULE_KEY_LEN 23 ++struct flow_rule { ++ char rule_key[RULE_KEY_LEN]; ++ struct rte_flow *flow; ++ UT_hash_handle hh; ++}; ++ ++static uint16_t g_flow_num = 0; ++static struct flow_rule *g_flow_rules = NULL; ++static struct flow_rule *find_rule(char *rule_key) ++{ ++ struct flow_rule *fl; ++ HASH_FIND_STR(g_flow_rules, rule_key, fl); ++ return fl; ++} ++ ++static void add_rule(char* rule_key, struct rte_flow *flow) ++{ ++ struct flow_rule *rule; ++ HASH_FIND_STR(g_flow_rules, rule_key, rule); ++ if (rule == NULL) { ++ rule = (struct flow_rule*)malloc(sizeof(struct flow_rule)); ++ strcpy_s(rule->rule_key, RULE_KEY_LEN, rule_key); ++ HASH_ADD_STR(g_flow_rules, rule_key, rule); ++ } ++ rule->flow = flow; ++} ++ ++static void delete_rule(char* rule_key) ++{ ++ struct flow_rule *rule = NULL; ++ HASH_FIND_STR(g_flow_rules, rule_key, rule); ++ if (rule != NULL) { ++ HASH_DEL(g_flow_rules, rule); ++ free(rule); ++ } ++} ++ ++static void init_listen_and_user_ports(void) ++{ ++ memset_s(g_user_ports, sizeof(g_user_ports), INVAILD_PROCESS_IDX, sizeof(g_user_ports)); ++ memset_s(g_listen_ports, sizeof(g_listen_ports), INVAILD_PROCESS_IDX, sizeof(g_listen_ports)); ++} ++ ++static int transfer_pkt_to_other_process(char *buf, int process_index, int write_len, bool need_reply) ++{ ++ /* other process queue_id */ ++ struct sockaddr_un serun; ++ int sockfd; ++ int ret = 0; ++ ++ sockfd = posix_api->socket_fn(AF_UNIX, SOCK_STREAM, 0); ++ memset_s(&serun, sizeof(serun), 0, sizeof(serun)); ++ serun.sun_family = AF_UNIX; ++ sprintf_s(serun.sun_path, PATH_MAX, "%s%d", SERVER_PATH, process_index); ++ int32_t len = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); ++ if (posix_api->connect_fn(sockfd, (struct sockaddr *)&serun, len) < 0) { ++ return CONNECT_ERROR; ++ } ++ posix_api->write_fn(sockfd, buf, write_len); ++ if (need_reply) { ++ char reply_message[REPLY_LEN]; ++ int32_t read_result = posix_api->read_fn(sockfd, reply_message, REPLY_LEN); ++ if (read_result > 0) { ++ if (strcmp(reply_message, SUCCESS_REPLY) == 0) { ++ ret = TRANSFER_SUCESS; ++ } else if (strcmp(reply_message, ERROR_REPLY) == 0) { ++ ret = REPLY_ERROR; ++ } else { ++ ret = atoi(reply_message); ++ } ++ } else { ++ ret = REPLY_ERROR; ++ } ++ } ++ posix_api->close_fn(sockfd); ++ ++ return ret; ++} ++ ++int32_t check_params_from_primary(void) ++{ ++ struct cfg_params *cfg = get_global_cfg_params(); ++ if (cfg->is_primary) { ++ return 0; ++ } ++ // check lstack num ++ char get_lstack_num[GET_LSTACK_NUM]; ++ sprintf_s(get_lstack_num, GET_LSTACK_NUM, "%s", GET_LSTACK_NUM_STRING); ++ int32_t ret = transfer_pkt_to_other_process(get_lstack_num, 0, GET_LSTACK_NUM, true); ++ if (ret != cfg->num_cpu) { ++ return -1; ++ } ++ return 0; ++} ++ ++static struct rte_flow *create_flow_director(uint16_t port_id, uint16_t queue_id, ++ uint32_t src_ip, uint32_t dst_ip, ++ uint16_t src_port, uint16_t dst_port, ++ struct rte_flow_error *error) ++{ ++ struct rte_flow_attr attr; ++ struct rte_flow_item pattern[MAX_PATTERN_NUM]; ++ struct rte_flow_action action[MAX_ACTION_NUM]; ++ struct rte_flow *flow = NULL; ++ struct rte_flow_action_queue queue = { .index = queue_id }; ++ struct rte_flow_item_ipv4 ip_spec; ++ struct rte_flow_item_ipv4 ip_mask; ++ ++ struct rte_flow_item_tcp tcp_spec; ++ struct rte_flow_item_tcp tcp_mask; ++ int res; ++ ++ memset_s(pattern, sizeof(pattern), 0, sizeof(pattern)); ++ memset_s(action, sizeof(action), 0, sizeof(action)); ++ ++ /* ++ * set the rule attribute. ++ * in this case only ingress packets will be checked. ++ */ ++ memset_s(&attr, sizeof(struct rte_flow_attr), 0, sizeof(struct rte_flow_attr)); ++ attr.ingress = 1; ++ ++ /* ++ * create the action sequence. ++ * one action only, move packet to queue ++ */ ++ action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; ++ action[0].conf = &queue; ++ action[1].type = RTE_FLOW_ACTION_TYPE_END; ++ ++ // not limit eth header ++ pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; ++ ++ // ip header ++ memset_s(&ip_spec, sizeof(struct rte_flow_item_ipv4), 0, sizeof(struct rte_flow_item_ipv4)); ++ memset_s(&ip_mask, sizeof(struct rte_flow_item_ipv4), 0, sizeof(struct rte_flow_item_ipv4)); ++ ip_spec.hdr.dst_addr = dst_ip; ++ ip_mask.hdr.dst_addr = FULL_MASK; ++ ip_spec.hdr.src_addr = src_ip; ++ ip_mask.hdr.src_addr = FULL_MASK; ++ pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; ++ pattern[1].spec = &ip_spec; ++ pattern[1].mask = &ip_mask; ++ ++ // tcp header, full mask 0xffff ++ memset_s(&tcp_spec, sizeof(struct rte_flow_item_tcp), 0, sizeof(struct rte_flow_item_tcp)); ++ memset_s(&tcp_mask, sizeof(struct rte_flow_item_tcp), 0, sizeof(struct rte_flow_item_tcp)); ++ pattern[2].type = RTE_FLOW_ITEM_TYPE_TCP; // 2: pattern 2 is tcp header ++ tcp_spec.hdr.src_port = src_port; ++ tcp_spec.hdr.dst_port = dst_port; ++ tcp_mask.hdr.src_port = rte_flow_item_tcp_mask.hdr.src_port; ++ tcp_mask.hdr.dst_port = rte_flow_item_tcp_mask.hdr.dst_port; ++ pattern[2].spec = &tcp_spec; ++ pattern[2].mask = &tcp_mask; ++ ++ /* the final level must be always type end */ ++ pattern[3].type = RTE_FLOW_ITEM_TYPE_END; ++ res = rte_flow_validate(port_id, &attr, pattern, action, error); ++ if (!res) { ++ flow = rte_flow_create(port_id, &attr, pattern, action, error); ++ } else { ++ LSTACK_LOG(ERR, LSTACK, "rte_flow_create.rte_flow_validate error, res %d \n", res); ++ } ++ ++ return flow; ++} ++ ++static void config_flow_director(uint16_t queue_id, uint32_t src_ip, ++ uint32_t dst_ip, uint16_t src_port, uint16_t dst_port) ++{ ++ uint16_t port_id = get_protocol_stack_group()->port_id; ++ char rule_key[RULE_KEY_LEN] = {0}; ++ sprintf_s(rule_key, sizeof(rule_key), "%u_%u_%u", src_ip, src_port, dst_port); ++ struct flow_rule *fl_exist = find_rule(rule_key); ++ if (fl_exist != NULL) { ++ return; ++ } ++ ++ LSTACK_LOG(INFO, LSTACK, ++ "config_flow_director, flow queue_id %u, src_ip %u,src_port_ntohs:%u, dst_port_ntohs:%u\n", ++ queue_id, src_ip, ntohs(src_port), ntohs(dst_port)); ++ ++ struct rte_flow_error error; ++ struct rte_flow *flow = create_flow_director(port_id, queue_id, src_ip, dst_ip, src_port, dst_port, &error); ++ if (!flow) { ++ LSTACK_LOG(ERR, LSTACK,"flow can not be created. queue_id %u, src_ip %u, src_port %u," ++ "dst_port %u, dst_port_ntohs :%u, type %d. message: %s\n", ++ queue_id, src_ip, src_port, dst_port, ntohs(dst_port), ++ error.type, error.message ? error.message : "(no stated reason)"); ++ return; ++ } ++ __sync_fetch_and_add(&g_flow_num, 1); ++ add_rule(rule_key, flow); ++} ++ ++static void delete_flow_director(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port) ++{ ++ uint16_t port_id = get_protocol_stack_group()->port_id; ++ char rule_key[RULE_KEY_LEN] = {0}; ++ sprintf_s(rule_key, RULE_KEY_LEN, "%u_%u_%u",dst_ip, dst_port, src_port); ++ struct flow_rule *fl = find_rule(rule_key); ++ ++ if(fl != NULL) { ++ struct rte_flow_error error; ++ int ret = rte_flow_destroy(port_id, fl->flow, &error); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "Flow can't be delete %d message: %s\n", ++ error.type, error.message ? error.message : "(no stated reason)"); ++ } ++ delete_rule(rule_key); ++ __sync_fetch_and_sub(&g_flow_num, 1); ++ } ++} ++ ++/* if process 0, delete directly, else transfer 'dst_ip,src_port,dst_port' to process 0. */ ++void transfer_delete_rule_info_to_process0(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port) ++{ ++ if (get_global_cfg_params()->is_primary) { ++ delete_flow_director(dst_ip, src_port, dst_port); ++ } else { ++ char process_server_path[DELETE_FLOWS_PARAMS_LENGTH]; ++ sprintf_s(process_server_path, DELETE_FLOWS_PARAMS_LENGTH, "%u%s%u%s%u", ++ dst_ip, SPLIT_DELIM, src_port, SPLIT_DELIM, dst_port); ++ int ret = transfer_pkt_to_other_process(process_server_path, 0, DELETE_FLOWS_PARAMS_LENGTH, false); ++ if (ret != TRANSFER_SUCESS) { ++ LSTACK_LOG(ERR, LSTACK, "error. tid %d. dst_ip %u, src_port: %u, dst_port %u\n", ++ rte_gettid(), dst_ip, src_port, dst_port); ++ } ++ } ++} ++ ++// if process 0, add directly, else transfer 'src_ip,dst_ip,src_port,dst_port,queue_id' to process 0. ++void transfer_create_rule_info_to_process0(uint16_t queue_id, uint32_t src_ip, ++ uint32_t dst_ip, uint16_t src_port, ++ uint16_t dst_port) ++{ ++ char process_server_path[CREATE_FLOWS_PARAMS_LENGTH]; ++ /* exchage src_ip and dst_ip, src_port and dst_port */ ++ uint8_t process_idx = get_global_cfg_params()->process_idx; ++ sprintf_s(process_server_path, CREATE_FLOWS_PARAMS_LENGTH, "%u%s%u%s%u%s%u%s%u%s%u", ++ dst_ip, SPLIT_DELIM, src_ip, SPLIT_DELIM, ++ dst_port, SPLIT_DELIM, src_port, SPLIT_DELIM, ++ queue_id, SPLIT_DELIM, process_idx); ++ int ret = transfer_pkt_to_other_process(process_server_path, 0, CREATE_FLOWS_PARAMS_LENGTH, true); ++ if (ret != TRANSFER_SUCESS) { ++ LSTACK_LOG(ERR, LSTACK, "error. tid %d. src_ip %u, dst_ip %u, src_port: %u, dst_port %u," ++ "queue_id %u, process_idx %u\n", ++ rte_gettid(), src_ip, dst_ip, src_port, dst_port, queue_id, process_idx); ++ } ++} ++ ++void transfer_add_or_delete_listen_port_to_process0(uint16_t listen_port, uint8_t process_idx, uint8_t is_add) ++{ ++ char process_server_path[ADD_OR_DELETE_LISTEN_PORT_PARAMS_LENGTH]; ++ sprintf_s(process_server_path, ADD_OR_DELETE_LISTEN_PORT_PARAMS_LENGTH, ++ "%u%s%u%s%u", listen_port, SPLIT_DELIM, process_idx, SPLIT_DELIM, is_add); ++ int ret = transfer_pkt_to_other_process(process_server_path, 0, ADD_OR_DELETE_LISTEN_PORT_PARAMS_LENGTH, true); ++ if (ret != TRANSFER_SUCESS) { ++ LSTACK_LOG(ERR, LSTACK, "error. tid %d. listen_port %u, process_idx %u\n", ++ rte_gettid(), listen_port, process_idx); ++ } ++} ++ ++static int str_to_array(char *args, uint32_t *array, int size) ++{ ++ int val; ++ uint16_t cnt = 0; ++ char *elem = NULL; ++ char *next_token = NULL; ++ ++ memset_s(array, sizeof(*array) * size, 0, sizeof(*array) * size); ++ elem = strtok_s((char *)args, SPLIT_DELIM, &next_token); ++ while (elem != NULL) { ++ if (cnt >= size) { ++ return -1; ++ } ++ val = atoi(elem); ++ if (val < 0) { ++ return -1; ++ } ++ array[cnt] = (uint32_t)val; ++ cnt++; ++ ++ elem = strtok_s(NULL, SPLIT_DELIM, &next_token); ++ } ++ ++ return cnt; ++} ++ ++static void parse_and_delete_rule(char* buf) ++{ ++ uint32_t array[DELETE_FLOWS_PARAMS_NUM]; ++ str_to_array(buf, array, DELETE_FLOWS_PARAMS_NUM); ++ uint32_t dst_ip = array[0]; ++ uint16_t src_port = array[1]; ++ uint16_t dst_port = array[2]; ++ delete_flow_director(dst_ip, src_port, dst_port); ++} ++ ++void add_user_process_port(uint16_t dst_port, uint8_t process_idx, enum port_type type) ++{ ++ if (type == PORT_LISTEN) { ++ g_listen_ports[dst_port] = process_idx; ++ } else { ++ g_user_ports[dst_port] = process_idx; ++ } ++} ++ ++void delete_user_process_port(uint16_t dst_port, enum port_type type) ++{ ++ if (type == PORT_LISTEN) { ++ g_listen_ports[dst_port] = INVAILD_PROCESS_IDX; ++ } else { ++ g_user_ports[dst_port] = INVAILD_PROCESS_IDX; ++ } ++} ++ ++static void parse_and_create_rule(char* buf) ++{ ++ uint32_t array[CREATE_FLOWS_PARAMS_NUM]; ++ str_to_array(buf, array, CREATE_FLOWS_PARAMS_NUM); ++ uint32_t src_ip = array[0]; ++ uint32_t dst_ip = array[1]; ++ uint16_t src_port = array[2]; ++ uint16_t dst_port = array[3]; ++ uint16_t queue_id = array[4]; ++ uint8_t process_idx = array[5]; ++ config_flow_director(queue_id, src_ip, dst_ip, src_port, dst_port); ++ add_user_process_port(dst_port, process_idx, PORT_CONNECT); ++} ++ ++static void parse_and_add_or_delete_listen_port(char* buf) ++{ ++ uint32_t array[ADD_OR_DELETE_LISTEN_PORT_PARAMS_NUM]; ++ str_to_array(buf, array, ADD_OR_DELETE_LISTEN_PORT_PARAMS_NUM); ++ uint16_t listen_port = array[0]; ++ uint8_t process_idx = array[1]; ++ uint8_t is_add = array[2]; ++ if (is_add == 1) { ++ add_user_process_port(listen_port, process_idx, PORT_LISTEN); ++ } else { ++ delete_user_process_port(listen_port, PORT_LISTEN); ++ } ++} ++ ++void transfer_arp_to_other_process(struct rte_mbuf *mbuf) ++{ ++ struct cfg_params *cfgs = get_global_cfg_params(); ++ ++ for (int i = 1; i < cfgs->num_process; i++) { ++ char arp_mbuf[LSTACK_MBUF_LEN] = {0}; ++ sprintf_s(arp_mbuf, sizeof(arp_mbuf), "%lu", mbuf); ++ int result = transfer_pkt_to_other_process(arp_mbuf, i, LSTACK_MBUF_LEN, false); ++ if (result == CONNECT_ERROR) { ++ LSTACK_LOG(INFO, LSTACK,"connect process %d failed, ensure the process is started.\n", i); ++ } else if (result == REPLY_ERROR) { ++ LSTACK_LOG(ERR, LSTACK,"transfer arp pakages to process %d error. %m\n", i); ++ } ++ } ++} ++ ++static void transfer_tcp_to_thread(struct rte_mbuf *mbuf, uint16_t stk_idx) ++{ ++ /* current process queue_id */ ++ struct protocol_stack *stack = get_protocol_stack_group()->stacks[stk_idx]; ++ int ret = -1; ++ while (ret != 0) { ++ ret = rpc_call_arp(&stack->rpc_queue, mbuf); ++ printf("transfer_tcp_to_thread, ret : %d \n", ret); ++ } ++} ++ ++static void parse_arp_and_transefer(char* buf) ++{ ++ struct rte_mbuf *mbuf = (struct rte_mbuf *)atoll(buf); ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ struct rte_mbuf *mbuf_copy = NULL; ++ struct protocol_stack *stack = NULL; ++ int32_t ret; ++ for (int32_t i = 0; i < stack_group->stack_num; i++) { ++ stack = stack_group->stacks[i]; ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, false); ++ while (ret != 0) { ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, false); ++ stack->stats.rx_allocmbuf_fail++; ++ } ++ copy_mbuf(mbuf_copy, mbuf); ++ ++ ret = rpc_call_arp(&stack->rpc_queue, mbuf_copy); ++ ++ while (ret != 0) { ++ rpc_call_arp(&stack->rpc_queue, mbuf_copy); ++ } ++ } ++} ++ ++static void parse_tcp_and_transefer(char* buf) ++{ ++ char *next_token = NULL; ++ char *elem = strtok_s(buf, SPLIT_DELIM, &next_token); ++ struct rte_mbuf *mbuf = (struct rte_mbuf *) atoll(elem); ++ elem = strtok_s(NULL, SPLIT_DELIM, &next_token); ++ uint16_t queue_id = atoll(elem); ++ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ uint16_t num_queue = get_global_cfg_params()->num_queue; ++ uint16_t stk_index = queue_id % num_queue; ++ struct rte_mbuf *mbuf_copy = NULL; ++ struct protocol_stack *stack = stack_group->stacks[stk_index]; ++ ++ int32_t ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, false); ++ while (ret != 0) { ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, false); ++ stack->stats.rx_allocmbuf_fail++; ++ } ++ ++ copy_mbuf(mbuf_copy,mbuf); ++ transfer_tcp_to_thread(mbuf_copy, stk_index); ++} ++ ++int recv_pkts_from_other_process(int process_index, void* arg) ++{ ++ struct sockaddr_un serun, cliun; ++ socklen_t cliun_len; ++ int listenfd, connfd, size; ++ char buf[132]; ++ /* socket */ ++ if ((listenfd = posix_api->socket_fn(AF_UNIX, SOCK_STREAM, 0)) < 0) { ++ perror("socket error"); ++ return -1; ++ } ++ /* bind */ ++ memset_s(&serun, sizeof(serun), 0, sizeof(serun)); ++ serun.sun_family = AF_UNIX; ++ char process_server_path[PATH_MAX]; ++ sprintf_s(process_server_path, sizeof(process_server_path), "%s%d", SERVER_PATH, process_index); ++ strcpy_s(serun.sun_path, sizeof(serun.sun_path), process_server_path); ++ size = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); ++ unlink(process_server_path); ++ if (posix_api->bind_fn(listenfd, (struct sockaddr *)&serun, size) < 0) { ++ perror("bind error"); ++ return -1; ++ } ++ if (posix_api->listen_fn(listenfd, 20) < 0) { /* 20: max backlog */ ++ perror("listen error"); ++ return -1; ++ } ++ sem_post((sem_t *)arg); ++ /* block */ ++ while (1) { ++ cliun_len = sizeof(cliun); ++ if ((connfd = posix_api->accept_fn(listenfd, (struct sockaddr *)&cliun, &cliun_len)) < 0) { ++ perror("accept error"); ++ continue; ++ } ++ while (1) { ++ int n = posix_api->read_fn(connfd, buf, sizeof(buf)); ++ if (n < 0) { ++ perror("read error"); ++ break; ++ } else if (n == 0) { ++ break; ++ } ++ ++ if (n == LSTACK_MBUF_LEN) { ++ /* arp */ ++ parse_arp_and_transefer(buf); ++ } else if (n == TRANSFER_TCP_MUBF_LEN) { ++ /* tcp. lstack_mbuf_queue_id */ ++ parse_tcp_and_transefer(buf); ++ } else if (n == DELETE_FLOWS_PARAMS_LENGTH) { ++ /* delete rule */ ++ parse_and_delete_rule(buf); ++ } else if (n == CREATE_FLOWS_PARAMS_LENGTH) { ++ /* add rule */ ++ parse_and_create_rule(buf); ++ char reply_buf[REPLY_LEN]; ++ sprintf_s(reply_buf, sizeof(reply_buf), "%s", SUCCESS_REPLY); ++ posix_api->write_fn(connfd, reply_buf, REPLY_LEN); ++ } else if (n == GET_LSTACK_NUM) { ++ char reply_buf[REPLY_LEN]; ++ sprintf_s(reply_buf, sizeof(reply_buf), "%d", get_global_cfg_params()->num_cpu); ++ posix_api->write_fn(connfd, reply_buf, REPLY_LEN); ++ } else { ++ /* add port */ ++ parse_and_add_or_delete_listen_port(buf); ++ char reply_buf[REPLY_LEN]; ++ sprintf_s(reply_buf, sizeof(reply_buf), "%s", SUCCESS_REPLY); ++ posix_api->write_fn(connfd, reply_buf, REPLY_LEN); ++ } ++ ++ } ++ posix_api->close_fn(connfd); ++ } ++ posix_api->close_fn(listenfd); ++ return 0; ++} ++ ++void concat_mbuf_and_queue_id(struct rte_mbuf *mbuf, uint16_t queue_id, ++ char* mbuf_and_queue_id, int write_len) ++{ ++ sprintf_s(mbuf_and_queue_id, write_len, "%lu%s%u", mbuf, SPLIT_DELIM, queue_id); ++} ++ ++static int mbuf_to_idx(struct rte_mbuf *mbuf, uint16_t *dst_port) ++{ ++ struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *); ++ u16_t type = rte_be_to_cpu_16(ethh->ether_type); ++ uint32_t index = 0; ++ if (type == RTE_ETHER_TYPE_IPV4) { ++ struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr)); ++ uint8_t ip_version = (iph->version_ihl & 0xf0) >> IPV4_VERSION_OFFSET; ++ if (likely(ip_version == IPV4_VERSION)) { ++ if (likely(iph->next_proto_id == IPPROTO_TCP)) { ++ struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr *, ++ sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)); ++ *dst_port = tcp_hdr->dst_port; ++ ++ if (unlikely(tcp_hdr->tcp_flags == TCP_SYN)) { ++ uint32_t src_ip = iph->src_addr; ++ uint16_t src_port = tcp_hdr->src_port; ++ index = rte_jhash_3words(src_ip, src_port | ((*dst_port) << 16), 0, 0); ++ } else { ++ return -1; ++ } ++ } ++ } ++ } else if (type == RTE_ETHER_TYPE_IPV6) { ++ struct rte_ipv6_hdr *iph = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv6_hdr *, sizeof(struct rte_ether_hdr)); ++ if (likely(iph->proto == IPPROTO_TCP)) { ++ struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr *, ++ sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv6_hdr)); ++ *dst_port = tcp_hdr->dst_port; ++ ++ if (unlikely(tcp_hdr->tcp_flags == TCP_SYN)) { ++ uint32_t *src_ip = (uint32_t *) &iph->src_addr; ++ uint16_t src_port = tcp_hdr->src_port; ++ uint32_t v = rte_jhash_3words(src_ip[0], src_ip[1], src_ip[2], 0); ++ index = rte_jhash_3words(src_ip[3], src_port | ((*dst_port) << 16), v, 0); ++ } else { ++ return -1; ++ } ++ } ++ } else { ++ return -1; ++ } ++ return index; ++} ++ ++int distribute_pakages(struct rte_mbuf *mbuf) ++{ ++ uint16_t dst_port = 0; ++ uint32_t index = mbuf_to_idx(mbuf, &dst_port); ++ if (index == -1) { ++ return TRANSFER_CURRENT_THREAD; ++ } ++ ++ uint16_t queue_id = 0; ++ uint32_t user_process_idx = 0; ++ int each_process_queue_num = get_global_cfg_params()->num_queue; ++ index = index % each_process_queue_num; ++ if (g_listen_ports[dst_port] != INVAILD_PROCESS_IDX) { ++ user_process_idx = g_listen_ports[dst_port]; ++ } else { ++ user_process_idx = g_user_ports[dst_port]; ++ } ++ ++ if (user_process_idx == INVAILD_PROCESS_IDX) { ++ return TRANSFER_KERNEL; ++ } ++ ++ if (get_global_cfg_params()->seperate_send_recv) { ++ queue_id = user_process_idx * each_process_queue_num + (index / 2) * 2; ++ } else { ++ queue_id = user_process_idx * each_process_queue_num + index; ++ } ++ if (queue_id != 0) { ++ if (user_process_idx == 0) { ++ transfer_tcp_to_thread(mbuf, queue_id); ++ } else { ++ char mbuf_and_queue_id[TRANSFER_TCP_MUBF_LEN]; ++ concat_mbuf_and_queue_id(mbuf, queue_id, mbuf_and_queue_id, TRANSFER_TCP_MUBF_LEN); ++ transfer_pkt_to_other_process(mbuf_and_queue_id, user_process_idx, ++ TRANSFER_TCP_MUBF_LEN, false); ++ } ++ return TRANSFER_OTHER_THREAD; ++ } else { ++ return TRANSFER_CURRENT_THREAD; ++ } ++ ++ return TRANSFER_KERNEL; ++} ++ ++void gazelle_listen_thread(void *arg) ++{ ++ struct cfg_params *cfg_param = get_global_cfg_params(); ++ recv_pkts_from_other_process(cfg_param->process_idx, arg); ++} ++ ++void flow_init(void) ++{ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ init_listen_and_user_ports(); ++ ++ /* run to completion mode does not currently support multiple process */ ++ if (!use_ltran() && !get_global_cfg_params()->stack_mode_rtc) { ++ char name[PATH_MAX]; ++ sem_init(&stack_group->sem_listen_thread, 0, 0); ++ sprintf_s(name, sizeof(name), "%s", "listen_thread"); ++ struct sys_thread *thread = sys_thread_new(name, gazelle_listen_thread, ++ (void*)(&stack_group->sem_listen_thread), 0, 0); ++ free(thread); ++ sem_wait(&stack_group->sem_listen_thread); ++ } ++} +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index f78e48a..3703092 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -33,6 +33,7 @@ + #include "lstack_protocol_stack.h" + #include "gazelle_reg_msg.h" + #include "lstack_lwip.h" ++#include "lstack_flow.h" + #include "lstack_vdev.h" + + /* INUSE_TX_PKTS_WATERMARK < VDEV_RX_QUEUE_SZ; +-- +2.27.0 + diff --git a/0138-fix-coreddump-when-stack-setup-failed-in-rtc-mode.patch b/0138-fix-coreddump-when-stack-setup-failed-in-rtc-mode.patch new file mode 100644 index 0000000..1e4c192 --- /dev/null +++ b/0138-fix-coreddump-when-stack-setup-failed-in-rtc-mode.patch @@ -0,0 +1,66 @@ +From 52fafeafd51ed5363081064076dff4ed276a99c1 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Thu, 22 Feb 2024 21:22:44 +0800 +Subject: [PATCH] fix coreddump when stack setup failed in rtc mode + +--- + src/lstack/api/lstack_rtc_api.c | 6 +++--- + src/lstack/core/lstack_init.c | 11 +++++------ + 2 files changed, 8 insertions(+), 9 deletions(-) + +diff --git a/src/lstack/api/lstack_rtc_api.c b/src/lstack/api/lstack_rtc_api.c +index d29e51e..2e10e30 100644 +--- a/src/lstack/api/lstack_rtc_api.c ++++ b/src/lstack/api/lstack_rtc_api.c +@@ -45,7 +45,7 @@ int rtc_socket(int domain, int type, int protocol) + int ret; + + if (stack_setup_app_thread() < 0) { +- LSTACK_EXIT(1, "stack_setup_app_thread failed!\n"); ++ exit(1); + } + + /* need call stack thread init function */ +@@ -74,7 +74,7 @@ int rtc_shutdown(int fd, int how) + int rtc_epoll_create(int flags) + { + if (stack_setup_app_thread() < 0) { +- LSTACK_EXIT(1, "stack_setup_app_thread failed!\n"); ++ exit(1); + } + + return lstack_epoll_create(flags); +@@ -83,7 +83,7 @@ int rtc_epoll_create(int flags) + int rtc_epoll_create1(int flags) + { + if (stack_setup_app_thread() < 0) { +- LSTACK_EXIT(1, "stack_setup_app_thread failed!\n"); ++ exit(1); + } + + return lstack_epoll_create1(flags); +diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c +index 31fd91d..bd9ba8a 100644 +--- a/src/lstack/core/lstack_init.c ++++ b/src/lstack/core/lstack_init.c +@@ -109,12 +109,11 @@ static int32_t check_process_conflict(void) + + void gazelle_exit(void) + { +- if (!get_global_cfg_params()->stack_mode_rtc) { +- wrap_api_set_dummy(); +- /* 1: wait until app thread call send functio complete */ +- sleep(1); +- stack_group_exit(); +- } ++ wrap_api_set_dummy(); ++ /* 1: wait until app thread call send functio complete */ ++ sleep(1); ++ stack_group_exit(); ++ + if (!use_ltran()) { + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + dpdk_kni_release(); +-- +2.27.0 + diff --git a/0139-diff-udp-and-tcp-read-from-stack.patch b/0139-diff-udp-and-tcp-read-from-stack.patch new file mode 100644 index 0000000..ff642fe --- /dev/null +++ b/0139-diff-udp-and-tcp-read-from-stack.patch @@ -0,0 +1,277 @@ +From 472e2f00b3fda7dad4396704fd94715d91be4642 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Wed, 21 Feb 2024 04:25:43 +0800 +Subject: [PATCH] diff udp and tcp read from stack + +--- + src/lstack/core/lstack_lwip.c | 211 +++++++++++++++++++++++----------- + 1 file changed, 146 insertions(+), 65 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 50a3389..0b339fe 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -831,74 +831,96 @@ static struct pbuf *pbuf_free_partial(struct pbuf *pbuf, uint16_t free_len) + return pbuf; + } + +-ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags, +- struct sockaddr *addr, socklen_t *addrlen) ++static bool recv_break_for_err(struct lwip_sock *sock) + { +- size_t recv_left = len; +- struct pbuf *pbuf = NULL; +- ssize_t recvd = 0; +- uint32_t copy_len; +- struct lwip_sock *sock = get_socket_by_fd(fd); +- bool latency_enable = get_protocol_stack_group()->latency_start; +- +- if (sock->errevent > 0 && !NETCONN_IS_DATAIN(sock)) { +- errno = err_to_errno(netconn_err(sock->conn)); +- return -1; +- } ++ bool break_wait = (sock->errevent > 0) && (!NETCONN_IS_DATAIN(sock)); ++ errno = err_to_errno(netconn_err(sock->conn)); ++ return break_wait; ++} + +- thread_bind_stack(sock); ++static void recv_block_wait(struct lwip_sock *sock) ++{ ++ lstack_block_wait(sock->wakeup); ++} + +- if (sock->same_node_rx_ring != NULL) { +- return gazelle_same_node_ring_recv(sock, buf, len, flags); ++/* ++ * return 0 on success, -1 on error ++ * pbuf maybe NULL(tcp fin packet) ++ */ ++static int recv_ring_get_one(struct lwip_sock *sock, bool noblock, struct pbuf **pbuf) ++{ ++ if (sock->recv_lastdata != NULL) { ++ *pbuf = sock->recv_lastdata; ++ sock->recv_lastdata = NULL; ++ return 0; + } + +- while (recv_left > 0) { +- if (sock->recv_lastdata) { +- pbuf = sock->recv_lastdata; +- sock->recv_lastdata = NULL; ++ if (noblock) { ++ if (gazelle_ring_read(sock->recv_ring, (void **)pbuf, 1) != 1) { ++ errno = EAGAIN; ++ return -1; + } else { +- if (netconn_is_nonblocking(sock->conn)) { +- if (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1) { +- break; +- } +- } else { +- while (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1 && recvd == 0) { +- /* if the connection is disconnected, recv return 0 */ +- if (sock->errevent > 0 && !NETCONN_IS_DATAIN(sock)) { +- errno = err_to_errno(netconn_err(sock->conn)); +- return -1; +- } +- +- lstack_block_wait(sock->wakeup); +- } ++ return 0; ++ } ++ } else { ++ while (gazelle_ring_read(sock->recv_ring, (void **)pbuf, 1) != 1) { ++ if (recv_break_for_err(sock)) { ++ return -1; + } ++ recv_block_wait(sock); + } ++ return 0; ++ } ++} + +- /* if udp recv a packet whose len is 0, return 0 */ +- if (NETCONN_IS_UDP(sock) && pbuf->tot_len == 0) { +- return 0; ++/* return true: fin is read to user, false: pend fin */ ++static bool recv_ring_handle_fin(struct lwip_sock *sock, struct pbuf *pbuf, ssize_t recvd) ++{ ++ if (pbuf == NULL) { ++ if (recvd > 0) { ++ /* handle data first, then handle fin */ ++ sock->recv_lastdata = (void *)&fin_packet; ++ gazelle_ring_read_over(sock->recv_ring); ++ return false; + } ++ gazelle_ring_read_over(sock->recv_ring); ++ return true; ++ } ++ /* pending fin */ ++ if (pbuf == (void *)&fin_packet) { ++ return true; ++ } + +- /* fin */ +- if (unlikely(pbuf == NULL)) { +- if (recvd > 0) { +- /* read data first, then read fin */ +- sock->recv_lastdata = (void *)&fin_packet; +- gazelle_ring_read_over(sock->recv_ring); +- break; +- } +- gazelle_ring_read_over(sock->recv_ring); +- return 0; ++ return false; ++} ++ ++static ssize_t recv_ring_tcp_read(struct lwip_sock *sock, void *buf, size_t len, bool noblock) ++{ ++ ssize_t recvd = 0; ++ size_t recv_left = len; ++ uint32_t copy_len; ++ struct pbuf *pbuf = NULL; ++ ++ if (len == 0) { ++ return 0; ++ } ++ ++ while (recv_left > 0) { ++ if (recv_ring_get_one(sock, noblock, &pbuf) != 0) { ++ break; + } + +- /* pending fin */ +- if (unlikely(pbuf == (void *)&fin_packet)) { +- return 0; ++ if (unlikely((pbuf == NULL) || (pbuf == (void *)&fin_packet))) { ++ if (recv_ring_handle_fin(sock, pbuf, recvd)) { ++ return 0; ++ } else { ++ break; /* recvd > 0, pending fin, handle data */ ++ } + } + + copy_len = (recv_left > pbuf->tot_len) ? pbuf->tot_len : recv_left; + if (copy_len > UINT16_MAX) { +- copy_len = UINT16_MAX; ++ copy_len = UINT16_MAX; /* it's impossible to get here */ + } + pbuf_copy_partial(pbuf, (char *)buf + recvd, copy_len, 0); + +@@ -907,39 +929,98 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + + if (pbuf->tot_len > copy_len) { + sock->recv_lastdata = pbuf_free_partial(pbuf, copy_len); +- break; + } else { + if (sock->wakeup) { + sock->wakeup->stat.app_read_cnt += 1; + } +- if (latency_enable) { ++ ++ if (get_protocol_stack_group()->latency_start) { + calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK); + } +- gazelle_ring_read_over(sock->recv_ring); + +- /* in udp, if pbuf remaining len less than copy_len, discard these packets */ +- if (recvd > 0 && NETCONN_IS_UDP(sock)) { +- sock->stack->stats.sock_rx_drop++; +- break; +- } ++ gazelle_ring_read_over(sock->recv_ring); + } + } + +- /* rte_ring_count reduce lock */ +- if (sock->wakeup && sock->wakeup->type == WAKEUP_EPOLL && (sock->events & EPOLLIN) +- && (!NETCONN_IS_DATAIN(sock))) { +- del_sock_event(sock, EPOLLIN); ++ if (recvd > 0) { ++ errno = 0; ++ } else { ++ recvd = -1; + } + ++ return recvd; ++} ++ ++static ssize_t recv_ring_udp_read(struct lwip_sock *sock, void *buf, size_t len, bool noblock, ++ struct sockaddr *addr, socklen_t *addrlen) ++{ ++ size_t recv_left = len; ++ struct pbuf *pbuf = NULL; ++ uint32_t copy_len; ++ ++ sock->recv_lastdata = NULL; ++ ++ if (recv_ring_get_one(sock, noblock, &pbuf) != 0) { ++ /* errno have set */ ++ return -1; ++ } ++ ++ copy_len = (recv_left > pbuf->tot_len) ? pbuf->tot_len : recv_left; ++ pbuf_copy_partial(pbuf, (char *)buf, copy_len, 0); ++ /* drop remaining data if have */ ++ gazelle_ring_read_over(sock->recv_ring); ++ + if (pbuf && addr && addrlen) { + lwip_sock_make_addr(sock->conn, &(pbuf->addr), pbuf->port, addr, addrlen); + } + +- if (recvd == 0) { ++ if (copy_len < pbuf->tot_len) { ++ sock->stack->stats.sock_rx_drop++; ++ } ++ ++ if (sock->wakeup) { ++ sock->wakeup->stat.app_read_cnt++; ++ } ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK); ++ } ++ ++ return copy_len; ++} ++ ++ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags, ++ struct sockaddr *addr, socklen_t *addrlen) ++{ ++ ssize_t recvd = 0; ++ struct lwip_sock *sock = get_socket_by_fd(fd); ++ ++ if (recv_break_for_err(sock)) { ++ return -1; ++ } ++ ++ thread_bind_stack(sock); ++ ++ if (sock->same_node_rx_ring != NULL) { ++ return gazelle_same_node_ring_recv(sock, buf, len, flags); ++ } ++ ++ if (NETCONN_IS_UDP(sock)) { ++ recvd = recv_ring_udp_read(sock, buf, len, netconn_is_nonblocking(sock->conn), addr, addrlen); ++ } else { ++ recvd = recv_ring_tcp_read(sock, buf, len, netconn_is_nonblocking(sock->conn)); ++ } ++ ++ /* rte_ring_count reduce lock */ ++ if (sock->wakeup && sock->wakeup->type == WAKEUP_EPOLL && (sock->events & EPOLLIN) ++ && (!NETCONN_IS_DATAIN(sock))) { ++ del_sock_event(sock, EPOLLIN); ++ } ++ ++ if (recvd < 0) { + if (sock->wakeup) { + sock->wakeup->stat.read_null++; + } +- GAZELLE_RETURN(EAGAIN); ++ return -1; + } + return recvd; + } +-- +2.27.0 + diff --git a/0140-FAULT-INJECT-gazelle-add-packet-delay-and-packet-dro.patch b/0140-FAULT-INJECT-gazelle-add-packet-delay-and-packet-dro.patch new file mode 100644 index 0000000..cb42a61 --- /dev/null +++ b/0140-FAULT-INJECT-gazelle-add-packet-delay-and-packet-dro.patch @@ -0,0 +1,798 @@ +From f28b880f3be68377003c60005011a835eb18e105 Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Sun, 18 Feb 2024 17:11:05 +0800 +Subject: [PATCH] FAULT INJECT: gazelle add packet delay and packet drop + +--- + src/common/gazelle_dfx_msg.h | 15 ++ + src/common/gazelle_fault_inject_common.h | 75 +++++++ + src/lstack/Makefile | 5 + + src/lstack/core/lstack_control_plane.c | 13 +- + src/lstack/include/lstack_fault_inject.h | 20 ++ + src/lstack/include/lstack_vdev.h | 1 + + src/lstack/netif/dir.mk | 3 + + src/lstack/netif/lstack_fault_inject.c | 187 ++++++++++++++++ + src/lstack/netif/lstack_vdev.c | 2 +- + src/ltran/CMakeLists.txt | 5 + + src/ltran/ltran_dfx.c | 274 ++++++++++++++++++++++- + 11 files changed, 595 insertions(+), 5 deletions(-) + create mode 100644 src/common/gazelle_fault_inject_common.h + create mode 100644 src/lstack/include/lstack_fault_inject.h + create mode 100644 src/lstack/netif/lstack_fault_inject.c + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 7f8422a..8d528d6 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -18,6 +18,10 @@ + + #include + ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++#include "gazelle_fault_inject_common.h" ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ ++ + #define GAZELLE_CLIENT_NUM_MIN 1 + #define GAZELLE_LOG_LEVEL_MAX 10 + #define GAZELLECTL_TIMEOUT 5000 // millisecond +@@ -54,6 +58,11 @@ enum GAZELLE_STAT_MODE { + GAZELLE_STAT_LSTACK_SHOW_AGGREGATE, + GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES, + ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ GAZELLE_STAT_FAULT_INJECT_SET, ++ GAZELLE_STAT_FAULT_INJECT_UNSET, ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ ++ + GAZELLE_STAT_MODE_MAX, + }; + +@@ -277,6 +286,9 @@ struct gazelle_stack_dfx_data { + struct gazelle_stat_lstack_snmp snmp; + struct nic_eth_xstats nic_xstats; + struct nic_eth_features nic_features; ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ struct gazelle_fault_inject_data inject; ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ + } data; + }; + +@@ -307,6 +319,9 @@ struct gazelle_stat_msg_request { + union stat_param { + char log_level[GAZELLE_LOG_LEVEL_MAX]; + uint16_t low_power_mod; ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ struct gazelle_fault_inject_data inject; ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ + } data; + }; + +diff --git a/src/common/gazelle_fault_inject_common.h b/src/common/gazelle_fault_inject_common.h +new file mode 100644 +index 0000000..3a77f39 +--- /dev/null ++++ b/src/common/gazelle_fault_inject_common.h +@@ -0,0 +1,75 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++ ++#ifndef __GAZELLE_INJECT_COMMON_H__ ++#define __GAZELLE_INJECT_COMMON_H__ ++ ++#include ++ ++enum GAZELLE_FAULT_INJECT_TYPE { ++ GAZELLE_FAULT_INJECT_TYPE_ERR = 0, ++ GAZELLE_FAULT_INJECT_PACKET_DELAY, ++ GAZELLE_FAULT_INJECT_PACKET_LOSS, ++ GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE, ++ GAZELLE_FAULT_INJECT_PACKET_REORDER, ++ GAZELLE_FAULT_INJECT_TYPE_MAX, ++}; ++ ++enum GAZELLE_FAULT_INJECT_RULE { ++ INJECT_RULE_ERR = 0, ++ /* packet delay rule */ ++ INJECT_DELAY_RANDOM, ++ /* packet loss rule */ ++ INJECT_LOSS_RANDOM, ++ /* packet duplicate */ ++ INJECT_DUPLICATE_RANDOM, ++ /* packet reorder */ ++ INJECT_REORDER_RANDOM, ++}; ++ ++/* fault inject delay: packet delay's time and range, time unit is "ms" */ ++struct delay_data { ++ uint32_t delay_time; ++ uint32_t delay_range; ++}; ++ ++/* fault inject loss: packet loss rate */ ++struct loss_data { ++ double loss_rate; ++ uint32_t loss_sigle_count; ++}; ++ ++/* fault inject duplicate: packet duplicate rate and duplicate count */ ++struct duplicate_data { ++ double duplicate_rate; ++ uint32_t duplicate_sigle_count; ++}; ++ ++/* fault inject reorder: packet reorder rate and reorder count */ ++struct reorder_data { ++ double reorder_rate; ++ uint32_t reorder_sigle_count; ++}; ++ ++struct gazelle_fault_inject_data { ++ int32_t fault_inject_on; ++ enum GAZELLE_FAULT_INJECT_TYPE inject_type; ++ enum GAZELLE_FAULT_INJECT_RULE inject_rule; ++ union { ++ struct delay_data delay; ++ struct loss_data loss; ++ struct duplicate_data duplicate; ++ struct reorder_data reorder; ++ } inject_data; ++}; ++ ++#endif /* __GAZELLE_INJECT_COMMON_H__ */ +diff --git a/src/lstack/Makefile b/src/lstack/Makefile +index df1ddaa..d2c039d 100644 +--- a/src/lstack/Makefile ++++ b/src/lstack/Makefile +@@ -47,6 +47,11 @@ ifeq ($(GAZELLE_COVERAGE_ENABLE), 1) + CFLAGS += -fprofile-arcs -ftest-coverage + endif + ++ifeq ($(GAZELLE_FAULT_INJECT_ENABLE), 1) ++ LDFLAGS += -DGAZELLE_FAULT_INJECT_ENABLE ++ CFLAGS += -DGAZELLE_FAULT_INJECT_ENABLE ++endif ++ + ifeq ($(shell $(CC) -dumpmachine | cut -d"-" -f1), x86_64) + CFLAGS += -mssse3 + endif +diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c +index 025291d..783f21c 100644 +--- a/src/lstack/core/lstack_control_plane.c ++++ b/src/lstack/core/lstack_control_plane.c +@@ -34,6 +34,10 @@ + #include "lstack_protocol_stack.h" + #include "lstack_control_plane.h" + ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++#include "lstack_fault_inject.h" ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ ++ + /* intervals between two connection attempts and two registration attempts, in second */ + #define CONNECT_TO_LTRAN_INFINITE (-1) + #define CONNECT_TO_LTRAN_RETRY_INTERVAL 1 +@@ -582,7 +586,14 @@ static int32_t handle_stat_request(int32_t sockfd) + LSTACK_LOG(ERR, LSTACK, "recv wrong stat mode %d\n", (int32_t)msg.stat_mode); + return 0; + } +- ++ ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ if (msg.stat_mode == GAZELLE_STAT_FAULT_INJECT_SET || ++ msg.stat_mode == GAZELLE_STAT_FAULT_INJECT_UNSET) { ++ return handle_fault_inject_cmd(sockfd, &msg); ++ } ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ ++ + if (msg.stat_mode == GAZELLE_STAT_LSTACK_LOG_LEVEL_SET || + msg.stat_mode == GAZELLE_STAT_LSTACK_LOW_POWER_MDF) { + return handle_proc_cmd(sockfd, &msg); +diff --git a/src/lstack/include/lstack_fault_inject.h b/src/lstack/include/lstack_fault_inject.h +new file mode 100644 +index 0000000..d54f1f2 +--- /dev/null ++++ b/src/lstack/include/lstack_fault_inject.h +@@ -0,0 +1,20 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++ ++#ifndef __GAZELLE_INJECT_H__ ++#define __GAZELLE_INJECT_H__ ++ ++#include ++ ++int32_t handle_fault_inject_cmd(int32_t sockfd, struct gazelle_stat_msg_request *msg); ++ ++#endif /* __GAZELLE_INJECT_H__ */ +diff --git a/src/lstack/include/lstack_vdev.h b/src/lstack/include/lstack_vdev.h +index 4e5d191..1a8342a 100644 +--- a/src/lstack/include/lstack_vdev.h ++++ b/src/lstack/include/lstack_vdev.h +@@ -18,5 +18,6 @@ struct gazelle_quintuple; + enum reg_ring_type; + void vdev_dev_ops_init(struct lstack_dev_ops *dev_ops); + int vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple); ++uint32_t vdev_tx_xmit(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t nr_pkts); + + #endif /* _GAZELLE_VDEV_H_ */ +diff --git a/src/lstack/netif/dir.mk b/src/lstack/netif/dir.mk +index 20fb5d6..1e67734 100644 +--- a/src/lstack/netif/dir.mk ++++ b/src/lstack/netif/dir.mk +@@ -9,4 +9,7 @@ + # See the Mulan PSL v2 for more details. + + SRC = lstack_ethdev.c lstack_vdev.c lstack_flow.c ++ifeq ($(GAZELLE_FAULT_INJECT_ENABLE), 1) ++ SRC += lstack_fault_inject.c ++endif + $(eval $(call register_dir, netif, $(SRC))) +diff --git a/src/lstack/netif/lstack_fault_inject.c b/src/lstack/netif/lstack_fault_inject.c +new file mode 100644 +index 0000000..4daad10 +--- /dev/null ++++ b/src/lstack/netif/lstack_fault_inject.c +@@ -0,0 +1,187 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "lstack_cfg.h" ++#include "lstack_log.h" ++#include "lstack_vdev.h" ++ ++#define INJECT_MODULO 1000 /* used in modulus operator */ ++#define INJECT_US_TO_MS 1000 /* transefer time unit us to ms */ ++ ++typedef int32_t (*inject_xmit_func)(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data); ++struct inject_tbl { ++ struct gazelle_fault_inject_data inject_data; ++ inject_xmit_func inject_func; ++}; ++static struct inject_tbl g_inject_tbl[GAZELLE_FAULT_INJECT_TYPE_MAX]; ++ ++struct inject_func_tbl { ++ enum GAZELLE_FAULT_INJECT_TYPE type; ++ enum GAZELLE_FAULT_INJECT_RULE rule; ++ inject_xmit_func inject_func; ++}; ++ ++static int32_t inject_packet_delay_random(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data); ++static int32_t inject_packet_loss_random(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data); ++ ++static struct inject_func_tbl g_inject_func_tbl[] = { ++ {GAZELLE_FAULT_INJECT_PACKET_LOSS, INJECT_LOSS_RANDOM, inject_packet_loss_random}, ++ {GAZELLE_FAULT_INJECT_PACKET_DELAY, INJECT_DELAY_RANDOM, inject_packet_delay_random}, ++}; ++ ++static int32_t inject_func_tbl_update() ++{ ++ int32_t func_count = sizeof(g_inject_func_tbl) / sizeof(g_inject_func_tbl[0]); ++ ++ for (int32_t i = 0; i < GAZELLE_FAULT_INJECT_TYPE_MAX; ++i) { ++ if (!g_inject_tbl[i].inject_data.fault_inject_on) { ++ continue; ++ } ++ for (int32_t j = 0; j < func_count; ++j) { ++ if (g_inject_func_tbl[j].type == g_inject_tbl[i].inject_data.inject_type && ++ g_inject_func_tbl[j].rule == g_inject_tbl[i].inject_data.inject_rule) { ++ g_inject_tbl[i].inject_func = g_inject_func_tbl[j].inject_func; ++ } ++ } ++ } ++ return 0; ++} ++ ++static uint32_t inject_tx_xmit(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t nr_pkts) ++{ ++ for (int32_t i = 0; i < GAZELLE_FAULT_INJECT_TYPE_MAX; ++i) { ++ if (g_inject_tbl[i].inject_data.fault_inject_on) { ++ int32_t xmit_pkts = 0; ++ xmit_pkts = g_inject_tbl[i].inject_func(stack, pkts, nr_pkts, ++ g_inject_tbl[i].inject_data); ++ if (xmit_pkts == nr_pkts) { ++ continue; ++ } ++ return xmit_pkts; ++ } ++ } ++ if (rte_mbuf_refcnt_read(*pkts) == 1) { ++ return nr_pkts; ++ } ++ return vdev_tx_xmit(stack, pkts, nr_pkts); ++} ++ ++static int32_t inject_strategy_update() ++{ ++ inject_func_tbl_update(); ++ ++ int32_t inject_on = 0; ++ for (int32_t i = 0; i < GAZELLE_FAULT_INJECT_TYPE_MAX; ++i) { ++ if (g_inject_tbl[i].inject_data.fault_inject_on) { ++ inject_on = 1; ++ break; ++ } ++ } ++ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ ++ if (inject_on) { ++ for (uint32_t i = 0; i < stack_group->stack_num; ++i) { ++ struct protocol_stack *stack = stack_group->stacks[i]; ++ stack->dev_ops.tx_xmit = inject_tx_xmit; ++ } ++ return 0; ++ } ++ ++ for (uint32_t i = 0; i < stack_group->stack_num; ++i) { ++ struct protocol_stack *stack = stack_group->stacks[i]; ++ vdev_dev_ops_init(&stack->dev_ops); ++ } ++ ++ return 0; ++} ++ ++static int32_t inject_packet_delay_random(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data) ++{ ++ /* while *pkts->refcnt == 1, other inject type is on, and the packets have been loss. */ ++ if (rte_mbuf_refcnt_read(*pkts) == 1) { ++ return nr_pkts; ++ } ++ int32_t delay_time = data.inject_data.delay.delay_time; ++ int32_t delay_range = data.inject_data.delay.delay_range; ++ int32_t rand_num = rte_rand(); ++ rand_num %= INJECT_MODULO; ++ delay_time += delay_range * rand_num / INJECT_MODULO; ++ rte_delay_us(delay_time * INJECT_US_TO_MS); ++ ++ return nr_pkts; ++} ++ ++static int32_t inject_packet_loss_random(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data) ++{ ++ double loss_rate = data.inject_data.loss.loss_rate; ++ int32_t boundary = (int32_t) (loss_rate * INJECT_MODULO); ++ ++ uint32_t rand_num = rte_rand(); ++ rand_num %= INJECT_MODULO; ++ ++ if (rand_num > boundary) { ++ return nr_pkts; ++ } ++ ++ for (int32_t i = 0; i < nr_pkts; ++i) { ++ rte_pktmbuf_free(pkts[i]); ++ } ++ return nr_pkts; ++} ++ ++int32_t handle_fault_inject_cmd(int32_t sockfd, struct gazelle_stat_msg_request *msg) ++{ ++ struct gazelle_stack_dfx_data rsp = {0}; ++ int32_t ret = 0; ++ ++ ret = memcpy_s(&g_inject_tbl[msg->data.inject.inject_type].inject_data, ++ sizeof(struct gazelle_fault_inject_data), ++ &msg->data.inject, sizeof(struct gazelle_fault_inject_data)); ++ if (ret != EOK) { ++ LSTACK_LOG(ERR, LSTACK, "fault inject memcpy_s error, ret = %d", ret); ++ return -1; ++ } ++ ++ inject_strategy_update(); ++ ++ for (int32_t i = 0; i < GAZELLE_FAULT_INJECT_TYPE_MAX; ++i) { ++ ret = memcpy_s(&rsp.data.inject, sizeof(struct gazelle_fault_inject_data), ++ &g_inject_tbl[i].inject_data, sizeof(struct gazelle_fault_inject_data)); ++ if (ret != EOK) { ++ LSTACK_LOG(ERR, LSTACK, "fault inject memcpy_s error, ret = %d", ret); ++ return -1; ++ } ++ if (i == GAZELLE_FAULT_INJECT_TYPE_MAX -1) { ++ rsp.eof = 1; ++ } ++ ret = (int32_t) posix_api->write_fn(sockfd, (void *)&rsp, sizeof(rsp)); ++ if (ret <= 0) { ++ LSTACK_LOG(ERR, LSTACK, "write msg from peer failed, errno %d. ret=%d\n", errno, ret); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index 3703092..107ee8c 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -150,7 +150,7 @@ static uint32_t ltran_tx_xmit(struct protocol_stack *stack, struct rte_mbuf **pk + return sent_pkts; + } + +-static uint32_t vdev_tx_xmit(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t nr_pkts) ++uint32_t vdev_tx_xmit(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t nr_pkts) + { + uint32_t sent_pkts = 0; + +diff --git a/src/ltran/CMakeLists.txt b/src/ltran/CMakeLists.txt +index f739ceb..a484ae3 100644 +--- a/src/ltran/CMakeLists.txt ++++ b/src/ltran/CMakeLists.txt +@@ -27,6 +27,11 @@ if($ENV{GAZELLE_COVERAGE_ENABLE}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs") + endif($ENV{GAZELLE_COVERAGE_ENABLE}) + ++if($ENV{GAZELLE_FAULT_INJECT_ENABLE}) ++ message("Enable Fault inject option") ++ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGAZELLE_FAULT_INJECT_ENABLE") ++endif($ENV{GAZELLE_FAULT_INJECT_ENABLE}) ++ + execute_process( + COMMAND rpm -qa dpdk + OUTPUT_VARIABLE DPDK_VERSION_FULL +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 344afb2..413bf89 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -60,6 +60,46 @@ static struct gazelle_stat_ltran_total g_last_ltran_total; + static struct gazelle_stat_lstack_total g_last_lstack_total[GAZELLE_MAX_STACK_ARRAY_SIZE]; + static struct gazelle_stack_dfx_data g_last_lstack_data[GAZELLE_MAX_STACK_ARRAY_SIZE]; + ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++#define INJECT_NAME_SIZE 32 ++#define INJECT_RULE_SIZE 32 ++ ++typedef int32_t (*inject_parse_digit_fun)(char*, char*, struct gazelle_stat_msg_request *req_msg); ++static int32_t parse_inject_packet_delay_digit(char *time, char *range, struct gazelle_stat_msg_request *req_msg); ++static int32_t parse_inject_packet_loss_digit(char *rate, char *count, struct gazelle_stat_msg_request *req_msg); ++static int32_t parse_inject_packet_duplicate_digit(char *rate, char *count, struct gazelle_stat_msg_request *req_msg); ++static int32_t parse_inject_packet_reorder_digit(char *rate, char *count, struct gazelle_stat_msg_request *req_msg); ++ ++struct gazelle_fault_inject_type_list { ++ char inject_type_item[INJECT_NAME_SIZE]; ++ enum GAZELLE_FAULT_INJECT_TYPE inject_type_parsed; ++ inject_parse_digit_fun parse_digit_func; ++}; ++ ++static struct gazelle_fault_inject_type_list inject_type_list[] = { ++ {"delay", GAZELLE_FAULT_INJECT_PACKET_DELAY, parse_inject_packet_delay_digit}, ++ {"loss", GAZELLE_FAULT_INJECT_PACKET_LOSS, parse_inject_packet_loss_digit}, ++ {"duplicate", GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE, parse_inject_packet_duplicate_digit}, ++ {"reorder", GAZELLE_FAULT_INJECT_PACKET_REORDER, parse_inject_packet_reorder_digit}, ++}; ++ ++struct gazelle_fault_inject_rule_list { ++ char inject_rule_item[INJECT_RULE_SIZE]; ++ enum GAZELLE_FAULT_INJECT_RULE inject_rule_parsed; ++ enum GAZELLE_FAULT_INJECT_TYPE rule_parse_assit; ++}; ++ ++static struct gazelle_fault_inject_rule_list g_gazelle_fault_inject_rule_list[] = { ++ {"random", INJECT_DELAY_RANDOM, GAZELLE_FAULT_INJECT_PACKET_DELAY}, ++ {"random", INJECT_LOSS_RANDOM, GAZELLE_FAULT_INJECT_PACKET_LOSS}, ++ {"random", INJECT_DUPLICATE_RANDOM, GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE}, ++ {"random", INJECT_REORDER_RANDOM, GAZELLE_FAULT_INJECT_PACKET_REORDER}, ++}; ++ ++static void gazelle_print_fault_inject_set_status(void *buf, const struct gazelle_stat_msg_request *req_msg); ++ ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ ++ + static bool g_use_ltran = false; + + static char* g_unix_prefix; +@@ -95,6 +135,11 @@ static void gazelle_print_lstack_xstats(void *buf, const struct gazelle_stat_msg + static void gazelle_print_lstack_aggregate(void *buf, const struct gazelle_stat_msg_request *req_msg); + static void gazelle_print_lstack_nic_features(void *buf, const struct gazelle_stat_msg_request *req_msg); + ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++static void gazelle_print_fault_inject_set_status(void *buf, const struct gazelle_stat_msg_request *req_msg); ++static void gazelle_print_fault_inject_unset_status(void *buf, const struct gazelle_stat_msg_request *req_msg); ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ ++ + static struct gazelle_dfx_list g_gazelle_dfx_tbl[] = { + {GAZELLE_STAT_LTRAN_SHOW, sizeof(struct gazelle_stat_ltran_total), gazelle_print_ltran_stat_total}, + {GAZELLE_STAT_LTRAN_SHOW_RATE, sizeof(struct gazelle_stat_ltran_total), gazelle_print_ltran_stat_rate}, +@@ -121,6 +166,11 @@ static struct gazelle_dfx_list g_gazelle_dfx_tbl[] = { + {GAZELLE_STAT_LSTACK_SHOW_XSTATS, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_xstats}, + {GAZELLE_STAT_LSTACK_SHOW_AGGREGATE, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_aggregate}, + {GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_nic_features}, ++ ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ {GAZELLE_STAT_FAULT_INJECT_SET, sizeof(struct gazelle_stack_dfx_data), gazelle_print_fault_inject_set_status}, ++ {GAZELLE_STAT_FAULT_INJECT_UNSET, sizeof(struct gazelle_stack_dfx_data), gazelle_print_fault_inject_unset_status}, ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ + }; + + static int32_t g_wait_reply = 1; +@@ -1121,7 +1171,10 @@ static void show_usage(void) + { + printf("Usage: gazellectl [-h | help] \n" + " or: gazellectl ltran {quit | show | set} [LTRAN_OPTIONS] [-u UNIX_PREFIX]\n" +- " or: gazellectl lstack {show | set} ip [LSTACK_OPTIONS] [-u UNIX_PREFIX]\n \n" ++ " or: gazellectl lstack {show | set} ip [LSTACK_OPTIONS] [-u UNIX_PREFIX]\n\n" ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ " or: gazellectl inject [inject_type] [digit_param_1] [digit_param_2] [inject_rule]\n\n" ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ + " quit ltran process exit \n \n" + " where LTRAN_OPTIONS := \n" + " show: \n" +@@ -1146,7 +1199,13 @@ static void show_usage(void) + " set: \n" + " loglevel {error | info | debug} set lstack loglevel \n" + " lowpower {0 | 1} set lowpower enable \n" +- " [time] measure latency time default 1S, maximum 30mins \n"); ++ " [time] measure latency time default 1S, maximum 30mins \n\n" ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ " *inject params*\n" ++ " |inject_type | digit_param_1 | digit_param_2 | inject_rule |\n" ++ " | delay | delay_time(unit: ms) | delay_range(unit: ms) | random |\n" ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ ++ ); + } + + static int32_t parse_dfx_ltran_set_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) +@@ -1436,6 +1495,211 @@ static int32_t parse_dfx_lstack_args(int32_t argc, char *argv[], struct gazelle_ + return num_cmd; + } + ++ ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ ++#define GAZELLE_SET_FAULT_INJECT_PARAM_COUNT 6 ++#define GAZELLE_UNSET_FAULT_INJECT_PARAM_COUNT 4 ++#define INJECT_TYPE_INDEX 2 ++#define INJECT_DIGITAL_FIRST_INDEX 3 ++#define INJECT_DIGITAL_SECOND_INDEX 4 ++#define INJECT_RULE_INDEX 5 ++ ++ ++static void gazelle_print_fault_inject_type_info(struct gazelle_fault_inject_data *inject) ++{ ++ if (!inject->fault_inject_on) { ++ return; ++ } ++ ++ if (inject->inject_type == GAZELLE_FAULT_INJECT_PACKET_DELAY) { ++ printf("\t| inject_type: delay | delay_time: %-7d | delay_range: %-3d | " ++ "inject_rule: random |\n", inject->inject_data.delay.delay_time, ++ inject->inject_data.delay.delay_range); ++ } ++ ++#define INJECT_PERCENT 100 ++ ++ if (inject->inject_type == GAZELLE_FAULT_INJECT_PACKET_LOSS) { ++ printf("\t| inject_type: loss | loss_rate: %-3.1f%% | loss_single_count: %-3d | " ++ "inject_rule: random |\n", inject->inject_data.loss.loss_rate * INJECT_PERCENT, ++ inject->inject_data.loss.loss_sigle_count); ++ } ++ printf("\n"); ++} ++ ++static void gazelle_print_fault_inject_set_status(void *buf, const struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t ret; ++ struct gazelle_stack_dfx_data *stat = (struct gazelle_stack_dfx_data *)buf; ++ struct gazelle_fault_inject_data *inject = &stat->data.inject; ++ ++ printf("\n\n\t\t\t\t\t **** FAULT INJECT INFO **** \n\n"); ++ do { ++ gazelle_print_fault_inject_type_info(inject); ++ if (stat->eof != 0) { ++ break; ++ } ++ ret = dfx_stat_read_from_ltran(buf, sizeof(struct gazelle_stack_dfx_data), req_msg->stat_mode); ++ if (ret != GAZELLE_OK) { ++ return; ++ } ++ } while (true); ++} ++ ++static void gazelle_print_fault_inject_unset_status(void *buf, const struct gazelle_stat_msg_request *req_msg) ++{ ++ return; ++} ++ ++static int32_t parse_inject_packet_delay_digit(char* time, char* range, struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t parse_success = 0; ++ int32_t delay_time = atoi(time); ++ if (delay_time <= 0) { ++ printf("FAULT INJECT error: delay time error -- %d, need positive integer.\n", delay_time); ++ return parse_success; ++ } ++ req_msg->data.inject.inject_data.delay.delay_time = (uint32_t) delay_time; ++ ++ int32_t delay_range = atoi(range); ++ if (delay_range < 0) { ++ printf("FAULT INJECT error: delay range error -- %d, need positive integer.\n", delay_range); ++ return parse_success; ++ } ++ if (delay_time - delay_range <= 0) { ++ printf("FAULT INJECT error: delay range should lower than delay time.\n"); ++ return parse_success; ++ } ++ req_msg->data.inject.inject_data.delay.delay_range = delay_range; ++ ++ return ++parse_success; ++} ++ ++#define INJECT_RATE_LOWER 0.001 ++ ++static int32_t parse_inject_packet_loss_digit(char *rate, char *count, struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t parse_success = 0; ++ double loss_rate = atof(rate); ++ if (loss_rate < INJECT_RATE_LOWER || loss_rate >= 1) { ++ printf("FAULT INJECT error: loss rate error, range in [0.001, 1), now is %f\n", loss_rate); ++ return parse_success; ++ } ++ req_msg->data.inject.inject_data.loss.loss_rate = loss_rate; ++ ++ int32_t loss_counts = atoi(count); ++ if (loss_counts <= 0) { ++ printf("FAULT INJECT error: single loss counts wrong --%d, need positive integer.", loss_counts); ++ return parse_success; ++ } ++ req_msg->data.inject.inject_data.loss.loss_sigle_count = loss_counts; ++ ++ return ++parse_success; ++} ++ ++static int32_t parse_inject_packet_duplicate_digit(char *rate, char *count, struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t parse_success = 0; ++ double duplicate_rate = atof(rate); ++ if (duplicate_rate < INJECT_RATE_LOWER || duplicate_rate >= 1) { ++ printf("FAULT INJECT error: duplicate rate error, range in [0.001, 1), now is %f\n", duplicate_rate); ++ return parse_success; ++ } ++ req_msg->data.inject.inject_data.duplicate.duplicate_rate = duplicate_rate; ++ ++ int32_t duplicate_counts = atoi(count); ++ if (duplicate_counts <= 0) { ++ printf("FAULT INJECT error: single duplicate counts wrong --%d, need positive integer.", duplicate_counts); ++ return parse_success; ++ } ++ req_msg->data.inject.inject_data.duplicate.duplicate_sigle_count = duplicate_counts; ++ ++ return ++parse_success; ++} ++ ++static int32_t parse_inject_packet_reorder_digit(char *rate, char *count, struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t parse_success = 0; ++ double reorder_rate = atof(rate); ++ if (reorder_rate < INJECT_RATE_LOWER || reorder_rate >= 1) { ++ printf("FAULT INJECT error: reorder rate error, range in [0.001, 1), now is %f\n", reorder_rate); ++ return parse_success; ++ } ++ req_msg->data.inject.inject_data.reorder.reorder_rate = reorder_rate; ++ ++ int32_t reorder_counts = atoi(count); ++ if (reorder_counts <= 0) { ++ printf("FAULT INJECT error: single duplicate counts wrong --%d, need positive integer.", reorder_counts); ++ return parse_success; ++ } ++ req_msg->data.inject.inject_data.reorder.reorder_sigle_count = reorder_counts; ++ ++ return ++parse_success; ++} ++ ++static int32_t parse_fault_inject_digital_data(char *argv[], struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t parse_success = 0; ++ int32_t func_count = sizeof(inject_type_list) / sizeof(inject_type_list[0]); ++ for (int32_t i = 0; i < func_count; ++i) { ++ if (inject_type_list[i].inject_type_parsed == req_msg->data.inject.inject_type) { ++ parse_success = inject_type_list[i].parse_digit_func(argv[INJECT_DIGITAL_FIRST_INDEX], ++ argv[INJECT_DIGITAL_SECOND_INDEX], req_msg); ++ break; ++ } ++ } ++ ++ return parse_success; ++} ++ ++static int32_t parse_dfx_fault_inject_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t num_cmd = 0; /* while parse error, num_cmd will return as 0, or num_cmd should be returned as 1. */ ++ ++ req_msg->data.inject.fault_inject_on = 1; /* set fault inject on */ ++ ++ if (argc == GAZELLE_SET_FAULT_INJECT_PARAM_COUNT) { ++ req_msg->stat_mode = GAZELLE_STAT_FAULT_INJECT_SET; ++ } else if (argc == GAZELLE_UNSET_FAULT_INJECT_PARAM_COUNT) { ++ req_msg->stat_mode = GAZELLE_STAT_FAULT_INJECT_UNSET; ++ } else { ++ printf("FAULT_INJECT error: Count of params wrong , correct count is 6 or 4, now is %d\n", argc); ++ return num_cmd; ++ } ++ ++ int32_t inject_type_count = sizeof(inject_type_list) / sizeof(inject_type_list[0]); ++ for (int32_t i = 0; i < inject_type_count; ++i) { ++ if (strcmp(inject_type_list[i].inject_type_item, argv[INJECT_TYPE_INDEX]) == 0) { ++ req_msg->data.inject.inject_type = inject_type_list[i].inject_type_parsed; ++ break; ++ } ++ } ++ if (req_msg->data.inject.inject_type == GAZELLE_FAULT_INJECT_TYPE_ERR) { ++ printf("FAULT_INJECT error: input inject type is wrong -- %s\n", argv[INJECT_TYPE_INDEX]); ++ return num_cmd; ++ } ++ ++ int32_t inject_rule_count = sizeof(g_gazelle_fault_inject_rule_list) / sizeof(g_gazelle_fault_inject_rule_list[0]); ++ for (int32_t i = 0; i < inject_rule_count; ++i) { ++ if (strcmp(g_gazelle_fault_inject_rule_list[i].inject_rule_item, argv[INJECT_RULE_INDEX]) == 0 && ++ g_gazelle_fault_inject_rule_list[i].rule_parse_assit == req_msg->data.inject.inject_type) { ++ req_msg->data.inject.inject_rule = g_gazelle_fault_inject_rule_list[i].inject_rule_parsed; ++ break; ++ } ++ } ++ if (req_msg->data.inject.inject_rule == INJECT_RULE_ERR) { ++ printf("FAULT_INJECT error: input inject rule is wrong -- %s\n", argv[INJECT_RULE_INDEX]); ++ return num_cmd; ++ } ++ ++ num_cmd = parse_fault_inject_digital_data(argv, req_msg); ++ ++ return num_cmd; ++} ++ ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ ++ + static int32_t parse_dfx_cmd_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) + { + int32_t num_cmd = 0; +@@ -1451,7 +1715,11 @@ static int32_t parse_dfx_cmd_args(int32_t argc, char *argv[], struct gazelle_sta + if (strcmp(param, "lstack") == 0) { + num_cmd = parse_dfx_lstack_args(argc, argv, req_msg); + } +- ++#ifdef GAZELLE_FAULT_INJECT_ENABLE ++ if (strcmp(param, "inject") == 0) { ++ num_cmd = parse_dfx_fault_inject_args(argc, argv, req_msg); ++ } ++#endif /* GAZELLE_FAULT_INJECT_ENABLE */ + return num_cmd; + } + +-- +2.27.0 + diff --git a/0141-recv-support-MSG_DONTWAIT.patch b/0141-recv-support-MSG_DONTWAIT.patch new file mode 100644 index 0000000..403b96b --- /dev/null +++ b/0141-recv-support-MSG_DONTWAIT.patch @@ -0,0 +1,36 @@ +From 34c272bf7f0484a1371033c187719adc72f061d5 Mon Sep 17 00:00:00 2001 +From: li_yunqing +Date: Tue, 27 Feb 2024 16:58:59 +0800 +Subject: [PATCH] recv support MSG_DONTWAIT + +--- + src/lstack/core/lstack_lwip.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 0b339fe..7715cf3 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -993,6 +993,7 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + { + ssize_t recvd = 0; + struct lwip_sock *sock = get_socket_by_fd(fd); ++ bool noblock = (flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn); + + if (recv_break_for_err(sock)) { + return -1; +@@ -1005,9 +1006,9 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + } + + if (NETCONN_IS_UDP(sock)) { +- recvd = recv_ring_udp_read(sock, buf, len, netconn_is_nonblocking(sock->conn), addr, addrlen); ++ recvd = recv_ring_udp_read(sock, buf, len, noblock, addr, addrlen); + } else { +- recvd = recv_ring_tcp_read(sock, buf, len, netconn_is_nonblocking(sock->conn)); ++ recvd = recv_ring_tcp_read(sock, buf, len, noblock); + } + + /* rte_ring_count reduce lock */ +-- +2.27.0 + diff --git a/0142-do_setsockopt-function-no-longer-checks-the-results-.patch b/0142-do_setsockopt-function-no-longer-checks-the-results-.patch new file mode 100644 index 0000000..8a87350 --- /dev/null +++ b/0142-do_setsockopt-function-no-longer-checks-the-results-.patch @@ -0,0 +1,29 @@ +From 712a3c23451ed79449cea9322586d958c27c679f Mon Sep 17 00:00:00 2001 +From: jiangjixiang +Date: Fri, 1 Mar 2024 10:10:01 +0800 +Subject: [PATCH] do_setsockopt function no longer checks the results of the + kernel. + +--- + src/lstack/api/lstack_wrap.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 8992e39..1e36d3d 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -398,10 +398,7 @@ static inline int32_t do_setsockopt(int32_t s, int32_t level, int32_t optname, c + } + + /* we both set kernel and lwip */ +- int32_t ret = posix_api->setsockopt_fn(s, level, optname, optval, optlen); +- if (ret != 0) { +- return ret; +- } ++ posix_api->setsockopt_fn(s, level, optname, optval, optlen); + + return g_wrap_api->setsockopt_fn(s, level, optname, optval, optlen); + } +-- +2.27.0 + diff --git a/0143-FAUT-INJECT-add-fault-inject-unset-method.patch b/0143-FAUT-INJECT-add-fault-inject-unset-method.patch new file mode 100644 index 0000000..31a8c4b --- /dev/null +++ b/0143-FAUT-INJECT-add-fault-inject-unset-method.patch @@ -0,0 +1,254 @@ +From c2cf2ef0cc9f28a8322e17870d209f546ad6711d Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Mon, 4 Mar 2024 11:15:34 +0800 +Subject: [PATCH] FAUT INJECT: add fault inject unset method + +--- + src/lstack/core/lstack_control_plane.c | 2 +- + src/lstack/include/lstack_fault_inject.h | 2 +- + src/lstack/netif/lstack_fault_inject.c | 60 ++++++++++++---- + src/ltran/ltran_dfx.c | 92 +++++++++++++++++++++--- + 4 files changed, 131 insertions(+), 25 deletions(-) + +diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c +index 783f21c..9f0c313 100644 +--- a/src/lstack/core/lstack_control_plane.c ++++ b/src/lstack/core/lstack_control_plane.c +@@ -590,7 +590,7 @@ static int32_t handle_stat_request(int32_t sockfd) + #ifdef GAZELLE_FAULT_INJECT_ENABLE + if (msg.stat_mode == GAZELLE_STAT_FAULT_INJECT_SET || + msg.stat_mode == GAZELLE_STAT_FAULT_INJECT_UNSET) { +- return handle_fault_inject_cmd(sockfd, &msg); ++ return handle_fault_inject_cmd(sockfd, msg.data.inject, msg.stat_mode); + } + #endif /* GAZELLE_FAULT_INJECT_ENABLE */ + +diff --git a/src/lstack/include/lstack_fault_inject.h b/src/lstack/include/lstack_fault_inject.h +index d54f1f2..afd8faf 100644 +--- a/src/lstack/include/lstack_fault_inject.h ++++ b/src/lstack/include/lstack_fault_inject.h +@@ -15,6 +15,6 @@ + + #include + +-int32_t handle_fault_inject_cmd(int32_t sockfd, struct gazelle_stat_msg_request *msg); ++int32_t handle_fault_inject_cmd(int32_t sockfd, struct gazelle_fault_inject_data inject, enum GAZELLE_STAT_MODE stat_mode); + + #endif /* __GAZELLE_INJECT_H__ */ +diff --git a/src/lstack/netif/lstack_fault_inject.c b/src/lstack/netif/lstack_fault_inject.c +index 4daad10..41e7d95 100644 +--- a/src/lstack/netif/lstack_fault_inject.c ++++ b/src/lstack/netif/lstack_fault_inject.c +@@ -150,21 +150,10 @@ static int32_t inject_packet_loss_random(struct protocol_stack *stack, struct rt + return nr_pkts; + } + +-int32_t handle_fault_inject_cmd(int32_t sockfd, struct gazelle_stat_msg_request *msg) ++static int32_t inject_respond_msg(int32_t sockfd) + { + struct gazelle_stack_dfx_data rsp = {0}; + int32_t ret = 0; +- +- ret = memcpy_s(&g_inject_tbl[msg->data.inject.inject_type].inject_data, +- sizeof(struct gazelle_fault_inject_data), +- &msg->data.inject, sizeof(struct gazelle_fault_inject_data)); +- if (ret != EOK) { +- LSTACK_LOG(ERR, LSTACK, "fault inject memcpy_s error, ret = %d", ret); +- return -1; +- } +- +- inject_strategy_update(); +- + for (int32_t i = 0; i < GAZELLE_FAULT_INJECT_TYPE_MAX; ++i) { + ret = memcpy_s(&rsp.data.inject, sizeof(struct gazelle_fault_inject_data), + &g_inject_tbl[i].inject_data, sizeof(struct gazelle_fault_inject_data)); +@@ -185,3 +174,50 @@ int32_t handle_fault_inject_cmd(int32_t sockfd, struct gazelle_stat_msg_request + return 0; + } + ++static int32_t inject_unset_cmd(int32_t sockfd, struct gazelle_fault_inject_data inject) ++{ ++ if (inject.inject_type == GAZELLE_FAULT_INJECT_TYPE_MAX) { ++ /* means unset all kinds of fault inject type */ ++ for (int32_t i = 0; i < GAZELLE_FAULT_INJECT_TYPE_MAX; ++i) { ++ g_inject_tbl[i].inject_data.fault_inject_on = 0; ++ } ++ } else { ++ int32_t ret = 0; ++ ret = memcpy_s(&g_inject_tbl[inject.inject_type].inject_data, ++ sizeof(struct gazelle_fault_inject_data), ++ &inject, sizeof(struct gazelle_fault_inject_data)); ++ if (ret != EOK) { ++ LSTACK_LOG(ERR, LSTACK, "fault inject memcpy_s error, ret = %d", ret); ++ return -1; ++ } ++ } ++ ++ inject_strategy_update(); ++ ++ return inject_respond_msg(sockfd); ++} ++ ++static int32_t inject_set_cmd(int32_t sockfd, struct gazelle_fault_inject_data inject) ++{ ++ int32_t ret = 0; ++ ret = memcpy_s(&g_inject_tbl[inject.inject_type].inject_data, ++ sizeof(struct gazelle_fault_inject_data), ++ &inject, sizeof(struct gazelle_fault_inject_data)); ++ if (ret != EOK) { ++ LSTACK_LOG(ERR, LSTACK, "fault inject memcpy_s error, ret = %d", ret); ++ return -1; ++ } ++ ++ inject_strategy_update(); ++ ++ return inject_respond_msg(sockfd); ++} ++ ++int32_t handle_fault_inject_cmd(int32_t sockfd, struct gazelle_fault_inject_data inject, enum GAZELLE_STAT_MODE stat_mode) ++{ ++ if (stat_mode == GAZELLE_STAT_FAULT_INJECT_UNSET) { ++ return inject_unset_cmd(sockfd, inject); ++ } ++ return inject_set_cmd(sockfd, inject); ++} ++ +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 413bf89..96509e5 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -97,7 +97,7 @@ static struct gazelle_fault_inject_rule_list g_gazelle_fault_inject_rule_list[] + }; + + static void gazelle_print_fault_inject_set_status(void *buf, const struct gazelle_stat_msg_request *req_msg); +- ++static void gazelle_print_fault_inject_unset_status(void *buf, const struct gazelle_stat_msg_request *req_msg); + #endif /* GAZELLE_FAULT_INJECT_ENABLE */ + + static bool g_use_ltran = false; +@@ -1504,6 +1504,7 @@ static int32_t parse_dfx_lstack_args(int32_t argc, char *argv[], struct gazelle_ + #define INJECT_DIGITAL_FIRST_INDEX 3 + #define INJECT_DIGITAL_SECOND_INDEX 4 + #define INJECT_RULE_INDEX 5 ++#define INJECT_UNSET_TYPE_INDEX 3 + + + static void gazelle_print_fault_inject_type_info(struct gazelle_fault_inject_data *inject) +@@ -1549,6 +1550,33 @@ static void gazelle_print_fault_inject_set_status(void *buf, const struct gazell + + static void gazelle_print_fault_inject_unset_status(void *buf, const struct gazelle_stat_msg_request *req_msg) + { ++ int32_t ret; ++ static int32_t inject_enable[GAZELLE_FAULT_INJECT_TYPE_MAX]; ++ struct gazelle_stack_dfx_data *stat = (struct gazelle_stack_dfx_data *)buf; ++ struct gazelle_fault_inject_data *inject = &stat->data.inject; ++ ++ printf("\n\t\t\t\t\t **** INJECT ENABLE ITEM **** \n\n"); ++ do { ++ inject_enable[inject->inject_type] = inject->fault_inject_on; ++ gazelle_print_fault_inject_type_info(inject); ++ if (stat->eof != 0) { ++ break; ++ } ++ ret = dfx_stat_read_from_ltran(buf, sizeof(struct gazelle_stack_dfx_data), req_msg->stat_mode); ++ if (ret != GAZELLE_OK) { ++ return; ++ } ++ } while (true); ++ ++ printf("\n\n\t\t\t\t\t **** INJECT DISABLE ITEM **** \n\n"); ++ printf("\tThe currently closed inject types are: "); ++ for (int32_t i = 1; i < GAZELLE_FAULT_INJECT_TYPE_MAX; ++i) { ++ if (!inject_enable[i]) { ++ /* i - 1 means fault inject type mapping inject_type_item name */ ++ printf("\"%s\" ", inject_type_list[i - 1].inject_type_item); ++ } ++ } ++ printf("\n"); + return; + } + +@@ -1653,21 +1681,45 @@ static int32_t parse_fault_inject_digital_data(char *argv[], struct gazelle_stat + return parse_success; + } + +-static int32_t parse_dfx_fault_inject_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) ++static int32_t parse_fault_inject_unset_type(char *argv[], struct gazelle_stat_msg_request *req_msg) + { +- int32_t num_cmd = 0; /* while parse error, num_cmd will return as 0, or num_cmd should be returned as 1. */ +- +- req_msg->data.inject.fault_inject_on = 1; /* set fault inject on */ ++ int32_t num_cmd = 0; ++ ++ if (strcmp(argv[INJECT_TYPE_INDEX], "unset") != 0) { ++ printf("FAULT_INJECT error: unrecognized input -- %s, should be \"unset\"\n", argv[INJECT_TYPE_INDEX]); ++ return num_cmd; ++ } ++ ++ req_msg->data.inject.fault_inject_on = 0; /* unset fault inject */ ++ req_msg->stat_mode = GAZELLE_STAT_FAULT_INJECT_UNSET; ++ ++ if (strcmp(argv[INJECT_UNSET_TYPE_INDEX], "all") == 0) { ++ req_msg->data.inject.inject_type = GAZELLE_FAULT_INJECT_TYPE_MAX; ++ return ++num_cmd; ++ } + +- if (argc == GAZELLE_SET_FAULT_INJECT_PARAM_COUNT) { +- req_msg->stat_mode = GAZELLE_STAT_FAULT_INJECT_SET; +- } else if (argc == GAZELLE_UNSET_FAULT_INJECT_PARAM_COUNT) { +- req_msg->stat_mode = GAZELLE_STAT_FAULT_INJECT_UNSET; +- } else { +- printf("FAULT_INJECT error: Count of params wrong , correct count is 6 or 4, now is %d\n", argc); ++ int32_t inject_type_count = sizeof(inject_type_list) / sizeof(inject_type_list[0]); ++ for (int32_t i = 0; i < inject_type_count; ++i) { ++ if (strcmp(inject_type_list[i].inject_type_item, argv[INJECT_UNSET_TYPE_INDEX]) == 0) { ++ req_msg->data.inject.inject_type = inject_type_list[i].inject_type_parsed; ++ break; ++ } ++ } ++ if (req_msg->data.inject.inject_type == GAZELLE_FAULT_INJECT_TYPE_ERR) { ++ printf("FAULT_INJECT error: input inject type is wrong -- %s\n", argv[INJECT_TYPE_INDEX]); + return num_cmd; + } + ++ return ++num_cmd; ++} ++ ++static int32_t parse_fault_inject_set_type(char *argv[], struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t num_cmd = 0; ++ ++ req_msg->data.inject.fault_inject_on = 1; /* set fault inject on */ ++ req_msg->stat_mode = GAZELLE_STAT_FAULT_INJECT_SET; ++ + int32_t inject_type_count = sizeof(inject_type_list) / sizeof(inject_type_list[0]); + for (int32_t i = 0; i < inject_type_count; ++i) { + if (strcmp(inject_type_list[i].inject_type_item, argv[INJECT_TYPE_INDEX]) == 0) { +@@ -1698,6 +1750,24 @@ static int32_t parse_dfx_fault_inject_args(int32_t argc, char *argv[], struct ga + return num_cmd; + } + ++static int32_t parse_dfx_fault_inject_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t num_cmd = 0; /* while parse error, num_cmd will return as 0, or num_cmd should be returned as 1. */ ++ ++ if (argc == GAZELLE_UNSET_FAULT_INJECT_PARAM_COUNT) { ++ num_cmd = parse_fault_inject_unset_type(argv, req_msg); ++ return num_cmd; ++ } ++ ++ if (argc == GAZELLE_SET_FAULT_INJECT_PARAM_COUNT) { ++ num_cmd = parse_fault_inject_set_type(argv, req_msg); ++ return num_cmd; ++ } ++ ++ printf("FAULT_INJECT error: Count of params wrong , correct count is 6 or 4, now is %d\n", argc); ++ return num_cmd; ++} ++ + #endif /* GAZELLE_FAULT_INJECT_ENABLE */ + + static int32_t parse_dfx_cmd_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) +-- +2.27.0 + diff --git a/0144-support-udp-pkglen-mtu.patch b/0144-support-udp-pkglen-mtu.patch new file mode 100644 index 0000000..c03fd04 --- /dev/null +++ b/0144-support-udp-pkglen-mtu.patch @@ -0,0 +1,85 @@ +From 5ba19529acaf76a681313245a9a278356b615687 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 4 Mar 2024 14:10:43 +0800 +Subject: [PATCH] support udp pkglen > mtu + +--- + src/lstack/core/lstack_lwip.c | 20 ++++++++++++++++++-- + src/lstack/include/lstack_dpdk.h | 2 +- + 2 files changed, 19 insertions(+), 3 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 7715cf3..f4199f8 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -252,6 +252,13 @@ struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_s + return NULL; + } + ++ /* udp send a pbuf chain, dequeue all pbufs except head pbuf */ ++ if (NETCONN_IS_UDP(sock) && remain_size > MBUF_MAX_DATA_LEN) { ++ int size = (remain_size + MBUF_MAX_DATA_LEN - 1) / MBUF_MAX_DATA_LEN - 1; ++ struct pbuf *pbuf_used[size]; ++ gazelle_ring_sc_dequeue(sock->send_ring, (void **)&pbuf_used, size); ++ } ++ + if (get_protocol_stack_group()->latency_start) { + calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_WRITE_LWIP); + } +@@ -285,7 +292,7 @@ void do_lwip_get_from_sendring_over(struct lwip_sock *sock) + sock->stack->stats.write_lwip_cnt++; + } + +-static ssize_t do_app_write(struct pbuf *pbufs[], void *buf, size_t len, uint32_t write_num) ++static ssize_t do_app_write(struct lwip_sock *sock, struct pbuf *pbufs[], void *buf, size_t len, uint32_t write_num) + { + ssize_t send_len = 0; + uint32_t i = 0; +@@ -297,6 +304,11 @@ static ssize_t do_app_write(struct pbuf *pbufs[], void *buf, size_t len, uint32_ + rte_memcpy((char *)pbufs[i]->payload, (char *)buf + send_len, MBUF_MAX_DATA_LEN); + pbufs[i]->tot_len = pbufs[i]->len = MBUF_MAX_DATA_LEN; + send_len += MBUF_MAX_DATA_LEN; ++ ++ /* if udp pkg len > mtu, use pbuf chain to send it */ ++ if (NETCONN_IS_UDP(sock) && i > 0) { ++ pbuf_cat(pbufs[0], pbufs[i]); ++ } + } + + /* reduce the branch in loop */ +@@ -305,6 +317,10 @@ static ssize_t do_app_write(struct pbuf *pbufs[], void *buf, size_t len, uint32_ + pbufs[i]->tot_len = pbufs[i]->len = copy_len; + send_len += copy_len; + ++ if (NETCONN_IS_UDP(sock) && i > 0) { ++ pbuf_cat(pbufs[0], pbufs[i]); ++ } ++ + return send_len; + } + +@@ -320,7 +336,7 @@ static inline ssize_t app_buff_write(struct lwip_sock *sock, void *buf, size_t l + time_stamp_into_pbuf(write_num, pbufs, time_stamp); + } + +- ssize_t send_len = do_app_write(pbufs, buf, len, write_num); ++ ssize_t send_len = do_app_write(sock, pbufs, buf, len, write_num); + + if (addr) { + if (addr->sa_family == AF_INET) { +diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h +index c40f3c0..c7cfbdf 100644 +--- a/src/lstack/include/lstack_dpdk.h ++++ b/src/lstack/include/lstack_dpdk.h +@@ -21,7 +21,7 @@ + + #define KNI_NB_MBUF (DEFAULT_RING_SIZE << 4) + +-#define MAX_PACKET_SZ 1530 ++#define MAX_PACKET_SZ 1538 + + #define RING_SIZE(x) ((x) - 1) + +-- +2.27.0 + diff --git a/0145-add-limit-with-level-for-sockopt.patch b/0145-add-limit-with-level-for-sockopt.patch new file mode 100644 index 0000000..c58bbc7 --- /dev/null +++ b/0145-add-limit-with-level-for-sockopt.patch @@ -0,0 +1,86 @@ +From 5e4b2366417b5f951ffd5ee45c0917ae67bd502e Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Sun, 3 Mar 2024 21:40:23 +0800 +Subject: [PATCH] add limit with level for sockopt + +--- + src/lstack/api/lstack_wrap.c | 49 +++++++++++++++++++++++++----------- + 2 files changed, 35 insertions(+), 16 deletions(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 1e36d3d..49bbf91 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -364,27 +364,46 @@ static inline int32_t do_getsockname(int32_t s, struct sockaddr *name, socklen_t + return posix_api->getsockname_fn(s, name, namelen); + } + +-static bool unsupport_optname(int32_t optname) +-{ +- if (optname == SO_BROADCAST || +- optname == SO_PROTOCOL || +- optname == TCP_QUICKACK || +- optname == SO_SNDTIMEO || +- optname == SO_RCVTIMEO || +- optname == SO_SNDBUF || +- optname == SO_RCVBUF || +- optname == TCP_INFO || +- optname == TCP_MAXSEG || +- optname == SO_DONTROUTE || +- optname == TCP_CONGESTION) { ++static bool unsupport_tcp_optname(int32_t optname) ++{ ++ if ((optname == TCP_QUICKACK) || ++ (optname == TCP_INFO) || ++ (optname == TCP_MAXSEG) || ++ (optname == TCP_CONGESTION)) { ++ return true; ++ } ++ return false; ++} ++ ++static bool unsupport_socket_optname(int32_t optname) ++{ ++ if ((optname == SO_BROADCAST) || ++ (optname == SO_PROTOCOL) || ++ (optname == SO_SNDTIMEO) || ++ (optname == SO_RCVTIMEO) || ++ (optname == SO_SNDBUF) || ++ (optname == SO_RCVBUF) || ++ (optname == SO_DONTROUTE)) { + return true; + } + return false; + } + ++static bool unsupport_optname(int32_t level, int32_t optname) ++{ ++ if (level == SOL_TCP) { ++ return unsupport_tcp_optname(optname); ++ } ++ ++ if (level == SOL_SOCKET) { ++ return unsupport_socket_optname(optname); ++ } ++ return false; ++} ++ + static inline int32_t do_getsockopt(int32_t s, int32_t level, int32_t optname, void *optval, socklen_t *optlen) + { +- if (select_fd_posix_path(s, NULL) == PATH_LWIP && !unsupport_optname(optname)) { ++ if (select_fd_posix_path(s, NULL) == PATH_LWIP && !unsupport_optname(level, optname)) { + return g_wrap_api->getsockopt_fn(s, level, optname, optval, optlen); + } + +@@ -393,7 +412,7 @@ static inline int32_t do_getsockopt(int32_t s, int32_t level, int32_t optname, v + + static inline int32_t do_setsockopt(int32_t s, int32_t level, int32_t optname, const void *optval, socklen_t optlen) + { +- if (select_fd_posix_path(s, NULL) == PATH_KERNEL || unsupport_optname(optname)) { ++ if (select_fd_posix_path(s, NULL) == PATH_KERNEL || unsupport_optname(level, optname)) { + return posix_api->setsockopt_fn(s, level, optname, optval, optlen); + } + +-- +2.27.0 + diff --git a/0146-udp-add-restriction-message-too-long.patch b/0146-udp-add-restriction-message-too-long.patch new file mode 100644 index 0000000..a74c49c --- /dev/null +++ b/0146-udp-add-restriction-message-too-long.patch @@ -0,0 +1,42 @@ +From a37c451e63bed06a70e887aba6364183d71f414f Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 11 Mar 2024 11:18:54 +0800 +Subject: [PATCH] udp add restriction: message too long + +--- + src/common/gazelle_opt.h | 2 ++ + src/lstack/core/lstack_lwip.c | 5 +++++ + 2 files changed, 7 insertions(+) + +diff --git a/src/common/gazelle_opt.h b/src/common/gazelle_opt.h +index 1d1c5f5..6d787b9 100644 +--- a/src/common/gazelle_opt.h ++++ b/src/common/gazelle_opt.h +@@ -60,6 +60,8 @@ + + #define DPDK_PKT_BURST_SIZE 512 + ++#define GAZELLE_UDP_PKGLEN_MAX (65535 - IP_HLEN - UDP_HLEN) ++ + /* total:33 client, index 32 is invaild client */ + #define GAZELLE_CLIENT_NUM_ALL 33 + #define GAZELLE_NULL_CLIENT (GAZELLE_CLIENT_NUM_ALL - 1) +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index f4199f8..8aae433 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -779,6 +779,11 @@ ssize_t do_lwip_send_to_stack(int32_t fd, const void *buf, size_t len, int32_t f + return 0; + } + ++ if (NETCONN_IS_UDP(sock) && (len > GAZELLE_UDP_PKGLEN_MAX)) { ++ LSTACK_LOG(ERR, LSTACK, "Message too long\n"); ++ GAZELLE_RETURN(EMSGSIZE); ++ } ++ + thread_bind_stack(sock); + + if (sock->same_node_tx_ring != NULL) { +-- +2.27.0 + diff --git a/0147-dfx-improve-log-readability-when-connect-ltran-lstac.patch b/0147-dfx-improve-log-readability-when-connect-ltran-lstac.patch new file mode 100644 index 0000000..f21edae --- /dev/null +++ b/0147-dfx-improve-log-readability-when-connect-ltran-lstac.patch @@ -0,0 +1,269 @@ +From 9d68f6bca1adfba6802e85aa213dbba5002cb289 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Tue, 27 Feb 2024 22:48:19 +0800 +Subject: [PATCH] dfx: improve log readability when connect ltran/lstack failed + +--- + src/ltran/ltran_dfx.c | 152 +++++++++++++++++++++++++++--------------- + 1 file changed, 99 insertions(+), 53 deletions(-) + +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 96509e5..a429866 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -101,6 +101,8 @@ static void gazelle_print_fault_inject_unset_status(void *buf, const struct gaze + #endif /* GAZELLE_FAULT_INJECT_ENABLE */ + + static bool g_use_ltran = false; ++static char g_ltran_unix_path[PATH_MAX]; ++static char g_lstack_unix_path[PATH_MAX]; + + static char* g_unix_prefix; + +@@ -268,24 +270,16 @@ static void gazelle_print_ltran_sock(void *buf, const struct gazelle_stat_msg_re + printf("ltran sock table num: %u\n", table->conn_num); + } + +-static int32_t dfx_connect_ltran(bool use_ltran, bool probe) ++static int dfx_make_unix_addr(struct sockaddr_un *addr, bool use_ltran) + { +- int32_t ret, fd; +- struct sockaddr_un addr; +- +- fd = socket(AF_UNIX, SOCK_STREAM, 0); +- if (fd == -1) { +- printf("create socket failed. errno: %d\n", errno); +- return GAZELLE_ERR; +- } +- +- ret = memset_s(&addr, sizeof(addr), 0, sizeof(struct sockaddr_un)); ++ int ret; ++ ret = memset_s(addr, sizeof(*addr), 0, sizeof(struct sockaddr_un)); + if (ret != EOK) { + printf("%s:%d memset_s fail ret=%d\n", __FUNCTION__, __LINE__, ret); + goto END; + } + +- ret = strncpy_s(addr.sun_path, sizeof(addr.sun_path), GAZELLE_RUN_DIR, ++ ret = strncpy_s(addr->sun_path, sizeof(addr->sun_path), GAZELLE_RUN_DIR, + strlen(GAZELLE_RUN_DIR) + 1); + if (ret != EOK) { + printf("%s:%d strncpy_s fail ret=%d\n", __FUNCTION__, __LINE__, ret); +@@ -293,7 +287,7 @@ static int32_t dfx_connect_ltran(bool use_ltran, bool probe) + } + + if (g_unix_prefix) { +- ret = strncat_s(addr.sun_path, sizeof(addr.sun_path), g_unix_prefix, ++ ret = strncat_s(addr->sun_path, sizeof(addr->sun_path), g_unix_prefix, + strlen(g_unix_prefix) + 1); + if (ret != EOK) { + printf("%s:%d strncat_s fail ret=%d\n", __FUNCTION__, __LINE__, ret); +@@ -301,43 +295,89 @@ static int32_t dfx_connect_ltran(bool use_ltran, bool probe) + } + } + +- addr.sun_family = AF_UNIX; ++ addr->sun_family = AF_UNIX; + if (use_ltran) { +- ret = strncat_s(addr.sun_path, sizeof(addr.sun_path), LTRAN_DFX_SOCK_FILENAME, ++ ret = strncat_s(addr->sun_path, sizeof(addr->sun_path), LTRAN_DFX_SOCK_FILENAME, + strlen(LTRAN_DFX_SOCK_FILENAME) + 1); + if (ret != EOK) { + printf("%s:%d strncat_s fail ret=%d\n", __FUNCTION__, __LINE__, ret); + goto END; + } ++ memcpy_s(g_ltran_unix_path, PATH_MAX, addr->sun_path, sizeof(addr->sun_path)); + } else { +- ret = strncat_s(addr.sun_path, sizeof(addr.sun_path), LSTACK_DFX_SOCK_FILENAME, ++ ret = strncat_s(addr->sun_path, sizeof(addr->sun_path), LSTACK_DFX_SOCK_FILENAME, + strlen(LSTACK_DFX_SOCK_FILENAME) + 1); + if (ret != EOK) { + printf("%s:%d strncat_s fail ret=%d\n", __FUNCTION__, __LINE__, ret); + goto END; + } ++ memcpy_s(g_lstack_unix_path, PATH_MAX, addr->sun_path, sizeof(addr->sun_path)); + } ++ return 0; ++END: ++ return -1; ++} ++ ++static int32_t dfx_connect_server(bool use_ltran) ++{ ++ int32_t ret, fd; ++ struct sockaddr_un addr; ++ ++ fd = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (fd == -1) { ++ printf("create socket failed. errno: %d\n", errno); ++ return GAZELLE_ERR; ++ } ++ ++ ret = dfx_make_unix_addr(&addr, use_ltran); ++ if (ret != 0) { ++ goto END; ++ } + + ret = connect(fd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)); +- if (ret == -1) { +- if (!probe) { +- printf("connect ltran failed. errno: %d ret=%d\n", errno, ret); +- printf("You may need to use the -u parameter to specify the UNIX_PREFIX that matches the configuration.\n"); +- } ++ if (ret != 0) { + goto END; + } + + return fd; + END: ++ ret = errno; + close(fd); +- return GAZELLE_ERR; ++ return -ret; ++} ++ ++static int dfx_connect_probe(void) ++{ ++ int32_t ret1; ++ int32_t ret2; ++ ret1 = dfx_connect_server(true); ++ if (ret1 > 0) { ++ close(ret1); ++ return 1; ++ } ++ ret2 = dfx_connect_server(false); ++ if (ret2 > 0) { ++ close(ret2); ++ return 0; ++ } ++ ++ printf("Connect lstack(path:%s), errno: %d; Connect ltran(path:%s) failed, errno: %d\n", ++ g_lstack_unix_path, -ret2, g_ltran_unix_path, -ret1); ++ printf("Please ensure the process is started; If use ltran mode, \ ++ set use_ltran=1 in lstack.conf, otherwise set use_ltran=0\n"); ++ return -1; + } + + static int32_t dfx_stat_conn_to_ltran(struct gazelle_stat_msg_request *req_msg) + { +- int32_t fd = dfx_connect_ltran(g_use_ltran, false); ++ int32_t fd = dfx_connect_server(g_use_ltran); + if (fd < 0) { +- return fd; ++ if (g_use_ltran) { ++ printf("Connect ltran(path:%s) failed. errno: %d\n", g_ltran_unix_path, -fd); ++ } else { ++ printf("Connect lstack(path:%s) failed. errno: %d\n", g_lstack_unix_path, -fd); ++ } ++ return GAZELLE_ERR; + } + + int32_t ret = write_specied_len(fd, (char *)req_msg, sizeof(*req_msg)); +@@ -1417,12 +1457,12 @@ static int32_t parse_dfx_lstack_show_args(int32_t argc, char *argv[], struct gaz + char *param = argv[GAZELLE_OPTIONS1_ARG_IDX]; + if (strcmp(param, "rate") == 0 || strcmp(param, "-r") == 0) { + if (g_use_ltran) { +- req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LTRAN_SHOW_LB_RATE; ++ req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LTRAN_SHOW_LB_RATE; + } else { +- req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LTRAN_START_LATENCY; +- req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LTRAN_STOP_LATENCY; +- req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_RATE; +- } ++ req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LTRAN_START_LATENCY; ++ req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LTRAN_STOP_LATENCY; ++ req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_RATE; ++ } + req_msg[cmd_index++].stat_mode = GAZELLE_STAT_MODE_MAX; + } else if (strcmp(param, "snmp") == 0 || strcmp(param, "-s") == 0) { + req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_SNMP; +@@ -1495,7 +1535,6 @@ static int32_t parse_dfx_lstack_args(int32_t argc, char *argv[], struct gazelle_ + return num_cmd; + } + +- + #ifdef GAZELLE_FAULT_INJECT_ENABLE + + #define GAZELLE_SET_FAULT_INJECT_PARAM_COUNT 6 +@@ -1770,19 +1809,48 @@ static int32_t parse_dfx_fault_inject_args(int32_t argc, char *argv[], struct ga + + #endif /* GAZELLE_FAULT_INJECT_ENABLE */ + ++static void parse_unix_arg(int32_t *argc, char *argv[]) ++{ ++ int unix_arg = 0; ++ for (int i = 1; i < *argc; i++) { ++ if (unix_arg == 0) { ++ if (!strcmp(argv[i], "-u")) { ++ unix_arg++; ++ } ++ } else if (unix_arg == 1) { ++ g_unix_prefix = argv[i]; ++ unix_arg++; ++ } else { ++ argv[i - unix_arg] = argv[i]; ++ } ++ } ++ ++ argv[*argc - unix_arg] = argv[*argc]; ++ *argc -= unix_arg; ++} ++ + static int32_t parse_dfx_cmd_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) + { +- int32_t num_cmd = 0; ++ int num_cmd = 0; ++ int ret; + + if (argc < GAZELLE_PARAM_MINNUM) { + return num_cmd; + } + ++ parse_unix_arg(&argc, argv); ++ + char *param = argv[GAZELLE_TARGET_ARG_IDX]; + if (strcmp(param, "ltran") == 0) { ++ g_use_ltran = true; + num_cmd = parse_dfx_ltran_args(argc, argv, req_msg); + } + if (strcmp(param, "lstack") == 0) { ++ ret = dfx_connect_probe(); ++ if (ret < 0) { ++ exit(0); ++ } ++ g_use_ltran = ret; + num_cmd = parse_dfx_lstack_args(argc, argv, req_msg); + } + #ifdef GAZELLE_FAULT_INJECT_ENABLE +@@ -1846,28 +1914,6 @@ int32_t main(int32_t argc, char *argv[]) + struct gazelle_stat_msg_request req_msg[GAZELLE_CMD_MAX] = {0}; + int32_t req_msg_num; + +- int unix_arg = 0; +- for (int32_t i = 1; i < argc; i++) { +- if (unix_arg == 0) { +- if (!strcmp(argv[i], "-u")) { +- unix_arg++; +- } +- } else if (unix_arg == 1) { +- g_unix_prefix = argv[i]; +- unix_arg++; +- } else { +- argv[i - unix_arg] = argv[i]; +- } +- } +- +- argv[argc - unix_arg] = argv[argc]; +- argc -= unix_arg; +- +- int32_t fd = dfx_connect_ltran(true, true); +- if (fd > 0) { +- g_use_ltran = true; +- close(fd); +- } + req_msg_num = parse_dfx_cmd_args(argc, argv, req_msg); + if (req_msg_num <= 0 || req_msg_num > GAZELLE_CMD_MAX) { + show_usage(); +-- +2.27.0 + diff --git a/0148-fix-rpc_pool-create-failed-coredump.patch b/0148-fix-rpc_pool-create-failed-coredump.patch new file mode 100644 index 0000000..b52c089 --- /dev/null +++ b/0148-fix-rpc_pool-create-failed-coredump.patch @@ -0,0 +1,103 @@ +From 98b8e8cea061d65ece3865ce8e772f5b4226199e Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Tue, 27 Feb 2024 22:37:47 +0800 +Subject: [PATCH] fix rpc_pool create failed coredump + +--- + src/lstack/core/lstack_thread_rpc.c | 34 ++++++++++++++++++++------ + src/lstack/include/lstack_thread_rpc.h | 6 ++++- + 2 files changed, 31 insertions(+), 9 deletions(-) + +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index 1fdb037..20c5a43 100644 +--- a/src/lstack/core/lstack_thread_rpc.c ++++ b/src/lstack/core/lstack_thread_rpc.c +@@ -36,6 +36,27 @@ static inline __attribute__((always_inline)) struct rpc_msg *get_rpc_msg(struct + return msg; + } + ++static void rpc_msg_init(struct rpc_msg *msg, rpc_msg_func func, struct rpc_msg_pool *pool) ++{ ++ msg->rpcpool = pool; ++ pthread_spin_init(&msg->lock, PTHREAD_PROCESS_PRIVATE); ++ msg->func = func; ++ msg->sync_flag = 1; ++ msg->recall_flag = 0; ++} ++ ++static struct rpc_msg *rpc_msg_alloc_except(rpc_msg_func func) ++{ ++ struct rpc_msg *msg = calloc(1, sizeof(struct rpc_msg)); ++ if (msg == NULL) { ++ return NULL; ++ } ++ ++ rpc_msg_init(msg, func, NULL); ++ ++ return msg; ++} ++ + static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) + { + struct rpc_msg *msg = NULL; +@@ -45,14 +66,15 @@ static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) + if (g_rpc_pool == NULL) { + LSTACK_LOG(INFO, LSTACK, "g_rpc_pool calloc failed\n"); + g_rpc_stats.call_alloc_fail++; +- return NULL; ++ exit(-1); + } + + g_rpc_pool->mempool = create_mempool("rpc_pool", RPC_MSG_MAX, sizeof(struct rpc_msg), + 0, rte_gettid()); + if (g_rpc_pool->mempool == NULL) { ++ LSTACK_LOG(INFO, LSTACK, "rpc_pool create failed, errno is %d\n", errno); + g_rpc_stats.call_alloc_fail++; +- return NULL; ++ exit(-1); + } + } + +@@ -61,12 +83,8 @@ static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) + g_rpc_stats.call_alloc_fail++; + return NULL; + } +- msg->rpcpool = g_rpc_pool; ++ rpc_msg_init(msg, func, g_rpc_pool); + +- pthread_spin_init(&msg->lock, PTHREAD_PROCESS_PRIVATE); +- msg->func = func; +- msg->sync_flag = 1; +- msg->recall_flag = 0; + return msg; + } + +@@ -247,7 +265,7 @@ int32_t rpc_call_close(rpc_queue *queue, int fd) + + int32_t rpc_call_stack_exit(rpc_queue *queue) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_exit_by_rpc); ++ struct rpc_msg *msg = rpc_msg_alloc_except(stack_exit_by_rpc); + if (msg == NULL) { + return -1; + } +diff --git a/src/lstack/include/lstack_thread_rpc.h b/src/lstack/include/lstack_thread_rpc.h +index 30caa66..4d89604 100644 +--- a/src/lstack/include/lstack_thread_rpc.h ++++ b/src/lstack/include/lstack_thread_rpc.h +@@ -104,7 +104,11 @@ static inline __attribute__((always_inline)) void rpc_call(rpc_queue *queue, str + static inline __attribute__((always_inline)) void rpc_msg_free(struct rpc_msg *msg) + { + pthread_spin_destroy(&msg->lock); +- rte_mempool_put(msg->rpcpool->mempool, (void *)msg); ++ if (msg->rpcpool != NULL && msg->rpcpool->mempool != NULL) { ++ rte_mempool_put(msg->rpcpool->mempool, (void *)msg); ++ } else { ++ free(msg); ++ } + } + + #endif +-- +2.27.0 + diff --git a/0149-ensure-the-bond-interface-flow_type_rss_offloads-mat.patch b/0149-ensure-the-bond-interface-flow_type_rss_offloads-mat.patch new file mode 100644 index 0000000..7585389 --- /dev/null +++ b/0149-ensure-the-bond-interface-flow_type_rss_offloads-mat.patch @@ -0,0 +1,24 @@ +From f8321fa815ca33267bd5b829fd8c06b75ab215d1 Mon Sep 17 00:00:00 2001 +From: zhangmengxuan +Date: Tue, 12 Mar 2024 19:51:57 +0800 +Subject: [PATCH] ensure the bond interface flow_type_rss_offloads match slave + +--- + src/lstack/core/lstack_dpdk.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 5811918..a774d45 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -584,6 +584,7 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + dev_info.rx_offload_capa = slave_dev_info.rx_offload_capa; + dev_info.tx_offload_capa = slave_dev_info.tx_offload_capa; + dev_info.reta_size = slave_dev_info.reta_size; ++ dev_info.flow_type_rss_offloads = slave_dev_info.flow_type_rss_offloads; + } + + eth_params_checksum(ð_params->conf, &dev_info); +-- +2.33.0 + diff --git a/0150-FAULT-INJECT-add-duplicate-and-reorder-methods.patch b/0150-FAULT-INJECT-add-duplicate-and-reorder-methods.patch new file mode 100644 index 0000000..17a1818 --- /dev/null +++ b/0150-FAULT-INJECT-add-duplicate-and-reorder-methods.patch @@ -0,0 +1,315 @@ +From 1929cc2a07a8e6d6a81b13a8338d816d7f09e709 Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Wed, 6 Mar 2024 10:51:42 +0800 +Subject: [PATCH] FAULT INJECT: add duplicate and reorder methods + +--- + src/common/gazelle_fault_inject_common.h | 4 +- + src/lstack/netif/lstack_fault_inject.c | 162 ++++++++++++++++++++++- + src/ltran/ltran_dfx.c | 20 ++- + 3 files changed, 174 insertions(+), 12 deletions(-) + +diff --git a/src/common/gazelle_fault_inject_common.h b/src/common/gazelle_fault_inject_common.h +index 3a77f39..72d778c 100644 +--- a/src/common/gazelle_fault_inject_common.h ++++ b/src/common/gazelle_fault_inject_common.h +@@ -17,10 +17,10 @@ + + enum GAZELLE_FAULT_INJECT_TYPE { + GAZELLE_FAULT_INJECT_TYPE_ERR = 0, +- GAZELLE_FAULT_INJECT_PACKET_DELAY, + GAZELLE_FAULT_INJECT_PACKET_LOSS, +- GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE, + GAZELLE_FAULT_INJECT_PACKET_REORDER, ++ GAZELLE_FAULT_INJECT_PACKET_DELAY, ++ GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE, + GAZELLE_FAULT_INJECT_TYPE_MAX, + }; + +diff --git a/src/lstack/netif/lstack_fault_inject.c b/src/lstack/netif/lstack_fault_inject.c +index 41e7d95..4edc6cc 100644 +--- a/src/lstack/netif/lstack_fault_inject.c ++++ b/src/lstack/netif/lstack_fault_inject.c +@@ -9,7 +9,7 @@ + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ +- ++#include + #include + #include + #include +@@ -31,6 +31,15 @@ struct inject_tbl { + }; + static struct inject_tbl g_inject_tbl[GAZELLE_FAULT_INJECT_TYPE_MAX]; + ++struct reorder_stat { ++ int32_t enable; ++ int32_t arr_size; ++ int32_t cur_cnt; ++ struct rte_mbuf **array; ++}; ++ ++static struct reorder_stat g_reorder[PROTOCOL_STACK_MAX]; ++ + struct inject_func_tbl { + enum GAZELLE_FAULT_INJECT_TYPE type; + enum GAZELLE_FAULT_INJECT_RULE rule; +@@ -41,10 +50,16 @@ static int32_t inject_packet_delay_random(struct protocol_stack *stack, struct r + uint32_t nr_pkts, struct gazelle_fault_inject_data data); + static int32_t inject_packet_loss_random(struct protocol_stack *stack, struct rte_mbuf **pkts, + uint32_t nr_pkts, struct gazelle_fault_inject_data data); ++static int32_t inject_packet_duplicate_random(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data); ++static int32_t inject_packet_reorder_random(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data); + + static struct inject_func_tbl g_inject_func_tbl[] = { + {GAZELLE_FAULT_INJECT_PACKET_LOSS, INJECT_LOSS_RANDOM, inject_packet_loss_random}, + {GAZELLE_FAULT_INJECT_PACKET_DELAY, INJECT_DELAY_RANDOM, inject_packet_delay_random}, ++ {GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE, INJECT_DUPLICATE_RANDOM, inject_packet_duplicate_random}, ++ {GAZELLE_FAULT_INJECT_PACKET_REORDER, INJECT_REORDER_RANDOM, inject_packet_reorder_random}, + }; + + static int32_t inject_func_tbl_update() +@@ -68,16 +83,16 @@ static int32_t inject_func_tbl_update() + static uint32_t inject_tx_xmit(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t nr_pkts) + { + for (int32_t i = 0; i < GAZELLE_FAULT_INJECT_TYPE_MAX; ++i) { +- if (g_inject_tbl[i].inject_data.fault_inject_on) { ++ if (g_inject_tbl[i].inject_data.fault_inject_on && g_inject_tbl[i].inject_func) { + int32_t xmit_pkts = 0; +- xmit_pkts = g_inject_tbl[i].inject_func(stack, pkts, nr_pkts, +- g_inject_tbl[i].inject_data); ++ xmit_pkts = g_inject_tbl[i].inject_func(stack, pkts, nr_pkts, g_inject_tbl[i].inject_data); + if (xmit_pkts == nr_pkts) { + continue; + } + return xmit_pkts; + } + } ++ + if (rte_mbuf_refcnt_read(*pkts) == 1) { + return nr_pkts; + } +@@ -105,7 +120,7 @@ static int32_t inject_strategy_update() + } + return 0; + } +- ++ + for (uint32_t i = 0; i < stack_group->stack_num; ++i) { + struct protocol_stack *stack = stack_group->stacks[i]; + vdev_dev_ops_init(&stack->dev_ops); +@@ -150,6 +165,132 @@ static int32_t inject_packet_loss_random(struct protocol_stack *stack, struct rt + return nr_pkts; + } + ++static int32_t inject_packet_duplicate_random(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data) ++{ ++ if (rte_mbuf_refcnt_read(*pkts) == 1) { ++ return nr_pkts; ++ } ++ ++ double duplicate_rate = data.inject_data.duplicate.duplicate_rate; ++ int32_t boundary = (int32_t) (duplicate_rate * INJECT_MODULO); ++ int32_t count_max = data.inject_data.duplicate.duplicate_sigle_count; ++ ++ uint32_t rand_num = rte_rand() % INJECT_MODULO; ++ if (rand_num > boundary) { ++ return nr_pkts; ++ } ++ ++ struct rte_mempool *mp = stack->rxtx_mbuf_pool; ++ struct rte_mbuf *mbuf_clone = NULL; ++ int32_t ret = 0; ++ ++ for (int32_t i = 0; i < nr_pkts; ++i) { ++ int32_t count = count_max; ++ while (count--) { ++ mbuf_clone = rte_pktmbuf_clone(pkts[i], mp); ++ rte_pktmbuf_free(pkts[i]); ++ if (mbuf_clone == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "fault inject mbuf_clone fail.\n"); ++ return 0; ++ } ++ ret = vdev_tx_xmit(stack, &mbuf_clone, 1); ++ if (ret < 1) { ++ rte_pktmbuf_free(mbuf_clone); ++ return ret; ++ } ++ } ++ } ++ return nr_pkts; ++} ++ ++static int32_t send_reorder_array(struct protocol_stack *stack) ++{ ++ int32_t idx = stack->stack_idx; ++ int32_t ret = 0; ++ ++ for (int32_t i = 0; i < g_reorder[idx].cur_cnt; ++i) { ++ ret = vdev_tx_xmit(stack, g_reorder[idx].array + i, 1); ++ if (ret < 1) { ++ rte_pktmbuf_free(*(g_reorder[idx].array + i)); ++ } ++ } ++ g_reorder[idx].cur_cnt = 0; ++ ++ return 0; ++} ++ ++static int32_t inject_packet_reorder_random(struct protocol_stack *stack, struct rte_mbuf **pkts, ++ uint32_t nr_pkts, struct gazelle_fault_inject_data data) ++{ ++ if (rte_mbuf_refcnt_read(*pkts) == 1) { ++ return nr_pkts; ++ } ++ ++ double reorder_rate = data.inject_data.reorder.reorder_rate; ++ int32_t boundary = (int32_t) (reorder_rate * INJECT_MODULO); ++ int32_t count_max = data.inject_data.reorder.reorder_sigle_count; ++ ++ uint32_t rand_num = rte_rand() % INJECT_MODULO; ++ if (rand_num > boundary) { ++ return nr_pkts; ++ } ++ ++ struct rte_mempool *mp = stack->rxtx_mbuf_pool; ++ struct rte_mbuf *mbuf_clone = NULL; ++ int32_t idx = stack->stack_idx; ++ for (int32_t i = 0; i < nr_pkts; ++i) { ++ if (g_reorder[idx].cur_cnt < count_max) { ++ mbuf_clone = rte_pktmbuf_clone(pkts[i], mp); ++ if (mbuf_clone == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "fault inject mbuf_clone fail.\n"); ++ return 0; ++ } ++ *(g_reorder[idx].array + g_reorder[idx].cur_cnt++) = mbuf_clone; ++ /* func rte_pktmbuf_clone will add refcnt of mbuf, so following operation will free mbuf double */ ++ rte_pktmbuf_free(pkts[i]); ++ rte_pktmbuf_free(pkts[i]); ++ } else { ++ send_reorder_array(stack); ++ } ++ } ++ ++ return nr_pkts; ++} ++ ++static int32_t inject_reorder_mem_release() ++{ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ ++ for (uint32_t i = 0; i < stack_group->stack_num; ++i) { ++ struct protocol_stack *stack = stack_group->stacks[i]; ++ if (!g_reorder[i].enable) { ++ return 0; ++ } ++ send_reorder_array(stack); ++ free(g_reorder[i].array); ++ g_reorder[i].enable = 0; ++ } ++ ++ return 0; ++} ++ ++static int32_t inject_reorder_mem_alloc() ++{ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ ++ for (uint32_t i = 0; i < stack_group->stack_num; ++i) { ++ g_reorder[i].enable = 1; ++ ++ g_reorder[i].arr_size = ++ g_inject_tbl[GAZELLE_FAULT_INJECT_PACKET_REORDER].inject_data.inject_data.reorder.reorder_sigle_count; ++ g_reorder[i].cur_cnt = 0; ++ g_reorder[i].array = ++ (struct rte_mbuf**) malloc(sizeof(struct rte_mbuf**) * (g_reorder[i].arr_size)); ++ } ++ return 0; ++} ++ + static int32_t inject_respond_msg(int32_t sockfd) + { + struct gazelle_stack_dfx_data rsp = {0}; +@@ -192,6 +333,10 @@ static int32_t inject_unset_cmd(int32_t sockfd, struct gazelle_fault_inject_data + } + } + ++ if (!g_inject_tbl[GAZELLE_FAULT_INJECT_PACKET_REORDER].inject_data.fault_inject_on) { ++ inject_reorder_mem_release(); ++ } ++ + inject_strategy_update(); + + return inject_respond_msg(sockfd); +@@ -208,8 +353,13 @@ static int32_t inject_set_cmd(int32_t sockfd, struct gazelle_fault_inject_data i + return -1; + } + ++ if (inject.inject_type == GAZELLE_FAULT_INJECT_PACKET_REORDER) { ++ inject_reorder_mem_release(); ++ inject_reorder_mem_alloc(); ++ } ++ + inject_strategy_update(); +- ++ + return inject_respond_msg(sockfd); + } + +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 96509e5..2cc3504 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -77,10 +77,10 @@ struct gazelle_fault_inject_type_list { + }; + + static struct gazelle_fault_inject_type_list inject_type_list[] = { +- {"delay", GAZELLE_FAULT_INJECT_PACKET_DELAY, parse_inject_packet_delay_digit}, + {"loss", GAZELLE_FAULT_INJECT_PACKET_LOSS, parse_inject_packet_loss_digit}, +- {"duplicate", GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE, parse_inject_packet_duplicate_digit}, + {"reorder", GAZELLE_FAULT_INJECT_PACKET_REORDER, parse_inject_packet_reorder_digit}, ++ {"delay", GAZELLE_FAULT_INJECT_PACKET_DELAY, parse_inject_packet_delay_digit}, ++ {"duplicate", GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE, parse_inject_packet_duplicate_digit}, + }; + + struct gazelle_fault_inject_rule_list { +@@ -1514,7 +1514,7 @@ static void gazelle_print_fault_inject_type_info(struct gazelle_fault_inject_dat + } + + if (inject->inject_type == GAZELLE_FAULT_INJECT_PACKET_DELAY) { +- printf("\t| inject_type: delay | delay_time: %-7d | delay_range: %-3d | " ++ printf("\t| inject_type: delay | delay_time: %-7d | delay_range: %-3d | " + "inject_rule: random |\n", inject->inject_data.delay.delay_time, + inject->inject_data.delay.delay_range); + } +@@ -1522,10 +1522,22 @@ static void gazelle_print_fault_inject_type_info(struct gazelle_fault_inject_dat + #define INJECT_PERCENT 100 + + if (inject->inject_type == GAZELLE_FAULT_INJECT_PACKET_LOSS) { +- printf("\t| inject_type: loss | loss_rate: %-3.1f%% | loss_single_count: %-3d | " ++ printf("\t| inject_type: loss | loss_rate: %-4.1f%% | loss_single_count: %-3d | " + "inject_rule: random |\n", inject->inject_data.loss.loss_rate * INJECT_PERCENT, + inject->inject_data.loss.loss_sigle_count); + } ++ ++ if (inject->inject_type == GAZELLE_FAULT_INJECT_PACKAET_DUPLICATE) { ++ printf("\t| inject_type: duplicate | duplicate_rate: %-4.1f%% | duplicate_single_count: %-3d | " ++ "inject_rule: random |\n", inject->inject_data.duplicate.duplicate_rate * INJECT_PERCENT, ++ inject->inject_data.duplicate.duplicate_sigle_count); ++ } ++ ++ if (inject->inject_type == GAZELLE_FAULT_INJECT_PACKET_REORDER) { ++ printf("\t| inject_type: reorder | reorder_rate: %-4.1f%% | reorder_sigle_count: %-3d | " ++ "inject_rule: random |\n", inject->inject_data.reorder.reorder_rate * INJECT_PERCENT, ++ inject->inject_data.reorder.reorder_sigle_count); ++ } + printf("\n"); + } + +-- +2.33.0 + diff --git a/0151-select-timeout-arguments-check.patch b/0151-select-timeout-arguments-check.patch new file mode 100644 index 0000000..61daec9 --- /dev/null +++ b/0151-select-timeout-arguments-check.patch @@ -0,0 +1,51 @@ +From fbd169eb504f5edc905f07f33785ba3df5812b4c Mon Sep 17 00:00:00 2001 +From: li_yunqing +Date: Thu, 14 Mar 2024 16:37:27 +0800 +Subject: [PATCH] select timeout arguments check + +--- + src/lstack/api/lstack_epoll.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index 7dbef9d..c9d1f0c 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -927,13 +927,17 @@ static void fds_poll2select(struct pollfd *fds, nfds_t nfds, fd_set *readfds, fd + } + } + +-static inline int timeval_to_ms(struct timeval *timeval) ++static inline int timeval_to_ms(struct timeval *timeval, int32_t *timeout) + { +- if (timeval == NULL) { ++ if (!timeval) { ++ *timeout = -1; ++ return 0; ++ } ++ if (unlikely((timeval->tv_sec < 0 || timeval->tv_usec < 0 || timeval->tv_usec >= 1000000))) { + return -1; + } +- +- return (timeval->tv_sec * 1000 + timeval->tv_usec / 1000); ++ *timeout = timeval->tv_sec * 1000 + timeval->tv_usec / 1000; ++ return 0; + } + + static nfds_t fds_select2poll(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct pollfd *fds) +@@ -969,7 +973,11 @@ int lstack_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfd + /* Convert the select parameter to the poll parameter. */ + struct pollfd fds[FD_SETSIZE] = { 0 }; + nfds_t nfds = fds_select2poll(maxfd, readfds, writefds, exceptfds, fds); +- int timeout = timeval_to_ms(timeval); ++ int timeout = 0; ++ if (timeval_to_ms(timeval, &timeout)) { ++ LSTACK_LOG(ERR, LSTACK, "select input param timeout error.\n"); ++ GAZELLE_RETURN(EINVAL); ++ } + + int event_num = lstack_poll(fds, nfds, timeout); + +-- +2.33.0 + diff --git a/0152-recvfrom-support-timeout.patch b/0152-recvfrom-support-timeout.patch new file mode 100644 index 0000000..fa91ff7 --- /dev/null +++ b/0152-recvfrom-support-timeout.patch @@ -0,0 +1,213 @@ +From e19bb18fad80ed95fb68318fc6ec7f2f892942dd Mon Sep 17 00:00:00 2001 +From: li_yunqing +Date: Tue, 19 Mar 2024 21:06:07 +0800 +Subject: [PATCH] recvfrom support timeout + +--- + src/lstack/api/lstack_epoll.c | 57 ++++++++++++++++--------- + src/lstack/api/lstack_wrap.c | 1 - + src/lstack/core/lstack_lwip.c | 28 +++++------- + src/lstack/core/lstack_protocol_stack.c | 2 +- + src/lstack/include/posix/lstack_epoll.h | 10 +---- + 5 files changed, 50 insertions(+), 48 deletions(-) + +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index 7dbef9d..1b68c36 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -586,6 +586,41 @@ static void ms_to_timespec(struct timespec *timespec, int32_t timeout) + timespec->tv_nsec = timespec->tv_nsec % SEC_TO_NSEC; + } + ++/** ++ * Block lstack thread ++ * ++ * @param wakeup ++ * The pointer to the wakeup_poll. ++ * @param timeout ++ * The time to wait, if 'timeout <= 0' will block until unlock ++ * ++ * @return ++ * - return '0' on unlock ++ * - return 'ETIMEDOUT' on timeout ++ */ ++int32_t lstack_block_wait(struct wakeup_poll *wakeup, int32_t timeout) ++{ ++ int ret = 0; ++ if (wakeup == NULL) { ++ return ret; ++ } ++ ++ __atomic_store_n(&wakeup->in_wait, true, __ATOMIC_RELEASE); ++ if (timeout > 0) { ++ struct timespec timespec; ++ ms_to_timespec(×pec, timeout); ++ ret = pthread_mutex_timedlock(&wakeup->wait, ×pec); ++ } else { ++ ret = pthread_mutex_lock(&wakeup->wait); ++ } ++ ++ if (__atomic_load_n(&wakeup->in_wait, __ATOMIC_ACQUIRE)) { ++ __atomic_store_n(&wakeup->in_wait, false, __ATOMIC_RELEASE); ++ } ++ ++ return ret; ++} ++ + int32_t lstack_rtc_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout) + { + struct lwip_sock *sock = get_socket_by_fd(epfd); +@@ -645,7 +680,6 @@ int32_t lstack_rtw_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t + struct wakeup_poll *wakeup = sock->wakeup; + int32_t kernel_num = 0; + int32_t lwip_num = 0; +- int32_t ret = 0; + + if (get_global_cfg_params()->app_bind_numa) { + epoll_bind_statck(sock->wakeup); +@@ -669,15 +703,7 @@ int32_t lstack_rtw_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t + if (timeout == 0) { + break; + } +- +- if (timeout < 0) { +- ret = pthread_mutex_lock(&wakeup->wait); +- } else { +- struct timespec epoll_time; +- ms_to_timespec(&epoll_time, timeout); +- ret = pthread_mutex_timedlock(&wakeup->wait, &epoll_time); +- } +- } while (ret == 0); ++ } while (lstack_block_wait(wakeup, timeout) == 0); + + __atomic_store_n(&wakeup->in_wait, false, __ATOMIC_RELEASE); + wakeup->stat.app_events += lwip_num; +@@ -857,7 +883,6 @@ int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout) + + int32_t kernel_num = 0; + int32_t lwip_num = 0; +- int32_t ret; + + do { + __atomic_store_n(&wakeup->in_wait, true, __ATOMIC_RELEASE); +@@ -881,15 +906,7 @@ int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout) + if (timeout == 0) { + break; + } +- +- if (timeout < 0) { +- ret = pthread_mutex_lock(&wakeup->wait); +- } else { +- struct timespec epoll_time; +- ms_to_timespec(&epoll_time, timeout); +- ret = pthread_mutex_timedlock(&wakeup->wait, &epoll_time); +- } +- } while (ret == 0); ++ } while (lstack_block_wait(wakeup, timeout) == 0); + + __atomic_store_n(&wakeup->in_wait, false, __ATOMIC_RELEASE); + wakeup->stat.app_events += lwip_num; +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 49bbf91..0dac82e 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -380,7 +380,6 @@ static bool unsupport_socket_optname(int32_t optname) + if ((optname == SO_BROADCAST) || + (optname == SO_PROTOCOL) || + (optname == SO_SNDTIMEO) || +- (optname == SO_RCVTIMEO) || + (optname == SO_SNDBUF) || + (optname == SO_RCVBUF) || + (optname == SO_DONTROUTE)) { +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 8aae433..d0dea80 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -859,39 +859,33 @@ static bool recv_break_for_err(struct lwip_sock *sock) + return break_wait; + } + +-static void recv_block_wait(struct lwip_sock *sock) +-{ +- lstack_block_wait(sock->wakeup); +-} +- + /* + * return 0 on success, -1 on error + * pbuf maybe NULL(tcp fin packet) + */ + static int recv_ring_get_one(struct lwip_sock *sock, bool noblock, struct pbuf **pbuf) + { ++ int32_t expect = 1; // only get one pbuf ++ + if (sock->recv_lastdata != NULL) { + *pbuf = sock->recv_lastdata; + sock->recv_lastdata = NULL; + return 0; + } + +- if (noblock) { +- if (gazelle_ring_read(sock->recv_ring, (void **)pbuf, 1) != 1) { +- errno = EAGAIN; ++ while (gazelle_ring_read(sock->recv_ring, (void **)pbuf, expect) != expect) { ++ if (noblock) { ++ GAZELLE_RETURN(EAGAIN); ++ } ++ if (recv_break_for_err(sock)) { + return -1; +- } else { +- return 0; + } +- } else { +- while (gazelle_ring_read(sock->recv_ring, (void **)pbuf, 1) != 1) { +- if (recv_break_for_err(sock)) { +- return -1; +- } +- recv_block_wait(sock); ++ if (lstack_block_wait(sock->wakeup, sock->conn->recv_timeout) == ETIMEDOUT) { ++ noblock = true; + } +- return 0; + } ++ ++ return 0; + } + + /* return true: fin is read to user, false: pend fin */ +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index a545b73..7c4af64 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -1270,7 +1270,7 @@ int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *ad + min_sock = get_min_accept_sock(fd); + } else { + while ((min_sock = get_min_accept_sock(fd)) == NULL) { +- lstack_block_wait(sock->wakeup); ++ lstack_block_wait(sock->wakeup, 0); + } + } + +diff --git a/src/lstack/include/posix/lstack_epoll.h b/src/lstack/include/posix/lstack_epoll.h +index 7591f0f..59b5ef7 100644 +--- a/src/lstack/include/posix/lstack_epoll.h ++++ b/src/lstack/include/posix/lstack_epoll.h +@@ -80,15 +80,7 @@ int32_t lstack_rtc_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t + int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout); + int lstack_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeval); + +-static inline void lstack_block_wait(struct wakeup_poll *wakeup) +-{ +- if (wakeup == NULL) { +- return; +- } +- +- __atomic_store_n(&wakeup->in_wait, true, __ATOMIC_RELEASE); +- pthread_mutex_lock(&wakeup->wait); +-} ++int32_t lstack_block_wait(struct wakeup_poll *wakeup, int32_t timeout); + + static inline void lstack_block_wakeup(struct wakeup_poll *wakeup) + { +-- +2.33.0 + diff --git a/0153-fix-netperf-setsockopt-fail.patch b/0153-fix-netperf-setsockopt-fail.patch new file mode 100644 index 0000000..5fcfe82 --- /dev/null +++ b/0153-fix-netperf-setsockopt-fail.patch @@ -0,0 +1,42 @@ +From 33efdf6e98d223f44a0168ae2e17e95cb7f27402 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Thu, 14 Mar 2024 13:16:58 +0800 +Subject: [PATCH] fix netperf setsockopt fail + +--- + src/lstack/api/lstack_wrap.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 49bbf91..1bec08b 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -364,6 +364,14 @@ static inline int32_t do_getsockname(int32_t s, struct sockaddr *name, socklen_t + return posix_api->getsockname_fn(s, name, namelen); + } + ++static bool unsupport_ip_optname(int32_t optname) ++{ ++ if (optname == IP_RECVERR) { ++ return true; ++ } ++ return false; ++} ++ + static bool unsupport_tcp_optname(int32_t optname) + { + if ((optname == TCP_QUICKACK) || +@@ -391,6 +399,10 @@ static bool unsupport_socket_optname(int32_t optname) + + static bool unsupport_optname(int32_t level, int32_t optname) + { ++ if (level == SOL_IP) { ++ return unsupport_ip_optname(optname); ++ } ++ + if (level == SOL_TCP) { + return unsupport_tcp_optname(optname); + } +-- +2.33.0 + diff --git a/0154-fix-LATENCY_WRITE-increase-in-recv-process.patch b/0154-fix-LATENCY_WRITE-increase-in-recv-process.patch new file mode 100644 index 0000000..3a0efb6 --- /dev/null +++ b/0154-fix-LATENCY_WRITE-increase-in-recv-process.patch @@ -0,0 +1,134 @@ +From c3d84d821fcdc15245f7cc9838cf97b4947a48e2 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Wed, 13 Mar 2024 13:01:38 +0800 +Subject: [PATCH] fix LATENCY_WRITE increase in recv process + +--- + src/common/dpdk_common.h | 5 +++++ + src/common/gazelle_dfx_msg.h | 2 ++ + src/lstack/core/lstack_lwip.c | 4 ++++ + src/lstack/core/lstack_stack_stat.c | 20 +++++++++++++++++++- + src/lstack/include/lstack_stack_stat.h | 1 + + 5 files changed, 31 insertions(+), 1 deletion(-) + +diff --git a/src/common/dpdk_common.h b/src/common/dpdk_common.h +index a79a0f2..cb41747 100644 +--- a/src/common/dpdk_common.h ++++ b/src/common/dpdk_common.h +@@ -23,6 +23,8 @@ + + #define GAZELLE_KNI_NAME "kni" // will be removed during dpdk update + ++#define GAZELLE_LATENCY_RD 0 ++#define GAZELLE_LATENCY_WR 1 + + /* Layout: + * | rte_mbuf | mbuf_private | payload | +@@ -31,6 +33,7 @@ + struct latency_timestamp { + uint64_t stamp; // time stamp + uint64_t check; // just for later vaild check ++ uint16_t type; // latency type + }; + struct mbuf_private { + /* struct pbuf_custom must at first */ +@@ -92,6 +95,7 @@ static __rte_always_inline void time_stamp_into_mbuf(uint32_t rx_count, struct r + lt = &mbuf_to_private(buf[i])->lt; + lt->stamp = time_stamp; + lt->check = ~(time_stamp); ++ lt->type = GAZELLE_LATENCY_RD; + } + } + +@@ -102,6 +106,7 @@ static __rte_always_inline void time_stamp_into_pbuf(uint32_t tx_count, struct p + lt = &pbuf_to_private(buf[i])->lt; + lt->stamp = time_stamp; + lt->check = ~(time_stamp); ++ lt->type = GAZELLE_LATENCY_WR; + } + } + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 8d528d6..d7ba80f 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -69,6 +69,8 @@ enum GAZELLE_STAT_MODE { + enum GAZELLE_LATENCY_TYPE { + GAZELLE_LATENCY_READ_LWIP, + GAZELLE_LATENCY_READ_LSTACK, ++ GAZELLE_LATENCY_READ_MAX, ++ + GAZELLE_LATENCY_WRITE_LWIP, + GAZELLE_LATENCY_WRITE_LSTACK, + GAZELLE_LATENCY_MAX, +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 8aae433..f9b83c7 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -257,6 +257,10 @@ struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_s + int size = (remain_size + MBUF_MAX_DATA_LEN - 1) / MBUF_MAX_DATA_LEN - 1; + struct pbuf *pbuf_used[size]; + gazelle_ring_sc_dequeue(sock->send_ring, (void **)&pbuf_used, size); ++ ++ for (uint32_t i = 0; get_protocol_stack_group()->latency_start && i < size; i++) { ++ calculate_lstack_latency(&sock->stack->latency, pbuf_used[i], GAZELLE_LATENCY_WRITE_LWIP); ++ } + } + + if (get_protocol_stack_group()->latency_start) { +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index 25b5557..3e016b7 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -48,10 +48,27 @@ uint64_t get_current_time(void) + return (rte_rdtsc() / g_cycles_per_us); + } + ++void time_stamp_transfer_pbuf(struct pbuf *pbuf_old, struct pbuf *pbuf_new) ++{ ++ if (!get_protocol_stack_group()->latency_start) { ++ return; ++ } ++ struct latency_timestamp *lt_old; ++ struct latency_timestamp *lt_new; ++ ++ lt_old = &pbuf_to_private(pbuf_old)->lt; ++ lt_new = &pbuf_to_private(pbuf_new)->lt; ++ ++ lt_new->stamp = lt_old->stamp; ++ lt_new->check = lt_old->check; ++ lt_new->type = lt_old->type; ++} ++ + void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const struct pbuf *pbuf, + enum GAZELLE_LATENCY_TYPE type) + { + uint64_t latency; ++ uint16_t lt_type; + const struct latency_timestamp *lt; + struct stack_latency *latency_stat; + +@@ -60,7 +77,8 @@ void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const + } + + lt = &pbuf_to_private(pbuf)->lt; +- if (lt->stamp != ~(lt->check) || lt->stamp < stack_latency->start_time) { ++ lt_type = (type / GAZELLE_LATENCY_READ_MAX) ? GAZELLE_LATENCY_WR : GAZELLE_LATENCY_RD; ++ if (lt->stamp != ~(lt->check) || lt->stamp < stack_latency->start_time || lt_type != lt->type) { + return; + } + +diff --git a/src/lstack/include/lstack_stack_stat.h b/src/lstack/include/lstack_stack_stat.h +index d5a4ec7..87951aa 100644 +--- a/src/lstack/include/lstack_stack_stat.h ++++ b/src/lstack/include/lstack_stack_stat.h +@@ -30,5 +30,6 @@ uint64_t get_current_time(void); + void lstack_get_low_power_info(struct gazelle_stat_low_power_info *low_power_info); + void unregister_wakeup(struct protocol_stack *stack, struct wakeup_poll *wakeup); + void lstack_calculate_aggregate(int type, uint32_t len); ++void time_stamp_transfer_pbuf(struct pbuf *pbuf_old, struct pbuf *pbuf_new); + + #endif /* GAZELLE_STACK_STAT_H */ +-- +2.33.0 + diff --git a/0155-dpdk-add-vlan-filter.patch b/0155-dpdk-add-vlan-filter.patch new file mode 100644 index 0000000..05c98d7 --- /dev/null +++ b/0155-dpdk-add-vlan-filter.patch @@ -0,0 +1,95 @@ +From 3d8a848dde959ef95796e8215cdb1882a3496ce4 Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Thu, 21 Mar 2024 11:24:26 +0800 +Subject: [PATCH] dpdk add vlan filter + +--- + src/common/dpdk_common.c | 6 ++++++ + src/lstack/core/lstack_dpdk.c | 19 +++++++++++++------ + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/src/common/dpdk_common.c b/src/common/dpdk_common.c +index c0c4f63..c03b2ec 100644 +--- a/src/common/dpdk_common.c ++++ b/src/common/dpdk_common.c +@@ -223,6 +223,12 @@ void eth_params_checksum(struct rte_eth_conf *conf, struct rte_eth_dev_info *dev + COMMON_INFO("RTE_ETH_RX_OFFLOAD_VLAN_STRIP\n"); + } + ++ // rx vlan filter ++ if (rx_ol_capa & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) { ++ rx_ol |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER; ++ COMMON_INFO("RTE_ETH_RX_OFFLOAD_VLAN_STRIP\n"); ++ } ++ + // tx ip + if (tx_ol_capa & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { + tx_ol |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM; +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index a774d45..42981f4 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -572,13 +572,13 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + int slave_id = rte_eth_bond_primary_get(port_id); + if (slave_id < 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk get bond primary port failed port = %d\n", slave_id); +- free(eth_params); ++ free(eth_params); + return slave_id; + } + ret = rte_eth_dev_info_get(slave_id, &slave_dev_info); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk get bond dev info failed ret = %d\n", ret); +- free(eth_params); ++ free(eth_params); + return ret; + } + dev_info.rx_offload_capa = slave_dev_info.rx_offload_capa; +@@ -623,6 +623,13 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + } + } + ++ /* after rte_eth_dev_configure */ ++ ret = rte_eth_dev_vlan_filter(port_id, get_global_cfg_params()->nic.vlan_mode, 1); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "dpdk add vlan filter failed ret = %d\n", ret); ++ return -1; ++ } ++ + rte_eth_allmulticast_enable(port_id); + + return 0; +@@ -733,7 +740,7 @@ int32_t init_dpdk_ethdev(void) + } + + ret = dpdk_ethdev_init(bond_port_id, 1); +- if (ret != 0) { ++ if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk_ethdev_init failed ret = %d\n", ret); + return -1; + } +@@ -765,18 +772,18 @@ int32_t init_dpdk_ethdev(void) + + ret = rte_eth_promiscuous_enable(bond_port_id); + if (ret < 0) { +- LSTACK_LOG(ERR, LSTACK, "dpdk enable promiscuous failed ret = %d\n", ret); ++ LSTACK_LOG(ERR, LSTACK, "dpdk enable promiscuous failed ret = %d\n", ret); + return -1; + } + + ret = rte_eth_allmulticast_enable(bond_port_id); + if (ret < 0) { +- LSTACK_LOG(ERR, LSTACK, "dpdk enable allmulticast failed ret = %d\n", ret); ++ LSTACK_LOG(ERR, LSTACK, "dpdk enable allmulticast failed ret = %d\n", ret); + return -1; + } + + ret = rte_eth_dev_start(bond_port_id); +- if (ret < 0) { ++ if (ret < 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk start bond port failed ret = %d\n", ret); + return -1; + } +-- +2.33.0 + diff --git a/0156-Correcting-spelling-errors.patch b/0156-Correcting-spelling-errors.patch new file mode 100644 index 0000000..ab52f92 --- /dev/null +++ b/0156-Correcting-spelling-errors.patch @@ -0,0 +1,25 @@ +From b766b84a25e9099e67ebacffed7ff96024af2268 Mon Sep 17 00:00:00 2001 +From: gaojiazhen +Date: Fri, 22 Mar 2024 17:33:59 +0800 +Subject: [PATCH] Correcting spelling errors + +--- + src/ltran/ltran_ethdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ltran/ltran_ethdev.c b/src/ltran/ltran_ethdev.c +index 2fb7fab..2f08d4a 100644 +--- a/src/ltran/ltran_ethdev.c ++++ b/src/ltran/ltran_ethdev.c +@@ -378,7 +378,7 @@ static int32_t ltran_bond_port_attr_set(uint16_t port_num, uint16_t bond_port_id + + struct rte_eth_dev_info dev_info; + if (rte_eth_dev_info_get(bond_port_id, &dev_info) != 0) { +- LTRAN_ERR("faile rte_eth_dev_info_get\n"); ++ LTRAN_ERR("rte_eth_dev_info_get failed\n"); + return GAZELLE_ERR; + } + +-- +2.33.0 + diff --git a/0157-perftool-add-lhist-statstic-tool.patch b/0157-perftool-add-lhist-statstic-tool.patch new file mode 100644 index 0000000..ed74fd8 --- /dev/null +++ b/0157-perftool-add-lhist-statstic-tool.patch @@ -0,0 +1,41 @@ +From 34c2f6cc1e1059ffe3e5edd7cebeb758e4ba9f36 Mon Sep 17 00:00:00 2001 +From: wuchangye +Date: Sun, 24 Mar 2024 00:10:08 +0800 +Subject: [PATCH] perftool: add lhist statstic tool + +--- + tools/perf/glhist.bt | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + create mode 100644 tools/perf/glhist.bt + +diff --git a/tools/perf/glhist.bt b/tools/perf/glhist.bt +new file mode 100644 +index 0000000..757f6e9 +--- /dev/null ++++ b/tools/perf/glhist.bt +@@ -0,0 +1,21 @@ ++#!/usr/bin/env bpftrace ++/* ++reference: https://github.com/bpftrace/bpftrace/blob/master/man/adoc/bpftrace.adoc ++prepare: yum install bpftrace ++example: ./glhist.bt rpc_poll_msg ++*/ ++ ++uprobe:/usr/lib64/liblstack.so:$1 ++{ ++ @t_start[tid] = nsecs; ++} ++ ++uretprobe:/usr/lib64/liblstack.so:$1 ++{ ++ @t_dur[tid] = nsecs - @t_start[tid]; ++ @t_count[tid] = count(); ++ if (@t_dur[tid] < 1000000000) { ++ // lhist(int64 n, int64 min, int64 max, int64 step) ++ @t_hist[tid] = lhist(@t_dur[tid], 0, 4000, 100); ++ } ++} +\ No newline at end of file +-- +2.33.0 + diff --git a/0158-add-udp-poll.patch b/0158-add-udp-poll.patch new file mode 100644 index 0000000..4b7380a --- /dev/null +++ b/0158-add-udp-poll.patch @@ -0,0 +1,47 @@ +From 776ff89196c1fb5bc0193ea746119e40f80fed46 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Fri, 22 Mar 2024 08:31:28 +0000 +Subject: [PATCH] add udp poll + +--- + src/lstack/core/lstack_lwip.c | 8 ++++++++ + src/lstack/core/lstack_protocol_stack.c | 4 ++++ + 2 files changed, 12 insertions(+) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index a604a62..c5161b4 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -1307,6 +1307,14 @@ void netif_poll(struct netif *netif) + /* processes on same node handshake packet use this function */ + err_t netif_loop_output(struct netif *netif, struct pbuf *p) + { ++ if (p != NULL) { ++ const struct ip_hdr *iphdr; ++ iphdr = (const struct ip_hdr *)p->payload; ++ if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { ++ return udp_netif_loop_output(netif, p); ++ } ++ } ++ + struct tcp_pcb *pcb = p->pcb; + struct pbuf *head = NULL; + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 7c4af64..138ac2b 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -491,6 +491,10 @@ int stack_polling(uint32_t wakeup_tick) + } + } + ++ if (cfg->udp_enable) { ++ udp_netif_poll(&stack->netif); ++ } ++ + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + /* run to completion mode currently does not support kni */ + /* KNI requests are generally low-rate I/Os, +-- +2.33.0 + diff --git a/0159-DFX-adapt-testcase-for-gazellectl-connect-failed.patch b/0159-DFX-adapt-testcase-for-gazellectl-connect-failed.patch new file mode 100644 index 0000000..b9d73f5 --- /dev/null +++ b/0159-DFX-adapt-testcase-for-gazellectl-connect-failed.patch @@ -0,0 +1,39 @@ +From f082b20ee9bab301fb21f2a40c32ca031f6177af Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Tue, 26 Mar 2024 10:40:00 +0800 +Subject: [PATCH] DFX: adapt testcase for gazellectl connect failed + +--- + src/ltran/ltran_dfx.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 91c6063..073dfa7 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -361,10 +361,10 @@ static int dfx_connect_probe(void) + return 0; + } + +- printf("Connect lstack(path:%s), errno: %d; Connect ltran(path:%s) failed, errno: %d\n", ++ printf("Connect lstack(path:%s) failed, errno: %d; Connect ltran(path:%s) failed, errno: %d\n", + g_lstack_unix_path, -ret2, g_ltran_unix_path, -ret1); +- printf("Please ensure the process is started; If use ltran mode, \ +- set use_ltran=1 in lstack.conf, otherwise set use_ltran=0\n"); ++ printf("Please ensure the process is started; If use ltran mode, " ++ "set use_ltran=1 in lstack.conf, otherwise set use_ltran=0\n"); + return -1; + } + +@@ -1860,7 +1860,7 @@ static int32_t parse_dfx_cmd_args(int32_t argc, char *argv[], struct gazelle_sta + if (strcmp(param, "lstack") == 0) { + ret = dfx_connect_probe(); + if (ret < 0) { +- exit(0); ++ exit(-1); + } + g_use_ltran = ret; + num_cmd = parse_dfx_lstack_args(argc, argv, req_msg); +-- +2.33.0 + diff --git a/0160-warp-add-configuration-check-with-host_addr-and-serv.patch b/0160-warp-add-configuration-check-with-host_addr-and-serv.patch new file mode 100644 index 0000000..fdafe9e --- /dev/null +++ b/0160-warp-add-configuration-check-with-host_addr-and-serv.patch @@ -0,0 +1,29 @@ +From 7604fb6e3917bd2b745f9dd5591de5a3b244c51e Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Mon, 25 Mar 2024 16:07:09 +0800 +Subject: [PATCH] warp: add configuration check with host_addr and server_ip + for ipv6 + +--- + src/lstack/api/lstack_wrap.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 49bbf91..2d5ef83 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -259,6 +259,11 @@ bool is_dst_ip_localhost(const struct sockaddr *addr) + if (get_global_cfg_params()->host_addr.addr == ((struct sockaddr_in *)addr)->sin_addr.s_addr) { + return true; + } ++ } else if (addr->sa_family == AF_INET6) { ++ if (memcmp(get_global_cfg_params()->host_addr6.addr, &((struct sockaddr_in6 *)addr)->sin6_addr, ++ sizeof(struct in6_addr)) == 0) { ++ return true; ++ } + } + + if (getifaddrs(&ifap) == -1) { +-- +2.33.0 + diff --git a/0161-add-latency-nodes-READ_APP_CALL-WRITE_RPC_MSG.patch b/0161-add-latency-nodes-READ_APP_CALL-WRITE_RPC_MSG.patch new file mode 100644 index 0000000..b30688e --- /dev/null +++ b/0161-add-latency-nodes-READ_APP_CALL-WRITE_RPC_MSG.patch @@ -0,0 +1,380 @@ +From 286e9a267e2d106d05c5fec80a932ed605d4b006 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 1 Apr 2024 09:15:56 +0800 +Subject: [PATCH] add latency nodes: READ_APP_CALL & WRITE_RPC_MSG + +--- + src/common/dpdk_common.h | 2 + + src/common/gazelle_dfx_msg.h | 18 ++++--- + src/lstack/core/lstack_lwip.c | 23 ++++++--- + src/lstack/core/lstack_protocol_stack.c | 4 ++ + src/lstack/core/lstack_stack_stat.c | 68 +++++++++++++++++++++---- + src/lstack/core/lstack_thread_rpc.c | 8 ++- + src/lstack/include/lstack_stack_stat.h | 4 ++ + src/lstack/include/lstack_thread_rpc.h | 2 + + src/lstack/netif/lstack_ethdev.c | 2 +- + src/ltran/ltran_dfx.c | 21 ++++++-- + 10 files changed, 124 insertions(+), 28 deletions(-) + +diff --git a/src/common/dpdk_common.h b/src/common/dpdk_common.h +index cb41747..7a05342 100644 +--- a/src/common/dpdk_common.h ++++ b/src/common/dpdk_common.h +@@ -19,6 +19,7 @@ + #include + #include + ++#include "gazelle_dfx_msg.h" + #include "gazelle_opt.h" + + #define GAZELLE_KNI_NAME "kni" // will be removed during dpdk update +@@ -33,6 +34,7 @@ + struct latency_timestamp { + uint64_t stamp; // time stamp + uint64_t check; // just for later vaild check ++ uint16_t stamp_seg[GAZELLE_LATENCY_MAX]; // time stamp segment + uint16_t type; // latency type + }; + struct mbuf_private { +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index d7ba80f..c2ff760 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -62,17 +62,23 @@ enum GAZELLE_STAT_MODE { + GAZELLE_STAT_FAULT_INJECT_SET, + GAZELLE_STAT_FAULT_INJECT_UNSET, + #endif /* GAZELLE_FAULT_INJECT_ENABLE */ +- ++ + GAZELLE_STAT_MODE_MAX, + }; + + enum GAZELLE_LATENCY_TYPE { +- GAZELLE_LATENCY_READ_LWIP, +- GAZELLE_LATENCY_READ_LSTACK, +- GAZELLE_LATENCY_READ_MAX, ++ GAZELLE_LATENCY_READ_LWIP, // t0 -> t1 ++ GAZELLE_LATENCY_READ_APP_CALL, // t1 -> t2 ++ GAZELLE_LATENCY_READ_LSTACK, // t2 -> t3 ++ GAZELLE_LATENCY_READ_MAX, // t0 -> t3 ++ ++ GAZELLE_LATENCY_WRITE_INTO_RING, // t0 -> t1 ++ GAZELLE_LATENCY_WRITE_LWIP, // t1 -> t2 ++ GAZELLE_LATENCY_WRITE_LSTACK, // t2 -> t3 ++ GAZELLE_LATENCY_WRITE_MAX, // t0 -> t3 ++ ++ GAZELLE_LATENCY_WRITE_RPC_MSG, // rpc_call_send + +- GAZELLE_LATENCY_WRITE_LWIP, +- GAZELLE_LATENCY_WRITE_LSTACK, + GAZELLE_LATENCY_MAX, + }; + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index a604a62..1d27938 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -259,12 +259,12 @@ struct pbuf *do_lwip_get_from_sendring(struct lwip_sock *sock, uint16_t remain_s + gazelle_ring_sc_dequeue(sock->send_ring, (void **)&pbuf_used, size); + + for (uint32_t i = 0; get_protocol_stack_group()->latency_start && i < size; i++) { +- calculate_lstack_latency(&sock->stack->latency, pbuf_used[i], GAZELLE_LATENCY_WRITE_LWIP); ++ calculate_lstack_latency(&sock->stack->latency, pbuf_used[i], GAZELLE_LATENCY_WRITE_LWIP, 0); + } + } + + if (get_protocol_stack_group()->latency_start) { +- calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_WRITE_LWIP); ++ calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_WRITE_LWIP, 0); + } + + sock->send_pre_del = pbuf; +@@ -362,6 +362,12 @@ static inline ssize_t app_buff_write(struct lwip_sock *sock, void *buf, size_t l + } + } + ++ for (int i = 0; get_protocol_stack_group()->latency_start && i < write_num; i++) { ++ if (pbufs[i] != NULL) { ++ calculate_lstack_latency(&sock->stack->latency, pbufs[i], GAZELLE_LATENCY_WRITE_INTO_RING, 0); ++ } ++ } ++ + gazelle_ring_read_over(sock->send_ring); + + sock->remain_len = MBUF_MAX_DATA_LEN - pbufs[write_num - 1]->len; +@@ -611,7 +617,7 @@ ssize_t do_lwip_read_from_lwip(struct lwip_sock *sock, int32_t flags, u8_t apifl + + for (uint32_t i = 0; get_protocol_stack_group()->latency_start && i < read_count; i++) { + if (pbufs[i] != NULL) { +- calculate_lstack_latency(&sock->stack->latency, pbufs[i], GAZELLE_LATENCY_READ_LWIP); ++ calculate_lstack_latency(&sock->stack->latency, pbufs[i], GAZELLE_LATENCY_READ_LWIP, 0); + } + } + +@@ -870,6 +876,7 @@ static bool recv_break_for_err(struct lwip_sock *sock) + static int recv_ring_get_one(struct lwip_sock *sock, bool noblock, struct pbuf **pbuf) + { + int32_t expect = 1; // only get one pbuf ++ uint64_t time_stamp = get_current_time(); + + if (sock->recv_lastdata != NULL) { + *pbuf = sock->recv_lastdata; +@@ -888,7 +895,11 @@ static int recv_ring_get_one(struct lwip_sock *sock, bool noblock, struct pbuf * + noblock = true; + } + } +- ++ ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_lstack_latency(&sock->stack->latency, *pbuf, GAZELLE_LATENCY_READ_APP_CALL, time_stamp); ++ } ++ + return 0; + } + +@@ -954,7 +965,7 @@ static ssize_t recv_ring_tcp_read(struct lwip_sock *sock, void *buf, size_t len, + } + + if (get_protocol_stack_group()->latency_start) { +- calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK); ++ calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK, 0); + } + + gazelle_ring_read_over(sock->recv_ring); +@@ -1001,7 +1012,7 @@ static ssize_t recv_ring_udp_read(struct lwip_sock *sock, void *buf, size_t len, + sock->wakeup->stat.app_read_cnt++; + } + if (get_protocol_stack_group()->latency_start) { +- calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK); ++ calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK, 0); + } + + return copy_len; +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 7c4af64..079bba0 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -876,6 +876,10 @@ void stack_send(struct rpc_msg *msg) + struct protocol_stack *stack = get_protocol_stack(); + int replenish_again; + ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_rpcmsg_latency(&stack->latency, msg, GAZELLE_LATENCY_WRITE_RPC_MSG); ++ } ++ + struct lwip_sock *sock = get_socket(fd); + if (sock == NULL) { + msg->result = -1; +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index 3e016b7..80d4998 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -62,16 +62,53 @@ void time_stamp_transfer_pbuf(struct pbuf *pbuf_old, struct pbuf *pbuf_new) + lt_new->stamp = lt_old->stamp; + lt_new->check = lt_old->check; + lt_new->type = lt_old->type; ++ for (int i = 0; i < GAZELLE_LATENCY_MAX; i++) { ++ lt_new->stamp_seg[i] = lt_old->stamp_seg[i]; ++ } + } + +-void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const struct pbuf *pbuf, ++void time_stamp_into_rpcmsg(struct rpc_msg *msg) ++{ ++ msg->time_stamp = get_current_time(); ++} ++ ++void calculate_rpcmsg_latency(struct gazelle_stack_latency *stack_latency, struct rpc_msg *msg, + enum GAZELLE_LATENCY_TYPE type) + { + uint64_t latency; +- uint16_t lt_type; +- const struct latency_timestamp *lt; ++ struct stack_latency *latency_stat; ++ if (msg == NULL || msg->time_stamp < stack_latency->start_time || type >= GAZELLE_LATENCY_MAX) { ++ return; ++ } ++ ++ latency = get_current_time() - msg->time_stamp; ++ latency_stat = &stack_latency->latency[type]; ++ ++ latency_stat->latency_total += latency; ++ latency_stat->latency_max = (latency_stat->latency_max > latency) ? latency_stat->latency_max : latency; ++ latency_stat->latency_min = (latency_stat->latency_min < latency) ? latency_stat->latency_min : latency; ++ latency_stat->latency_pkts++; ++} ++ ++void calculate_latency_stat(struct gazelle_stack_latency *stack_latency, uint64_t latency, ++ enum GAZELLE_LATENCY_TYPE type) ++{ + struct stack_latency *latency_stat; + ++ latency_stat = &stack_latency->latency[type]; ++ latency_stat->latency_total += latency; ++ latency_stat->latency_max = (latency_stat->latency_max > latency) ? latency_stat->latency_max : latency; ++ latency_stat->latency_min = (latency_stat->latency_min < latency) ? latency_stat->latency_min : latency; ++ latency_stat->latency_pkts++; ++} ++ ++void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const struct pbuf *pbuf, ++ enum GAZELLE_LATENCY_TYPE type, uint64_t time_record) ++{ ++ uint64_t latency; ++ uint16_t lt_type; ++ struct latency_timestamp *lt; ++ + if (pbuf == NULL || type >= GAZELLE_LATENCY_MAX) { + return; + } +@@ -82,13 +119,26 @@ void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const + return; + } + +- latency = get_current_time() - lt->stamp; +- latency_stat = &stack_latency->latency[type]; ++ if (time_record == 0) { ++ lt->stamp_seg[type] = get_current_time() - lt->stamp; ++ } else { ++ lt->stamp_seg[type] = time_record > (lt->stamp_seg[type - 1] + lt->stamp) ? ++ (time_record - lt->stamp) : lt->stamp_seg[type - 1]; ++ } + +- latency_stat->latency_total += latency; +- latency_stat->latency_max = (latency_stat->latency_max > latency) ? latency_stat->latency_max : latency; +- latency_stat->latency_min = (latency_stat->latency_min < latency) ? latency_stat->latency_min : latency; +- latency_stat->latency_pkts++; ++ latency = lt->stamp_seg[type]; ++ if (((lt_type == GAZELLE_LATENCY_RD && type > GAZELLE_LATENCY_READ_LWIP) || ++ (lt_type == GAZELLE_LATENCY_WR && type > GAZELLE_LATENCY_WRITE_INTO_RING)) && ++ latency >= lt->stamp_seg[type - 1]) { ++ latency -= lt->stamp_seg[type - 1]; ++ } ++ ++ /* calculate the time of the entire read/write process */ ++ if (type == GAZELLE_LATENCY_READ_MAX - 1 || type == GAZELLE_LATENCY_WRITE_MAX - 1) { ++ calculate_latency_stat(stack_latency, lt->stamp_seg[type], type + 1); ++ } ++ ++ calculate_latency_stat(stack_latency, latency, type); + } + + void lstack_calculate_aggregate(int type, uint32_t len) +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index 20c5a43..30bd827 100644 +--- a/src/lstack/core/lstack_thread_rpc.c ++++ b/src/lstack/core/lstack_thread_rpc.c +@@ -15,6 +15,8 @@ + #include "lstack_log.h" + #include "lstack_dpdk.h" + #include "lstack_rpc_proc.h" ++#include "lstack_stack_stat.h" ++#include "lstack_protocol_stack.h" + #include "lstack_thread_rpc.h" + + static PER_THREAD struct rpc_msg_pool *g_rpc_pool = NULL; +@@ -467,11 +469,15 @@ int32_t rpc_call_send(rpc_queue *queue, int fd, const void *buf, size_t len, int + return -1; + } + ++ if (get_protocol_stack_group()->latency_start) { ++ time_stamp_into_rpcmsg(msg); ++ } ++ + msg->args[MSG_ARG_0].i = fd; + msg->args[MSG_ARG_1].size = len; + msg->args[MSG_ARG_2].i = flags; + msg->sync_flag = 0; +- ++ + rpc_call(queue, msg); + + return 0; +diff --git a/src/lstack/include/lstack_stack_stat.h b/src/lstack/include/lstack_stack_stat.h +index 87951aa..f901982 100644 +--- a/src/lstack/include/lstack_stack_stat.h ++++ b/src/lstack/include/lstack_stack_stat.h +@@ -15,6 +15,7 @@ + + struct gazelle_stack_latency; + struct pbuf; ++struct rpc_msg; + struct gazelle_stat_low_power_info; + struct wakeup_poll; + struct protocol_stack; +@@ -22,6 +23,8 @@ enum GAZELLE_LATENCY_TYPE; + enum GAZELLE_STAT_MODE; + + void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const struct pbuf *pbuf, ++ enum GAZELLE_LATENCY_TYPE type, uint64_t time_record); ++void calculate_rpcmsg_latency(struct gazelle_stack_latency *stack_latency, struct rpc_msg *msg, + enum GAZELLE_LATENCY_TYPE type); + void stack_stat_init(void); + int handle_stack_cmd(int fd, enum GAZELLE_STAT_MODE stat_mode); +@@ -31,5 +34,6 @@ void lstack_get_low_power_info(struct gazelle_stat_low_power_info *low_power_inf + void unregister_wakeup(struct protocol_stack *stack, struct wakeup_poll *wakeup); + void lstack_calculate_aggregate(int type, uint32_t len); + void time_stamp_transfer_pbuf(struct pbuf *pbuf_old, struct pbuf *pbuf_new); ++void time_stamp_into_rpcmsg(struct rpc_msg *msg); + + #endif /* GAZELLE_STACK_STAT_H */ +diff --git a/src/lstack/include/lstack_thread_rpc.h b/src/lstack/include/lstack_thread_rpc.h +index 4d89604..8e97c11 100644 +--- a/src/lstack/include/lstack_thread_rpc.h ++++ b/src/lstack/include/lstack_thread_rpc.h +@@ -60,6 +60,8 @@ struct rpc_msg { + + rpc_msg_func func; /* msg handle func hook */ + union rpc_msg_arg args[RPM_MSG_ARG_SIZE]; /* resolve by type */ ++ ++ uint64_t time_stamp; /* rpc_call_* start time */ + }; + + static inline void rpc_queue_init(rpc_queue *queue) +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 8fe11c4..23edc19 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -224,7 +224,7 @@ static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + rte_mbuf_refcnt_update(mbuf, 1); + + if (get_protocol_stack_group()->latency_start) { +- calculate_lstack_latency(&stack->latency, pbuf, GAZELLE_LATENCY_WRITE_LSTACK); ++ calculate_lstack_latency(&stack->latency, pbuf, GAZELLE_LATENCY_WRITE_LSTACK, 0); + } + pbuf = pbuf->next; + } +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 91c6063..79c172b 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -881,11 +881,22 @@ static void gazelle_print_lstack_stat_latency(void *buf, const struct gazelle_st + gazelle_show_latency_result_total(buf, req_msg, res); + + printf("Statistics of lstack latency pkts min(us) max(us) average(us)\n"); +- printf("range: t0--->t3\n%s", res[GAZELLE_LATENCY_READ_LSTACK].latency_stat_result); +- printf("range: t0--->t2\n%s", res[GAZELLE_LATENCY_READ_LWIP].latency_stat_result); +- printf("range: t3--->t0\n%s", res[GAZELLE_LATENCY_WRITE_LSTACK].latency_stat_result); +- printf("range: t2--->t0\n%s", res[GAZELLE_LATENCY_WRITE_LWIP].latency_stat_result); +- printf("t0:read form/send to nic t1:into/out of lstask queue t2:into/out of app queue t3:app read/send\n"); ++ printf("Recv:\n"); ++ printf("range: t0--->t1\n%s", res[GAZELLE_LATENCY_READ_LWIP].latency_stat_result); ++ printf("range: t1--->t2\n%s", res[GAZELLE_LATENCY_READ_APP_CALL].latency_stat_result); ++ printf("range: t2--->t3\n%s", res[GAZELLE_LATENCY_READ_LSTACK].latency_stat_result); ++ printf("range: t0--->t3\n%s", res[GAZELLE_LATENCY_READ_MAX].latency_stat_result); ++ printf("t0: read from nic t1: into recv ring t2: app read start t3: app read end\n"); ++ ++ printf("Send:\n"); ++ printf("range: t0--->t1\n%s", res[GAZELLE_LATENCY_WRITE_INTO_RING].latency_stat_result); ++ printf("range: t1--->t2\n%s", res[GAZELLE_LATENCY_WRITE_LWIP].latency_stat_result); ++ printf("range: t2--->t3\n%s", res[GAZELLE_LATENCY_WRITE_LSTACK].latency_stat_result); ++ printf("range: t0--->t3\n%s", res[GAZELLE_LATENCY_WRITE_MAX].latency_stat_result); ++ printf("t0: app send t1: into send ring t2: out of send ring t3: send to nic\n"); ++ ++ printf("Rpc:\n"); ++ printf("rpc_call_send \n%s", res[GAZELLE_LATENCY_WRITE_RPC_MSG].latency_stat_result); + + free(res); + } +-- +2.33.0 + diff --git a/0162-fix-vlan-filter-can-be-added-when-vlan_mode-1.patch b/0162-fix-vlan-filter-can-be-added-when-vlan_mode-1.patch new file mode 100644 index 0000000..05a5681 --- /dev/null +++ b/0162-fix-vlan-filter-can-be-added-when-vlan_mode-1.patch @@ -0,0 +1,33 @@ +From c392e263cb5f5392713600174d3b8955f2d26759 Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Wed, 3 Apr 2024 14:33:57 +0800 +Subject: [PATCH] fix vlan filter can be added when vlan_mode=-1 + +--- + src/lstack/core/lstack_dpdk.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 42981f4..b972c00 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -624,10 +624,12 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + } + + /* after rte_eth_dev_configure */ +- ret = rte_eth_dev_vlan_filter(port_id, get_global_cfg_params()->nic.vlan_mode, 1); +- if (ret != 0) { +- LSTACK_LOG(ERR, LSTACK, "dpdk add vlan filter failed ret = %d\n", ret); +- return -1; ++ if (get_global_cfg_params()->nic.vlan_mode != -1) { ++ ret = rte_eth_dev_vlan_filter(port_id, get_global_cfg_params()->nic.vlan_mode, 1); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "dpdk add vlan filter failed ret = %d\n", ret); ++ return -1; ++ } + } + + rte_eth_allmulticast_enable(port_id); +-- +2.33.0 + diff --git a/0163-Add-support-for-arch-ppc64le.patch b/0163-Add-support-for-arch-ppc64le.patch new file mode 100644 index 0000000..7d42df3 --- /dev/null +++ b/0163-Add-support-for-arch-ppc64le.patch @@ -0,0 +1,36 @@ +From e89442aa3aebae9896a5d5dac0e397e5da16f8de Mon Sep 17 00:00:00 2001 +From: Ren Zhijie +Date: Mon, 25 Mar 2024 16:46:08 +0800 +Subject: [PATCH] Add support for arch ppc64le + +Signed-off-by: Ren Zhijie +--- + src/ltran/CMakeLists.txt | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/ltran/CMakeLists.txt b/src/ltran/CMakeLists.txt +index a484ae3..2eb7d70 100644 +--- a/src/ltran/CMakeLists.txt ++++ b/src/ltran/CMakeLists.txt +@@ -63,6 +63,9 @@ if (DPDK_VERSION GREATER_EQUAL 23.11) + set(DPDK_LINK_FLAGS "${DPDK_LINK_FLAGS} -lrte_log -larchive -Wl,-lrte_eal") + else() + set(DPDK_LINK_FLAGS "${DPDK_LINK_FLAGS} -lrte_kni -Wl,-Bstatic -lrte_eal -Wl,-Bdynamic") ++ if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "ppc64le") ++ set(DPDK_LINK_FLAGS "${DPDK_LINK_FLAGS} -Wl,-larchive") ++ endif() + endif() + + add_executable(ltran main.c ltran_param.c ltran_config.c ltran_ethdev.c ltran_stat.c ltran_errno.c +@@ -79,7 +82,7 @@ target_compile_options(ltran PRIVATE -fno-strict-aliasing -D__ARM_FEATURE_CRC32= + -Wdeprecated -Wwrite-strings -Wno-implicit-fallthrough -D_FORTIFY_SOURCE=2 -Wno-error=deprecated-declarations) + + # gcc coredump in openEuler-20.03-LTS-XX aarch64 when add -march=native +-if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "sw_64|aarch64" ) ++if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "sw_64|aarch64|ppc64le" ) + target_compile_options(ltran PRIVATE -march=native -Wcast-align) + endif() + +-- +2.33.0 + diff --git a/0164-dfx-support-get-nic-bond-status.patch b/0164-dfx-support-get-nic-bond-status.patch new file mode 100644 index 0000000..af4f21a --- /dev/null +++ b/0164-dfx-support-get-nic-bond-status.patch @@ -0,0 +1,120 @@ +From 819f74f014592b8af93eb45fd13681caa2cb662a Mon Sep 17 00:00:00 2001 +From: zhangmengxuan +Date: Thu, 28 Mar 2024 21:24:05 +0800 +Subject: [PATCH] dfx: support get nic bond status + +--- + src/common/gazelle_dfx_msg.h | 9 +++++++++ + src/lstack/core/lstack_dpdk.c | 27 +++++++++++++++++++++++++++ + src/ltran/ltran_dfx.c | 14 ++++++++++++++ + 3 files changed, 50 insertions(+) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index d7ba80f..4929ae7 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -256,15 +256,24 @@ struct gazelle_stat_low_power_info { + + #define RTE_ETH_XSTATS_NAME_SIZE 64 + #define RTE_ETH_XSTATS_MAX_LEN 256 ++#define RTE_MAX_ETHPORTS 32 + struct nic_eth_xstats_name { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + }; + ++struct bonding { ++ int8_t mode; ++ int32_t miimon; ++ uint16_t primary_port_id; ++ uint16_t slaves[RTE_MAX_ETHPORTS]; ++}; ++ + struct nic_eth_xstats { + struct nic_eth_xstats_name xstats_name[RTE_ETH_XSTATS_MAX_LEN]; + uint64_t values[RTE_ETH_XSTATS_MAX_LEN]; + uint32_t len; + uint16_t port_id; ++ struct bonding bonding; + }; + + struct nic_eth_features { +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index a774d45..cd87026 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -870,6 +870,31 @@ static int dpdk_nic_xstats_name_get(struct nic_eth_xstats_name *names, uint16_t + return len; + } + ++void dpdk_nic_bond_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id, uint16_t *slaves, int count) ++{ ++ dfx->data.nic_xstats.bonding.mode = rte_eth_bond_mode_get(port_id); ++ if (dfx->data.nic_xstats.bonding.mode < 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eth_bond_mode_get failed.\n"); ++ return; ++ } ++ ++ dfx->data.nic_xstats.bonding.primary_port_id = rte_eth_bond_primary_get(port_id); ++ if (dfx->data.nic_xstats.bonding.primary_port_id < 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eth_bond_primary_get failed.\n"); ++ return; ++ } ++ ++ dfx->data.nic_xstats.bonding.miimon = rte_eth_bond_link_monitoring_get(port_id); ++ if (dfx->data.nic_xstats.bonding.miimon <= 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eth_bond_link_monitoring_get failed.\n"); ++ return; ++ } ++ ++ for (int i = 0; i < count; i++) { ++ dfx->data.nic_xstats.bonding.slaves[i] = slaves[i]; ++ } ++} ++ + void dpdk_nic_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id) + { + struct rte_eth_dev_info dev_info; +@@ -878,6 +903,7 @@ void dpdk_nic_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id) + + dfx->data.nic_xstats.len = -1; + dfx->data.nic_xstats.port_id = port_id; ++ dfx->data.nic_xstats.bonding.mode = -1; + ret = rte_eth_dev_info_get(port_id, &dev_info); + if (ret < 0) { + LSTACK_LOG(ERR, LSTACK, "rte_eth_dev_info_get failed.\n"); +@@ -904,6 +930,7 @@ void dpdk_nic_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id) + if (dpdk_nic_xstats_value_get(dfx->data.nic_xstats.values, len, slaves, slave_count) != 0) { + return; + } ++ dpdk_nic_bond_xstats_get(dfx, port_id, slaves, slave_count); + } else { + len = dpdk_nic_xstats_name_get(dfx->data.nic_xstats.xstats_name, port_id); + if (len <= 0) { +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 073dfa7..88d11bd 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -200,6 +200,20 @@ static void gazelle_print_lstack_xstats(void *buf, const struct gazelle_stat_msg + struct nic_eth_xstats *xstats = &stat->data.nic_xstats; + static const char *nic_stats_border = "########################"; + ++ if (xstats->bonding.mode >= 0) { ++ printf("############# NIC bonding mode display #############\n"); ++ printf("%s############################\n", nic_stats_border); ++ printf("Bonding mode: [%d]\n", xstats->bonding.mode); ++ printf("Bonding miimon: [%d]\n", xstats->bonding.miimon); ++ printf("Slaves(%d): [", xstats->port_id); ++ for (int i = 0; i < xstats->port_id - 1; i++) { ++ printf("%d ", xstats->bonding.slaves[i]); ++ } ++ printf("%d]\n", xstats->bonding.slaves[xstats->port_id - 1]); ++ printf("Primary: [%d]\n", xstats->bonding.primary_port_id); ++ printf("%s############################\n", nic_stats_border); ++ } ++ + printf("###### NIC extended statistics for port %-2d #########\n", xstats->port_id); + printf("%s############################\n", nic_stats_border); + if (xstats->len <= 0 || xstats->len > RTE_ETH_XSTATS_MAX_LEN) { +-- +2.33.0 + diff --git a/0165-remove-dpdk_skip_nic_init-for-dpdk-23.11.patch b/0165-remove-dpdk_skip_nic_init-for-dpdk-23.11.patch new file mode 100644 index 0000000..c97b59f --- /dev/null +++ b/0165-remove-dpdk_skip_nic_init-for-dpdk-23.11.patch @@ -0,0 +1,54 @@ +From aae704235da3299fb2d6920aef46afd560ab2c01 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Tue, 9 Apr 2024 17:50:46 +0800 +Subject: [PATCH] remove dpdk_skip_nic_init for dpdk-23.11 + +--- + src/lstack/core/lstack_init.c | 4 ++++ + src/lstack/include/lstack_dpdk.h | 4 +++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c +index f1ef134..79b4060 100644 +--- a/src/lstack/core/lstack_init.c ++++ b/src/lstack/core/lstack_init.c +@@ -144,7 +144,9 @@ static void create_control_thread(void) + pthread_t tid; + if (use_ltran()) { + /* The function call here should be in strict order. */ ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + dpdk_skip_nic_init(); ++#endif + if (control_init_client(false) != 0) { + LSTACK_EXIT(1, "control_init_client failed\n"); + } +@@ -279,7 +281,9 @@ __attribute__((constructor)) void gazelle_network_init(void) + + /* Init control plane and dpdk init */ + create_control_thread(); ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + dpdk_restore_pci(); ++#endif + + /* cancel the core binding from DPDK initialization */ + if (!get_global_cfg_params()->main_thread_affinity) { +diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h +index c7cfbdf..fe3d07b 100644 +--- a/src/lstack/include/lstack_dpdk.h ++++ b/src/lstack/include/lstack_dpdk.h +@@ -48,9 +48,11 @@ int32_t create_shared_ring(struct protocol_stack *stack); + void lstack_log_level_init(void); + int dpdk_ethdev_init(int port_id, bool bond_port); + int dpdk_ethdev_start(void); ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + void dpdk_skip_nic_init(void); +-int32_t dpdk_init_lstack_kni(void); + void dpdk_restore_pci(void); ++#endif ++int32_t dpdk_init_lstack_kni(void); + bool port_in_stack_queue(gz_addr_t *src_ip, gz_addr_t *dst_ip, uint16_t src_port, uint16_t dst_port); + struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_mbuf, + uint32_t mbuf_cache_size, uint16_t queue_id, unsigned numa_id); +-- +2.33.0 + diff --git a/0166-gazellectl-add-lwip-stats_proto-print.patch b/0166-gazellectl-add-lwip-stats_proto-print.patch new file mode 100644 index 0000000..bb4c27f --- /dev/null +++ b/0166-gazellectl-add-lwip-stats_proto-print.patch @@ -0,0 +1,317 @@ +From 3beb273528f360c7d6863990a5d0cdcb5ebcb407 Mon Sep 17 00:00:00 2001 +From: ningjin +Date: Thu, 28 Mar 2024 16:05:01 +0800 +Subject: [PATCH] gazellectl add lwip stats_proto print + +--- + src/common/gazelle_dfx_msg.h | 23 ++++++++++ + src/lstack/core/lstack_control_plane.c | 2 +- + src/lstack/core/lstack_stack_stat.c | 41 +++++++++++++++-- + src/lstack/include/lstack_stack_stat.h | 3 +- + src/ltran/ltran_dfx.c | 61 +++++++++++++++++++++++++- + src/ltran/ltran_monitor.c | 1 + + 6 files changed, 124 insertions(+), 7 deletions(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index d7ba80f..6cd90b1 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -24,6 +24,7 @@ + + #define GAZELLE_CLIENT_NUM_MIN 1 + #define GAZELLE_LOG_LEVEL_MAX 10 ++#define MAX_PROTOCOL_LENGTH 20 + #define GAZELLECTL_TIMEOUT 5000 // millisecond + /* maybe it should be consistent with MEMP_NUM_TCP_PCB */ + #define GAZELLE_LSTACK_MAX_CONN (20000 + 2000) // same as MAX_CLIENTS + RESERVED_CLIENTS in lwipopts.h +@@ -46,6 +47,7 @@ enum GAZELLE_STAT_MODE { + GAZELLE_STAT_LTRAN_SHOW_SOCKTABLE, + GAZELLE_STAT_LTRAN_SHOW_CONNTABLE, + GAZELLE_STAT_LTRAN_SHOW_LSTACK, ++ GAZELLE_STAT_LSTACK_SHOW_PROTOCOL, + + GAZELLE_STAT_LSTACK_SHOW, + GAZELLE_STAT_LSTACK_LOG_LEVEL_SET, +@@ -193,6 +195,24 @@ struct gazelle_stat_lstack_snmp { + uint32_t icmp_out_echo_reps; + }; + ++/* same as define in lwip/stats.h - struct stats_proto */ ++struct gazelle_stat_lstack_proto { ++ /* data */ ++ uint16_t xmit; /* Transmitted packets. */ ++ uint16_t recv; /* Received packets. */ ++ uint16_t fw; /* Forwarded packets. */ ++ uint16_t drop; /* Dropped packets. */ ++ uint16_t chkerr; /* Checksum error. */ ++ uint16_t lenerr; /* Invalid length error. */ ++ uint16_t memerr; /* Out of memory error. */ ++ uint16_t rterr; /* Routing error. */ ++ uint16_t proterr; /* Protocol error. */ ++ uint16_t opterr; /* Error in options. */ ++ uint16_t err; /* Misc error. */ ++ uint16_t cachehit; ++}; ++ ++ + /* same as define in lwip/tcp.h - struct tcp_pcb_dp */ + struct gazelle_stat_lstack_conn_info { + uint32_t state; +@@ -288,6 +308,8 @@ struct gazelle_stack_dfx_data { + struct gazelle_stat_lstack_snmp snmp; + struct nic_eth_xstats nic_xstats; + struct nic_eth_features nic_features; ++ struct gazelle_stat_lstack_proto proto_data; ++ + #ifdef GAZELLE_FAULT_INJECT_ENABLE + struct gazelle_fault_inject_data inject; + #endif /* GAZELLE_FAULT_INJECT_ENABLE */ +@@ -321,6 +343,7 @@ struct gazelle_stat_msg_request { + union stat_param { + char log_level[GAZELLE_LOG_LEVEL_MAX]; + uint16_t low_power_mod; ++ char protocol[MAX_PROTOCOL_LENGTH]; + #ifdef GAZELLE_FAULT_INJECT_ENABLE + struct gazelle_fault_inject_data inject; + #endif /* GAZELLE_FAULT_INJECT_ENABLE */ +diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c +index 9f0c313..04858c7 100644 +--- a/src/lstack/core/lstack_control_plane.c ++++ b/src/lstack/core/lstack_control_plane.c +@@ -601,7 +601,7 @@ static int32_t handle_stat_request(int32_t sockfd) + msg.stat_mode == GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES) { + return handle_dpdk_cmd(sockfd, msg.stat_mode); + } else { +- ret = handle_stack_cmd(sockfd, msg.stat_mode); ++ ret = handle_stack_cmd(sockfd, &msg); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "get_stats failed ret=%d\n", ret); + } +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index 3e016b7..d439357 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -210,11 +210,42 @@ static void get_stack_stats(struct gazelle_stack_dfx_data *dfx, struct protocol_ + dfx->data.pkts.conn_num = stack->conn_num; + } + ++static void get_stack_dfx_data_proto(struct gazelle_stack_dfx_data *dfx, struct protocol_stack *stack, ++ struct gazelle_stat_msg_request *msg) ++{ ++ int32_t ret = 0; ++ msg->data.protocol[MAX_PROTOCOL_LENGTH - 1] = '\0'; ++ const char* proto_mode = msg->data.protocol; ++ ++ if (strcmp(proto_mode, "UDP") == 0) { ++ ret = memcpy_s(&dfx->data.proto_data, sizeof(dfx->data.proto_data), ++ &stack->lwip_stats->udp, sizeof(stack->lwip_stats->udp)); ++ } else if (strcmp(proto_mode, "TCP") == 0) { ++ ret = memcpy_s(&dfx->data.proto_data, sizeof(dfx->data.proto_data), ++ &stack->lwip_stats->tcp, sizeof(stack->lwip_stats->tcp)); ++ } else if (strcmp(proto_mode, "IP") == 0) { ++ ret = memcpy_s(&dfx->data.proto_data, sizeof(dfx->data.proto_data), ++ &stack->lwip_stats->ip, sizeof(stack->lwip_stats->ip)); ++ } else if (strcmp(proto_mode, "ICMP") == 0) { ++ ret = memcpy_s(&dfx->data.proto_data, sizeof(dfx->data.proto_data), ++ &stack->lwip_stats->icmp, sizeof(stack->lwip_stats->icmp)); ++ } else if (strcmp(proto_mode, "ETHARP") == 0) { ++ ret = memcpy_s(&dfx->data.proto_data, sizeof(dfx->data.proto_data), ++ &stack->lwip_stats->etharp, sizeof(stack->lwip_stats->etharp)); ++ } else { ++ printf("Error: Invalid protocol\n"); ++ } ++ if (ret != EOK) { ++ LSTACK_LOG(ERR, LSTACK, "memcpy_s err ret=%d \n", ret); ++ } ++} ++ + static void get_stack_dfx_data(struct gazelle_stack_dfx_data *dfx, struct protocol_stack *stack, +- enum GAZELLE_STAT_MODE stat_mode) ++ struct gazelle_stat_msg_request *msg) + { + int32_t rpc_call_result; + int32_t ret; ++ enum GAZELLE_STAT_MODE stat_mode = msg->stat_mode; + + switch (stat_mode) { + case GAZELLE_STAT_LSTACK_SHOW: +@@ -255,6 +286,9 @@ static void get_stack_dfx_data(struct gazelle_stack_dfx_data *dfx, struct protoc + case GAZELLE_STAT_LTRAN_STOP_LATENCY: + set_latency_start_flag(false); + break; ++ case GAZELLE_STAT_LSTACK_SHOW_PROTOCOL: ++ get_stack_dfx_data_proto(dfx, stack, msg); ++ break; + default: + break; + } +@@ -298,16 +332,17 @@ int handle_dpdk_cmd(int fd, enum GAZELLE_STAT_MODE stat_mode) + return 0; + } + +-int handle_stack_cmd(int fd, enum GAZELLE_STAT_MODE stat_mode) ++int handle_stack_cmd(int fd, struct gazelle_stat_msg_request *msg) + { + struct gazelle_stack_dfx_data dfx; + struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ enum GAZELLE_STAT_MODE stat_mode = msg->stat_mode; + + for (uint32_t i = 0; i < stack_group->stack_num; i++) { + struct protocol_stack *stack = stack_group->stacks[i]; + + memset_s(&dfx, sizeof(dfx), 0, sizeof(dfx)); +- get_stack_dfx_data(&dfx, stack, stat_mode); ++ get_stack_dfx_data(&dfx, stack, msg); + + if (!use_ltran() && + (stat_mode == GAZELLE_STAT_LTRAN_START_LATENCY || stat_mode == GAZELLE_STAT_LTRAN_STOP_LATENCY)) { +diff --git a/src/lstack/include/lstack_stack_stat.h b/src/lstack/include/lstack_stack_stat.h +index 87951aa..867f35b 100644 +--- a/src/lstack/include/lstack_stack_stat.h ++++ b/src/lstack/include/lstack_stack_stat.handle +@@ -21,13 +21,14 @@ struct wakeup_poll; + struct protocol_stack; + enum GAZELLE_LATENCY_TYPE; + enum GAZELLE_STAT_MODE; ++struct gazelle_stat_msg_request; + + void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const struct pbuf *pbuf, + enum GAZELLE_LATENCY_TYPE type, uint64_t time_record); + void calculate_rpcmsg_latency(struct gazelle_stack_latency *stack_latency, struct rpc_msg *msg, + enum GAZELLE_LATENCY_TYPE type); + void stack_stat_init(void); +-int handle_stack_cmd(int fd, enum GAZELLE_STAT_MODE stat_mode); ++int handle_stack_cmd(int fd, struct gazelle_stat_msg_request *msg); + int handle_dpdk_cmd(int fd, enum GAZELLE_STAT_MODE stat_mode); + uint64_t get_current_time(void); + void lstack_get_low_power_info(struct gazelle_stat_low_power_info *low_power_info); +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 073dfa7..717744a 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -136,6 +136,7 @@ static void gazelle_print_ltran_conn(void *buf, const struct gazelle_stat_msg_re + static void gazelle_print_lstack_xstats(void *buf, const struct gazelle_stat_msg_request *req_msg); + static void gazelle_print_lstack_aggregate(void *buf, const struct gazelle_stat_msg_request *req_msg); + static void gazelle_print_lstack_nic_features(void *buf, const struct gazelle_stat_msg_request *req_msg); ++static void gazelle_print_lstack_stat_proto(void *buf, const struct gazelle_stat_msg_request *req_msg); + + #ifdef GAZELLE_FAULT_INJECT_ENABLE + static void gazelle_print_fault_inject_set_status(void *buf, const struct gazelle_stat_msg_request *req_msg); +@@ -168,7 +169,8 @@ static struct gazelle_dfx_list g_gazelle_dfx_tbl[] = { + {GAZELLE_STAT_LSTACK_SHOW_XSTATS, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_xstats}, + {GAZELLE_STAT_LSTACK_SHOW_AGGREGATE, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_aggregate}, + {GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_nic_features}, +- ++ {GAZELLE_STAT_LSTACK_SHOW_PROTOCOL, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_stat_proto}, ++ + #ifdef GAZELLE_FAULT_INJECT_ENABLE + {GAZELLE_STAT_FAULT_INJECT_SET, sizeof(struct gazelle_stack_dfx_data), gazelle_print_fault_inject_set_status}, + {GAZELLE_STAT_FAULT_INJECT_UNSET, sizeof(struct gazelle_stack_dfx_data), gazelle_print_fault_inject_unset_status}, +@@ -1083,6 +1085,20 @@ static void gazelle_print_lstack_stat_snmp_core(const struct gazelle_stack_dfx_d + printf("icmp_out_echo_reps: %u\n", snmp->icmp_out_echo_reps); + } + ++static void gazelle_print_lstack_stat_proto_core(const struct gazelle_stack_dfx_data *stat, ++ const struct gazelle_stat_lstack_proto *proto) ++{ ++ printf("\n------ stack tid: %6u ------\n", stat->tid); ++ printf("xmit: %u\n", proto->xmit); ++ printf("recv: %u\n", proto->recv); ++ printf("fw: %u\n", proto->fw); ++ printf("drop: %u\n", proto->drop); ++ printf("chkerr: %u\n", proto->chkerr); ++ printf("lenerr: %u\n", proto->lenerr); ++ printf("memerr: %u\n", proto->memerr); ++ printf("rterr: %u\n", proto->rterr); ++} ++ + static void gazelle_print_lstack_stat_snmp(void *buf, const struct gazelle_stat_msg_request *req_msg) + { + int32_t ret; +@@ -1102,6 +1118,26 @@ static void gazelle_print_lstack_stat_snmp(void *buf, const struct gazelle_stat_ + } while (true); + } + ++static void gazelle_print_lstack_stat_proto(void *buf, const struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t ret; ++ struct gazelle_stack_dfx_data *stat = (struct gazelle_stack_dfx_data *)buf; ++ struct gazelle_stat_lstack_proto *proto = NULL; ++ ++ proto = &stat->data.proto_data; ++ printf("Statistics of lstack proto:\n"); ++ do { ++ gazelle_print_lstack_stat_proto_core(stat, proto); ++ if (stat->eof != 0) { ++ break; ++ } ++ ret = dfx_stat_read_from_ltran(buf, sizeof(struct gazelle_stack_dfx_data), req_msg->stat_mode); ++ if (ret != GAZELLE_OK) { ++ return; ++ } ++ } while (true); ++} ++ + static void gazelle_keepalive_string(char* str, int buff_len, struct gazelle_stat_lstack_conn_info *conn_info) + { + if (conn_info->keepalive == 0) { +@@ -1240,6 +1276,7 @@ static void show_usage(void) + " loglevel {error | info | debug} set lstack loglevel \n" + " lowpower {0 | 1} set lowpower enable \n" + " [time] measure latency time default 1S, maximum 30mins \n\n" ++ " -p, protocol {UDP | TCP | ICMP | IP | ETHARP | IP_FRAG} show lstack protocol statistics \n" + #ifdef GAZELLE_FAULT_INJECT_ENABLE + " *inject params*\n" + " |inject_type | digit_param_1 | digit_param_2 | inject_rule |\n" +@@ -1444,6 +1481,25 @@ static int parse_delay_arg(int32_t argc, char *argv[], long int delay) + return 0; + } + ++static int32_t parse_dfx_lstack_show_proto_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) ++{ ++ int32_t cmd_index = 0; ++ int32_t ret; ++ ++ char *param = argv[GAZELLE_OPTIONS2_ARG_IDX]; ++ if (strcmp(param, "UDP") != 0 && strcmp(param, "TCP") != 0 && strcmp(param, "IP") && ++ strcmp(param, "ICMP") && strcmp(param, "ETHARP") != 0) { ++ return cmd_index; ++ } ++ ret = strncpy_s(req_msg[cmd_index].data.protocol, MAX_PROTOCOL_LENGTH, argv[GAZELLE_OPTIONS2_ARG_IDX], ++ MAX_PROTOCOL_LENGTH - 1); ++ if (ret != EOK) { ++ return -1; ++ } ++ req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_PROTOCOL; ++ return cmd_index; ++} ++ + static int32_t parse_dfx_lstack_show_args(int32_t argc, char *argv[], struct gazelle_stat_msg_request *req_msg) + { + int32_t cmd_index = 0; +@@ -1490,8 +1546,9 @@ static int32_t parse_dfx_lstack_show_args(int32_t argc, char *argv[], struct gaz + } + } else if (strcmp(param, "-k") == 0 || strcmp(param, "nic-features") == 0) { + req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES; ++ } else if (strcmp(param, "protocol") == 0 || strcmp(param, "-p") == 0) { ++ cmd_index = parse_dfx_lstack_show_proto_args(argc, argv, req_msg); + } +- + return cmd_index; + } + +diff --git a/src/ltran/ltran_monitor.c b/src/ltran/ltran_monitor.c +index ea31e84..457e8c8 100644 +--- a/src/ltran/ltran_monitor.c ++++ b/src/ltran/ltran_monitor.c +@@ -347,6 +347,7 @@ static int32_t lstack_req_mode_process(int32_t fd, const struct gazelle_stat_msg + case GAZELLE_STAT_LSTACK_SHOW_CONN: + case GAZELLE_STAT_LSTACK_SHOW_LATENCY: + case GAZELLE_STAT_LSTACK_LOW_POWER_MDF: ++ case GAZELLE_STAT_LSTACK_SHOW_PROTOCOL: + handle_resp_lstack_transfer(req_msg, fd); + break; + default: +-- +2.33.0 + diff --git a/0167-fix-port-not-support-vlan-filter.patch b/0167-fix-port-not-support-vlan-filter.patch new file mode 100644 index 0000000..3083078 --- /dev/null +++ b/0167-fix-port-not-support-vlan-filter.patch @@ -0,0 +1,26 @@ +From 3171100d06146791ab9d22523805b8ed580daf3f Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Fri, 12 Apr 2024 15:09:12 +0800 +Subject: [PATCH] fix port not support vlan filter + +--- + src/lstack/core/lstack_dpdk.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index a6a8a01..5d90408 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -624,7 +624,8 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + } + + /* after rte_eth_dev_configure */ +- if (get_global_cfg_params()->nic.vlan_mode != -1) { ++ if ((get_global_cfg_params()->nic.vlan_mode != -1) && ++ ((stack_group->rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) == RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) { + ret = rte_eth_dev_vlan_filter(port_id, get_global_cfg_params()->nic.vlan_mode, 1); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk add vlan filter failed ret = %d\n", ret); +-- +2.33.0 + diff --git a/0168-fix-tcp-recv-does-not-return-pkg-when-ring-buffer-is.patch b/0168-fix-tcp-recv-does-not-return-pkg-when-ring-buffer-is.patch new file mode 100644 index 0000000..01ded10 --- /dev/null +++ b/0168-fix-tcp-recv-does-not-return-pkg-when-ring-buffer-is.patch @@ -0,0 +1,27 @@ +From 5fff605ff68741482d7fff992343eaccb383115f Mon Sep 17 00:00:00 2001 +From: li_yunqing +Date: Fri, 22 Mar 2024 15:47:19 +0800 +Subject: [PATCH] fix tcp recv does not return pkg when ring buffer is empty + +--- + src/lstack/core/lstack_lwip.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index a604a62..51238ba 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -925,7 +925,9 @@ static ssize_t recv_ring_tcp_read(struct lwip_sock *sock, void *buf, size_t len, + } + + while (recv_left > 0) { +- if (recv_ring_get_one(sock, noblock, &pbuf) != 0) { ++ if (recv_ring_get_one(sock, noblock | recvd, &pbuf) != 0) { ++ /* When the buffer is empty, it will be returned directly ++ if in non-blocking mode or if data has already been received */ + break; + } + +-- +2.33.0 + diff --git a/0169-add-tuple_fileter-error-info.patch b/0169-add-tuple_fileter-error-info.patch new file mode 100644 index 0000000..e15770e --- /dev/null +++ b/0169-add-tuple_fileter-error-info.patch @@ -0,0 +1,24 @@ +From e4d3f17fbb3efce9e29c86838a09fa1f9e224fd3 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Tue, 16 Apr 2024 03:46:12 +0000 +Subject: [PATCH] add tuple_fileter error info + +--- + src/lstack/core/lstack_cfg.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index b533a33..533eb6c 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -1159,6 +1159,7 @@ static int parse_tuple_filter(void) + return 0; + } + if (g_config_params.use_ltran || g_config_params.listen_shadow) { ++ LSTACK_LOG(ERR, LSTACK, "tuple filter and (ltran or listen_shadow) cannot be enabled at the same time\n"); + return -EINVAL; + } + +-- +2.33.0 + diff --git a/0170-adapt-dpdk-23.11-remove-kni.patch b/0170-adapt-dpdk-23.11-remove-kni.patch new file mode 100644 index 0000000..f264f5d --- /dev/null +++ b/0170-adapt-dpdk-23.11-remove-kni.patch @@ -0,0 +1,80 @@ +From 201e8d1e2fad0d83ea1544fd14b35492d8dd72bc Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Wed, 17 Apr 2024 15:43:07 +0800 +Subject: [PATCH] adapt dpdk-23.11 remove kni + +--- + src/lstack/core/lstack_dpdk.c | 4 +++- + src/lstack/core/lstack_init.c | 4 ++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 5d90408..016276a 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -694,6 +694,7 @@ int32_t dpdk_ethdev_start(void) + return 0; + } + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + int32_t dpdk_init_lstack_kni(void) + { + struct protocol_stack_group *stack_group = get_protocol_stack_group(); +@@ -712,7 +713,6 @@ int32_t dpdk_init_lstack_kni(void) + return 0; + } + +-#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + void dpdk_skip_nic_init(void) + { + /* when lstack init nic again, ltran can't read pkts from nic. unregister pci_bus to avoid init nic in lstack */ +@@ -799,12 +799,14 @@ int32_t init_dpdk_ethdev(void) + } + } + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + if (get_global_cfg_params()->kni_switch && get_global_cfg_params()->is_primary) { + ret = dpdk_init_lstack_kni(); + if (ret < 0) { + return -1; + } + } ++#endif + + return 0; + } +diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c +index 79b4060..c2499d7 100644 +--- a/src/lstack/core/lstack_init.c ++++ b/src/lstack/core/lstack_init.c +@@ -183,6 +183,7 @@ static void gazelle_signal_init(void) + lstack_signal_init(); + } + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + static void set_kni_ip_mac() + { + struct cfg_params *cfg = get_global_cfg_params(); +@@ -230,6 +231,7 @@ static void set_kni_ip_mac() + + posix_api->close_fn(fd); + } ++#endif + + __attribute__((constructor)) void gazelle_network_init(void) + { +@@ -315,9 +317,11 @@ __attribute__((constructor)) void gazelle_network_init(void) + /* lwip initialization */ + lwip_sock_init(); + ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + if (get_global_cfg_params()->kni_switch) { + set_kni_ip_mac(); + } ++#endif + + if (set_process_start_flag() != 0) { + gazelle_exit(); +-- +2.33.0 + diff --git a/0171-fix-ioctl-set-failed.patch b/0171-fix-ioctl-set-failed.patch new file mode 100644 index 0000000..e1cfefc --- /dev/null +++ b/0171-fix-ioctl-set-failed.patch @@ -0,0 +1,49 @@ +From 5924fd2879acbb52b12a61380b939cce30a133a9 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sun, 28 Apr 2024 10:44:15 +0800 +Subject: [PATCH] fix ioctl set failed + +--- + src/lstack/api/lstack_wrap.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index c90aa04..7101d98 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -690,13 +690,27 @@ static int32_t do_select(int32_t nfds, fd_set *readfds, fd_set *writefds, fd_set + if (select_posix_path() == PATH_KERNEL || \ + select_fd_posix_path(_fd, &sock) == PATH_KERNEL) \ + return _fcntl_fn(_fd, _cmd, val); \ +- int32_t ret = _fcntl_fn(_fd, _cmd, val); \ +- if (ret == -1) \ +- return ret; \ +- return _lwip_fcntl(_fd, _cmd, val); \ ++ int32_t ret1 = _fcntl_fn(_fd, _cmd, val); \ ++ if (ret1 == -1) { \ ++ LSTACK_LOG(ERR, LSTACK, "fd(%d) kernel path call failed, errno is %d, maybe not error\n", \ ++ _fd, errno); \ ++ return ret1; \ ++ } \ ++ int32_t ret2 = _lwip_fcntl(_fd, _cmd, val); \ ++ /* ++ * if function not implemented, fcntl get/set context will not be modifyed by user path, ++ * return kernel path result ++ */ \ ++ if (ret2 == -1) { \ ++ if (errno == ENOSYS) { \ ++ return ret1; \ ++ } \ ++ LSTACK_LOG(ERR, LSTACK, "fd(%d) user path call failed, errno is %d, maybe not error\n", \ ++ _fd, errno); \ ++ } \ ++ return ret2; \ + } while (0) + +- + /* -------------------------------------------------------- + * ------- LD_PRELOAD mode replacement interface -------- + * -------------------------------------------------------- +-- +2.33.0 + diff --git a/0172-ltran-memset-quintuple.patch b/0172-ltran-memset-quintuple.patch new file mode 100644 index 0000000..94a2d36 --- /dev/null +++ b/0172-ltran-memset-quintuple.patch @@ -0,0 +1,25 @@ +From 3e10c7661d412082990d88d479c02d77c14fbd8c Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Tue, 30 Apr 2024 09:56:59 +0800 +Subject: [PATCH] ltran: memset quintuple + +--- + src/ltran/ltran_forward.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ltran/ltran_forward.c b/src/ltran/ltran_forward.c +index a5756d7..0658b11 100644 +--- a/src/ltran/ltran_forward.c ++++ b/src/ltran/ltran_forward.c +@@ -251,7 +251,7 @@ static __rte_always_inline int32_t tcp_handle(struct rte_mbuf *m, const struct r + { + struct gazelle_tcp_conn *tcp_conn = NULL; + struct gazelle_tcp_sock *tcp_sock = NULL; +- struct gazelle_quintuple quintuple; ++ struct gazelle_quintuple quintuple = {0}; + + quintuple.dst_ip.u_addr.ip4.addr = ipv4_hdr->dst_addr; + quintuple.src_ip.u_addr.ip4.addr = ipv4_hdr->src_addr; +-- +2.33.0 + diff --git a/0173-gazellectl-add-lwip-stats_proto-print.patch b/0173-gazellectl-add-lwip-stats_proto-print.patch new file mode 100644 index 0000000..82ec1dd --- /dev/null +++ b/0173-gazellectl-add-lwip-stats_proto-print.patch @@ -0,0 +1,69 @@ +From 62297e7fb9299a75bc582b1abb4343e88e5c7c05 Mon Sep 17 00:00:00 2001 +From: ningjin +Date: Thu, 28 Mar 2024 16:05:01 +0800 +Subject: [PATCH] gazellectl add lwip stats_proto print + +--- + src/common/gazelle_dfx_msg.h | 4 ++++ + src/ltran/ltran_dfx.c | 12 +++++++----- + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 5d626a2..17e1662 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -206,6 +206,10 @@ struct gazelle_stat_lstack_proto { + /* data */ + uint16_t xmit; /* Transmitted packets. */ + uint16_t recv; /* Received packets. */ ++ uint16_t tx_in; /* Transmitted in packets. */ ++ uint16_t tx_out; /* Transmitted out packets. */ ++ uint16_t rx_in; /* Received in packets. */ ++ uint16_t rx_out; /* Received out packets. */ + uint16_t fw; /* Forwarded packets. */ + uint16_t drop; /* Dropped packets. */ + uint16_t chkerr; /* Checksum error. */ +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index c81cce2..f4e55e3 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -1114,8 +1114,10 @@ static void gazelle_print_lstack_stat_proto_core(const struct gazelle_stack_dfx_ + const struct gazelle_stat_lstack_proto *proto) + { + printf("\n------ stack tid: %6u ------\n", stat->tid); +- printf("xmit: %u\n", proto->xmit); +- printf("recv: %u\n", proto->recv); ++ printf("tx_in: %u\n", proto->tx_in); ++ printf("tx_out: %u\n", proto->tx_out); ++ printf("rx_in: %u\n", proto->rx_in); ++ printf("rx_out: %u\n", proto->rx_out); + printf("fw: %u\n", proto->fw); + printf("drop: %u\n", proto->drop); + printf("chkerr: %u\n", proto->chkerr); +@@ -1297,11 +1299,11 @@ static void show_usage(void) + " -x, xstats show lstack xstats \n" + " -k, nic-features show state of protocol offload and other features \n" + " -a, aggregatin [time] show lstack send/recv aggregation \n" ++ " -p, protocol {UDP | TCP | ICMP | IP | ETHARP} show lstack protocol statistics \n" + " set: \n" + " loglevel {error | info | debug} set lstack loglevel \n" + " lowpower {0 | 1} set lowpower enable \n" + " [time] measure latency time default 1S, maximum 30mins \n\n" +- " -p, protocol {UDP | TCP | ICMP | IP | ETHARP | IP_FRAG} show lstack protocol statistics \n" + #ifdef GAZELLE_FAULT_INJECT_ENABLE + " *inject params*\n" + " |inject_type | digit_param_1 | digit_param_2 | inject_rule |\n" +@@ -1512,8 +1514,8 @@ static int32_t parse_dfx_lstack_show_proto_args(int32_t argc, char *argv[], stru + int32_t ret; + + char *param = argv[GAZELLE_OPTIONS2_ARG_IDX]; +- if (strcmp(param, "UDP") != 0 && strcmp(param, "TCP") != 0 && strcmp(param, "IP") && +- strcmp(param, "ICMP") && strcmp(param, "ETHARP") != 0) { ++ if ((param == NULL) || (strcmp(param, "UDP") != 0 && strcmp(param, "TCP") != 0 && strcmp(param, "IP") && ++ strcmp(param, "ICMP") && strcmp(param, "ETHARP") != 0)) { + return cmd_index; + } + ret = strncpy_s(req_msg[cmd_index].data.protocol, MAX_PROTOCOL_LENGTH, argv[GAZELLE_OPTIONS2_ARG_IDX], +-- +2.33.0 + diff --git a/0174-CFG-set-multicast-IP-assert.patch b/0174-CFG-set-multicast-IP-assert.patch new file mode 100644 index 0000000..0bdb20e --- /dev/null +++ b/0174-CFG-set-multicast-IP-assert.patch @@ -0,0 +1,28 @@ +From 38f5dbd34dfede9fc4a22c89903132fafc01fc6d Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Mon, 29 Apr 2024 17:07:15 +0800 +Subject: [PATCH] CFG:set multicast IP assert + +--- + src/lstack/core/lstack_cfg.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 533eb6c..319a720 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -244,6 +244,11 @@ static int32_t parse_host_addr(void) + if (g_config_params.host_addr.addr == INADDR_NONE) { + return -EINVAL; + } ++ ++ if (IN_MULTICAST(g_config_params.host_addr.addr)) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: host_addr:%s should not be a multicast IP.", value); ++ return -EINVAL; ++ } + return 0; + } + +-- +2.33.0 + diff --git a/0175-cfg-devices-must-be-in-bond_slave_mac-for-BONDING_MO.patch b/0175-cfg-devices-must-be-in-bond_slave_mac-for-BONDING_MO.patch new file mode 100644 index 0000000..fef0c39 --- /dev/null +++ b/0175-cfg-devices-must-be-in-bond_slave_mac-for-BONDING_MO.patch @@ -0,0 +1,47 @@ +From 82ad5f93a2bd11411fec78ec7bcb26d6055fdfda Mon Sep 17 00:00:00 2001 +From: zhangmengxuan +Date: Mon, 29 Apr 2024 10:43:37 +0800 +Subject: [PATCH] cfg: devices must be in bond_slave_mac for + BONDING_MODE_ACTIVE + +--- + src/lstack/core/lstack_cfg.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 533eb6c..8073dd4 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -1210,6 +1210,16 @@ static int32_t parse_bond_miimon(void) + return ret; + } + ++static bool validate_bond_mac(uint8_t *mac_addr, struct rte_ether_addr *bond_slave_mac, int num_slaves) ++{ ++ for (int i = 0; i < num_slaves; i++) { ++ if (memcmp(mac_addr, bond_slave_mac[i].addr_bytes, ETHER_ADDR_LEN) == 0) { ++ return true; ++ } ++ } ++ return false; ++} ++ + static int32_t parse_bond_slave_mac(void) + { + if (g_config_params.bond_mode == -1) { +@@ -1252,6 +1262,12 @@ static int32_t parse_bond_slave_mac(void) + k = k + 1; + } + free(bond_slave_mac_tmp); ++ if (g_config_params.bond_mode == BONDING_MODE_ACTIVE_BACKUP) { ++ if (!validate_bond_mac(g_config_params.mac_addr, g_config_params.bond_slave_mac_addr, GAZELLE_MAX_BOND_NUM)) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: devices must be in bond_slave_mac for BONDING_MODE_ACTIVE_BACKUP.\n"); ++ return -EINVAL; ++ } ++ } + return ret; + } + +-- +2.33.0 + diff --git a/0176-CFG-fix-multicast-IP-assert-error.patch b/0176-CFG-fix-multicast-IP-assert-error.patch new file mode 100644 index 0000000..ec26a4b --- /dev/null +++ b/0176-CFG-fix-multicast-IP-assert-error.patch @@ -0,0 +1,25 @@ +From f9407c8871223cef6dfbc66afb89a3b1b13b811a Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Wed, 8 May 2024 16:32:44 +0800 +Subject: [PATCH] CFG:fix multicast IP assert error + +--- + src/lstack/core/lstack_cfg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 7967bb7..9efdbaa 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -245,7 +245,7 @@ static int32_t parse_host_addr(void) + return -EINVAL; + } + +- if (IN_MULTICAST(g_config_params.host_addr.addr)) { ++ if (IN_MULTICAST(ntohl(g_config_params.host_addr.addr))) { + LSTACK_PRE_LOG(LSTACK_ERR, "cfg: host_addr:%s should not be a multicast IP.", value); + return -EINVAL; + } +-- +2.33.0 + diff --git a/0177-fix-mbuf-leak-in-dpdk-23.11-due-to-kni-removed.patch b/0177-fix-mbuf-leak-in-dpdk-23.11-due-to-kni-removed.patch new file mode 100644 index 0000000..042fd04 --- /dev/null +++ b/0177-fix-mbuf-leak-in-dpdk-23.11-due-to-kni-removed.patch @@ -0,0 +1,82 @@ +From 27af442164cce5ccb7df65435f76262ebb2d810e Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Thu, 9 May 2024 15:27:48 +0800 +Subject: [PATCH] fix mbuf leak in dpdk-23.11 due to kni removed + +--- + src/lstack/core/lstack_dpdk.c | 3 +++ + src/lstack/core/lstack_protocol_stack.c | 3 ++- + src/lstack/netif/lstack_ethdev.c | 2 ++ + src/ltran/ltran_forward.c | 5 ++++- + 4 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 016276a..ec35f9c 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -321,6 +321,9 @@ int32_t fill_mbuf_to_ring(struct rte_mempool *mempool, struct rte_ring *ring, ui + ret = gazelle_ring_sp_enqueue(ring, (void **)free_buf, batch); + if (ret == 0) { + LSTACK_LOG(ERR, LSTACK, "cannot enqueue to ring, count: %u\n", batch); ++ for (int i = 0; i < batch; i++) { ++ rte_pktmbuf_free(free_buf[i]); ++ } + return -1; + } + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 04d54c5..892c16d 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -937,16 +937,17 @@ void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack + + ret = rpc_call_arp(&stack->rpc_queue, mbuf_copy); + if (ret != 0) { ++ rte_pktmbuf_free(mbuf_copy); + return; + } + } ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + if (ret != 0) { + cur_stack->stats.rx_allocmbuf_fail++; + return; + } + copy_mbuf(mbuf_copy, mbuf); +-#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + kni_handle_tx(mbuf_copy); + #endif + return; +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 23edc19..048ea92 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -173,6 +173,8 @@ int32_t eth_dev_poll(void) + } else if (transfer_type == TRANSFER_KERNEL) { + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + kni_handle_tx(stack->pkts[i]); ++#else ++ rte_pktmbuf_free(stack->pkts[i]); + #endif + } else { + /* transfer to other thread */ +diff --git a/src/ltran/ltran_forward.c b/src/ltran/ltran_forward.c +index a5756d7..d27f073 100644 +--- a/src/ltran/ltran_forward.c ++++ b/src/ltran/ltran_forward.c +@@ -424,8 +424,11 @@ forward_to_kni: + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + if (get_ltran_config()->dpdk.kni_switch == GAZELLE_ON) { + enqueue_rx_packet(get_kni_stack(), m); +- } ++ } else + #endif ++ { ++ rte_pktmbuf_free(m); ++ } + return; + } + +-- +2.33.0 + diff --git a/0178-add-riscv64-support.patch b/0178-add-riscv64-support.patch new file mode 100644 index 0000000..a1cbcb7 --- /dev/null +++ b/0178-add-riscv64-support.patch @@ -0,0 +1,48 @@ +From c17a61a4e7872af8eabdf213f71ff8aad84687ad Mon Sep 17 00:00:00 2001 +From: laokz +Date: Thu, 9 May 2024 18:44:28 +0800 +Subject: [PATCH] add riscv64 support + +--- + src/lstack/Makefile | 2 +- + src/ltran/CMakeLists.txt | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/lstack/Makefile b/src/lstack/Makefile +index d2c039d..ace33bd 100644 +--- a/src/lstack/Makefile ++++ b/src/lstack/Makefile +@@ -109,7 +109,7 @@ else + $(LIB_PATH)/librte_net_virtio.so \ + $(LIB_PATH)/librte_telemetry.so \ + $(LIB_PATH)/librte_pcapng.so +- ifneq ($(ARCH), loongarch64) ++ ifeq ($(filter loongarch64 riscv64, $(ARCH)),) + LIBRTE_LIB += $(LIB_PATH)/librte_net_i40e.so + endif + endif +diff --git a/src/ltran/CMakeLists.txt b/src/ltran/CMakeLists.txt +index 2eb7d70..fee3a94 100644 +--- a/src/ltran/CMakeLists.txt ++++ b/src/ltran/CMakeLists.txt +@@ -54,7 +54,7 @@ if (DPDK_VERSION STREQUAL "19.11") + else() + set(DPDK_LINK_FLAGS "-Wl,-lrte_net_bond -Wl,-lrte_net_hinic -Wl,-lrte_net_ixgbe \ + -Wl,-lpcap -Wl,-lrte_net_pcap -Wl,-lrte_net_virtio -Wl,-lrte_pcapng -Wl,-lrte_telemetry") +- if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "loongarch64") ++ if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "loongarch64|riscv64") + set(DPDK_LINK_FLAGS "${DPDK_LINK_FLAGS} -Wl,-lrte_net_i40e") + endif() + endif() +@@ -82,7 +82,7 @@ target_compile_options(ltran PRIVATE -fno-strict-aliasing -D__ARM_FEATURE_CRC32= + -Wdeprecated -Wwrite-strings -Wno-implicit-fallthrough -D_FORTIFY_SOURCE=2 -Wno-error=deprecated-declarations) + + # gcc coredump in openEuler-20.03-LTS-XX aarch64 when add -march=native +-if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "sw_64|aarch64|ppc64le" ) ++if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "sw_64|aarch64|ppc64le|riscv64" ) + target_compile_options(ltran PRIVATE -march=native -Wcast-align) + endif() + +-- +2.33.0 + diff --git a/0179-dfx-fix-gazellectl-x-for-bond.patch b/0179-dfx-fix-gazellectl-x-for-bond.patch new file mode 100644 index 0000000..f9c46fe --- /dev/null +++ b/0179-dfx-fix-gazellectl-x-for-bond.patch @@ -0,0 +1,59 @@ +From 3c3f69c0ca77b3d05df27aeda2fb7daa9757f50c Mon Sep 17 00:00:00 2001 +From: zhangmengxuan +Date: Mon, 13 May 2024 14:51:18 +0800 +Subject: [PATCH] dfx: fix gazellectl -x for bond + +--- + src/common/gazelle_dfx_msg.h | 1 + + src/lstack/core/lstack_dpdk.c | 2 ++ + src/ltran/ltran_dfx.c | 7 ++++--- + 3 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 17e1662..9f88203 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -296,6 +296,7 @@ struct bonding { + int32_t miimon; + uint16_t primary_port_id; + uint16_t slaves[RTE_MAX_ETHPORTS]; ++ uint16_t slave_count; + }; + + struct nic_eth_xstats { +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index ec35f9c..f1a22ea 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -905,6 +905,8 @@ void dpdk_nic_bond_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_ + return; + } + ++ dfx->data.nic_xstats.bonding.slave_count = count; ++ + for (int i = 0; i < count; i++) { + dfx->data.nic_xstats.bonding.slaves[i] = slaves[i]; + } +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index f4e55e3..aa08f25 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -207,11 +207,12 @@ static void gazelle_print_lstack_xstats(void *buf, const struct gazelle_stat_msg + printf("%s############################\n", nic_stats_border); + printf("Bonding mode: [%d]\n", xstats->bonding.mode); + printf("Bonding miimon: [%d]\n", xstats->bonding.miimon); +- printf("Slaves(%d): [", xstats->port_id); +- for (int i = 0; i < xstats->port_id - 1; i++) { ++ printf("Port range: 0->%d; Bonding port is %d\n", xstats->port_id, xstats->port_id); ++ printf("Slaves(%d): [", xstats->bonding.slave_count); ++ for (int i = 0; i < xstats->bonding.slave_count - 1; i++) { + printf("%d ", xstats->bonding.slaves[i]); + } +- printf("%d]\n", xstats->bonding.slaves[xstats->port_id - 1]); ++ printf("%d]\n", xstats->bonding.slaves[xstats->bonding.slave_count - 1]); + printf("Primary: [%d]\n", xstats->bonding.primary_port_id); + printf("%s############################\n", nic_stats_border); + } +-- +2.33.0 + diff --git a/0180-change-gazelle_stat_lstack_proto-from-u16-to-u64.patch b/0180-change-gazelle_stat_lstack_proto-from-u16-to-u64.patch new file mode 100644 index 0000000..bac10b5 --- /dev/null +++ b/0180-change-gazelle_stat_lstack_proto-from-u16-to-u64.patch @@ -0,0 +1,87 @@ +From f9872991239cc4ddcd9b3c706cf135cdbea28a48 Mon Sep 17 00:00:00 2001 +From: ningjin +Date: Tue, 21 May 2024 10:23:49 +0800 +Subject: [PATCH] change gazelle_stat_lstack_proto from u16 to u64 + +--- + src/common/gazelle_dfx_msg.h | 32 ++++++++++++++++---------------- + src/ltran/ltran_dfx.c | 20 ++++++++++---------- + 2 files changed, 26 insertions(+), 26 deletions(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 9f88203..cad7978 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -204,22 +204,22 @@ struct gazelle_stat_lstack_snmp { + /* same as define in lwip/stats.h - struct stats_proto */ + struct gazelle_stat_lstack_proto { + /* data */ +- uint16_t xmit; /* Transmitted packets. */ +- uint16_t recv; /* Received packets. */ +- uint16_t tx_in; /* Transmitted in packets. */ +- uint16_t tx_out; /* Transmitted out packets. */ +- uint16_t rx_in; /* Received in packets. */ +- uint16_t rx_out; /* Received out packets. */ +- uint16_t fw; /* Forwarded packets. */ +- uint16_t drop; /* Dropped packets. */ +- uint16_t chkerr; /* Checksum error. */ +- uint16_t lenerr; /* Invalid length error. */ +- uint16_t memerr; /* Out of memory error. */ +- uint16_t rterr; /* Routing error. */ +- uint16_t proterr; /* Protocol error. */ +- uint16_t opterr; /* Error in options. */ +- uint16_t err; /* Misc error. */ +- uint16_t cachehit; ++ uint64_t xmit; /* Transmitted packets. */ ++ uint64_t recv; /* Received packets. */ ++ uint64_t tx_in; /* Transmitted in packets. */ ++ uint64_t tx_out; /* Transmitted out packets. */ ++ uint64_t rx_in; /* Received in packets. */ ++ uint64_t rx_out; /* Received out packets. */ ++ uint64_t fw; /* Forwarded packets. */ ++ uint64_t drop; /* Dropped packets. */ ++ uint64_t chkerr; /* Checksum error. */ ++ uint64_t lenerr; /* Invalid length error. */ ++ uint64_t memerr; /* Out of memory error. */ ++ uint64_t rterr; /* Routing error. */ ++ uint64_t proterr; /* Protocol error. */ ++ uint64_t opterr; /* Error in options. */ ++ uint64_t err; /* Misc error. */ ++ uint64_t cachehit; + }; + + +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index aa08f25..319f7cd 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -1115,16 +1115,16 @@ static void gazelle_print_lstack_stat_proto_core(const struct gazelle_stack_dfx_ + const struct gazelle_stat_lstack_proto *proto) + { + printf("\n------ stack tid: %6u ------\n", stat->tid); +- printf("tx_in: %u\n", proto->tx_in); +- printf("tx_out: %u\n", proto->tx_out); +- printf("rx_in: %u\n", proto->rx_in); +- printf("rx_out: %u\n", proto->rx_out); +- printf("fw: %u\n", proto->fw); +- printf("drop: %u\n", proto->drop); +- printf("chkerr: %u\n", proto->chkerr); +- printf("lenerr: %u\n", proto->lenerr); +- printf("memerr: %u\n", proto->memerr); +- printf("rterr: %u\n", proto->rterr); ++ printf("tx_in: %lu\n", proto->tx_in); ++ printf("tx_out: %lu\n", proto->tx_out); ++ printf("rx_in: %lu\n", proto->rx_in); ++ printf("rx_out: %lu\n", proto->rx_out); ++ printf("fw: %lu\n", proto->fw); ++ printf("drop: %lu\n", proto->drop); ++ printf("chkerr: %lu\n", proto->chkerr); ++ printf("lenerr: %lu\n", proto->lenerr); ++ printf("memerr: %lu\n", proto->memerr); ++ printf("rterr: %lu\n", proto->rterr); + } + + static void gazelle_print_lstack_stat_snmp(void *buf, const struct gazelle_stat_msg_request *req_msg) +-- +2.33.0 + diff --git a/0181-memary-error-fix-some-memary-error.patch b/0181-memary-error-fix-some-memary-error.patch new file mode 100644 index 0000000..8c602ff --- /dev/null +++ b/0181-memary-error-fix-some-memary-error.patch @@ -0,0 +1,45 @@ +From 7b859a1e3dbb8ed719035942040a581982d71508 Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Sat, 18 May 2024 17:27:35 +0800 +Subject: [PATCH] memary error: fix some memary error + +--- + src/lstack/core/lstack_protocol_stack.c | 3 ++- + src/lstack/netif/lstack_flow.c | 4 ++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 892c16d..c5a265e 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -626,10 +626,11 @@ int32_t stack_setup_app_thread(void) + + if (stack_thread_init(t_params) == NULL) { + LSTACK_LOG(INFO, LSTACK, "stack setup failed in app thread\n"); ++ free(t_params); + return -1; + } + atomic_fetch_add(&g_stack_group.stack_num, 1); +- ++ free(t_params); + return 0; + } + +diff --git a/src/lstack/netif/lstack_flow.c b/src/lstack/netif/lstack_flow.c +index 4e04209..9e8792c 100644 +--- a/src/lstack/netif/lstack_flow.c ++++ b/src/lstack/netif/lstack_flow.c +@@ -84,6 +84,10 @@ static void add_rule(char* rule_key, struct rte_flow *flow) + HASH_FIND_STR(g_flow_rules, rule_key, rule); + if (rule == NULL) { + rule = (struct flow_rule*)malloc(sizeof(struct flow_rule)); ++ if (rule == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "flow rule add failed. \n"); ++ return; ++ } + strcpy_s(rule->rule_key, RULE_KEY_LEN, rule_key); + HASH_ADD_STR(g_flow_rules, rule_key, rule); + } +-- +2.33.0 + diff --git a/gazelle.spec b/gazelle.spec index 1e4a606..b37075a 100644 --- a/gazelle.spec +++ b/gazelle.spec @@ -2,7 +2,7 @@ Name: gazelle Version: 1.0.2 -Release: 18 +Release: 38 Summary: gazelle is a high performance user-mode stack License: MulanPSL-2.0 URL: https://gitee.com/openeuler/gazelle @@ -12,6 +12,9 @@ BuildRequires: cmake gcc-c++ BuildRequires: lwip >= 2.1.3-78 BuildRequires: dpdk-devel >= 19.11-23 BuildRequires: numactl-devel libpcap-devel libconfig-devel libboundscheck uthash-devel +%ifarch ppc64le +BuildRequires: libarchive libarchive-devel +%endif Requires: dpdk >= 19.11-23 Requires: numactl libpcap libconfig libboundscheck @@ -91,14 +94,115 @@ Patch9074: 0074-The-call-stack-is-not-printed-in-the-proactive-exit-.patch Patch9075: 0075-dfx-fix-gazellectl-lstack-show-ip-failed.patch Patch9076: 0076-gazellectl-add-connect-para.patch Patch9077: 0077-log-optimize-lstack-log.patch - +Patch9078: 0078-support-show-nic-offload-and-features.patch Patch9079: 0079-Fixed-an-issue-where-no-packet-is-sent-or-received-w.patch Patch9080: 0080-fix-example-print-error.patch +Patch9081: 0081-dfx-fix-kernel_events-stat.patch +Patch9082: 0082-add-keep-alive-info.patch +Patch9083: 0083-fix-close-can-t-exit.patch +Patch9084: 0084-mod-unix-time-stamp-to-local-time.patch +Patch9085: 0085-optimize-gazelle-exit-process.patch +Patch9086: 0086-fix-EPOLLIN-event-error.patch +Patch9087: 0087-mod-time-err.patch +Patch9088: 0088-fix-gazellectl-lstack-show-ip-r-with-ltran-error-log.patch +Patch9089: 0089-fix-udp-multicast-bind-error.patch +Patch9090: 0090-support-netperf.patch +Patch9091: 0091-fix-alloc-not-free.patch +Patch9092: 0092-sigaction-fix-deprecated-signal-flags.patch +Patch9093: 0093-fix-gazellectl-c-msg-error.patch +Patch9094: 0094-CFG-fix-check-func-strdup-return-value-is-NULL.patch +Patch9095: 0095-fix-func-separate_str_to_array-overflow-problem.patch +Patch9096: 0096-use-default-nonblock-mode.patch +Patch9097: 0097-fix-rte_ring_create-free-time-consuming.patch +Patch9098: 0098-optimize-shutdown-exit-process.patch +Patch9099: 0099-fix-func-separate_str_to_array-overflow-problem.patch +Patch9100: 0100-fix-func-separate_str_to_array-overflow-problem.patch +Patch9101: 0101-fix-func-separate_str_to_array-overflow-problem.patch +Patch9102: 0102-fix-func-separate_str_to_array-overflow-problem.patch +Patch9103: 0103-fix-func-stack_setup_thread-array-doesn-t-init.patch +Patch9104: 0104-fix-stack_setup_thread-array-range.patch +Patch9105: 0105-fix-func-separate_str_to_array-overflow-problem.patch +Patch9106: 0106-fix-dpdk_alloc_pktmbuf-time-consuming.patch +Patch9107: 0107-ltran-optimize-config-file-error-message.patch +Patch9108: 0108-replace-with-gz_addr_t.patch +Patch9109: 0109-match_host_addr-func-support-ipv6.patch +Patch9110: 0110-add-example-keep-alive-interval-para.patch +Patch9111: 0111-update-src-common-dpdk_common.c.patch +Patch9112: 0112-listen_shadow-support-ipv6.patch +Patch9113: 0113-lstack_dpdk-limit-mbuf-max-num.patch +Patch9114: 0114-gazellectl-add-tcp_input-empty-ack-cnt.patch +Patch9115: 0115-add-socket-accept-fail-cnt.patch +Patch9116: 0116-diff-lstack-and-ltran-dfx-sock.patch +Patch9117: 0117-fix-host_addr6-can-be-assigned-a-multicast-address.patch +Patch9118: 0118-udp-do-not-merge-data-into-last-pbuf.patch +Patch9119: 0119-adpat-dpdk-23.11.patch +Patch9120: 0120-modify-conf-vlan-default-vlaue.patch +Patch9121: 0121-remove-unused-variables-in-pbuf-and-reduce-mbuf-size.patch +Patch9122: 0122-optimize-recv-exit-process-for-FIN-and-unsupport-SO_.patch +Patch9123: 0123-remove-expand_send_ring.patch +Patch9124: 0124-set-ltran.patch +Patch9125: 0125-add-bond-doc.patch +Patch9126: 0126-cfg-host_addr-is-not-mandatory.patch +Patch9127: 0127-add-bond1-support.patch +Patch9128: 0128-fix-t_params-double-free.patch +Patch9129: 0129-fix-receive-fin-packet-process-error.patch +Patch9130: 0130-support-netperf-UDP_STREAM-and-UDP_RR.patch +Patch9131: 0131-adapt-lwip-2.2.0.patch +Patch9132: 0132-add-observable-method-of-data-aggregation.patch +Patch9133: 0133-try-to-ensure-arp-packet-can-be-sent.patch +Patch9134: 0134-gazellectl-support-send-latency-show.patch +Patch9135: 0135-rpc-function-does-not-depend-on-protocol-stack.patch +Patch9136: 0136-readv-return-1-errno-is-EAGAIN-when-recvring-no-data.patch +Patch9137: 0137-split-the-flow-fules-related-functions-into-separate.patch +Patch9138: 0138-fix-coreddump-when-stack-setup-failed-in-rtc-mode.patch +Patch9139: 0139-diff-udp-and-tcp-read-from-stack.patch +Patch9140: 0140-FAULT-INJECT-gazelle-add-packet-delay-and-packet-dro.patch +Patch9141: 0141-recv-support-MSG_DONTWAIT.patch +Patch9142: 0142-do_setsockopt-function-no-longer-checks-the-results-.patch +Patch9143: 0143-FAUT-INJECT-add-fault-inject-unset-method.patch +Patch9144: 0144-support-udp-pkglen-mtu.patch +Patch9145: 0145-add-limit-with-level-for-sockopt.patch +Patch9146: 0146-udp-add-restriction-message-too-long.patch +Patch9147: 0147-dfx-improve-log-readability-when-connect-ltran-lstac.patch +Patch9148: 0148-fix-rpc_pool-create-failed-coredump.patch +Patch9149: 0149-ensure-the-bond-interface-flow_type_rss_offloads-mat.patch +Patch9150: 0150-FAULT-INJECT-add-duplicate-and-reorder-methods.patch +Patch9151: 0151-select-timeout-arguments-check.patch +Patch9152: 0152-recvfrom-support-timeout.patch +Patch9153: 0153-fix-netperf-setsockopt-fail.patch +Patch9154: 0154-fix-LATENCY_WRITE-increase-in-recv-process.patch +Patch9155: 0155-dpdk-add-vlan-filter.patch +Patch9156: 0156-Correcting-spelling-errors.patch +Patch9157: 0157-perftool-add-lhist-statstic-tool.patch +Patch9158: 0158-add-udp-poll.patch +Patch9159: 0159-DFX-adapt-testcase-for-gazellectl-connect-failed.patch +Patch9160: 0160-warp-add-configuration-check-with-host_addr-and-serv.patch +Patch9161: 0161-add-latency-nodes-READ_APP_CALL-WRITE_RPC_MSG.patch +Patch9162: 0162-fix-vlan-filter-can-be-added-when-vlan_mode-1.patch +Patch9163: 0163-Add-support-for-arch-ppc64le.patch +Patch9164: 0164-dfx-support-get-nic-bond-status.patch +Patch9165: 0165-remove-dpdk_skip_nic_init-for-dpdk-23.11.patch +Patch9166: 0166-gazellectl-add-lwip-stats_proto-print.patch +Patch9167: 0167-fix-port-not-support-vlan-filter.patch +Patch9168: 0168-fix-tcp-recv-does-not-return-pkg-when-ring-buffer-is.patch +Patch9169: 0169-add-tuple_fileter-error-info.patch +Patch9170: 0170-adapt-dpdk-23.11-remove-kni.patch +Patch9171: 0171-fix-ioctl-set-failed.patch +Patch9172: 0172-ltran-memset-quintuple.patch +Patch9173: 0173-gazellectl-add-lwip-stats_proto-print.patch +Patch9174: 0174-CFG-set-multicast-IP-assert.patch +Patch9175: 0175-cfg-devices-must-be-in-bond_slave_mac-for-BONDING_MO.patch +Patch9176: 0176-CFG-fix-multicast-IP-assert-error.patch +Patch9177: 0177-fix-mbuf-leak-in-dpdk-23.11-due-to-kni-removed.patch +Patch9178: 0178-add-riscv64-support.patch +Patch9179: 0179-dfx-fix-gazellectl-x-for-bond.patch +Patch9180: 0180-change-gazelle_stat_lstack_proto-from-u16-to-u64.patch +Patch9181: 0181-memary-error-fix-some-memary-error.patch %description %{name} is a high performance user-mode stack. -ExclusiveArch: x86_64 aarch64 +ExclusiveArch: x86_64 aarch64 ppc64le %prep %autosetup -n %{name}-%{version} -p1 @@ -135,6 +239,140 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b %config(noreplace) %{conf_path}/ltran.conf %changelog +* Fri May 24 2024 yinbin6 - 1.0.2-38 +- memary error: fix some memary error +- change gazelle_stat_lstack_proto from u16 to u64 + +* Thu May 16 2024 yinbin6 - 1.0.2-37 +- dfx: fix gazellectl -x for bond + +* Fri May 10 2024 yangchen555 - 1.0.2-36 +- add riscv64 support +- fix mbuf leak in dpdk-23.11 due to kni removed + +* Thu May 9 2024 yinbin6 - 1.0.2-35 +- CFG:fix multicast IP assert error +- cfg: devices must be in bond_slave_mac for BONDING_MODE_ACTIVE +- CFG:set multicast IP assert +- gazellectl add lwip stats_proto print +- ltran: memset quintuple + +* Sun Apr 28 2024 yinbin6 - 1.0.2-34 +- fix ioctl set failed + +* Fri Apr 19 2024 yangchen555 - 1.0.2-33 +- adapt dpdk-23.11 remove kni +- add tuple_fileter error info +- fix tcp recv does not return pkg when ring buffer is empty + +* Fri Apr 12 2024 yinbin6 - 1.0.2-32 +- fix port not support vlan filter +- gazellectl add lwip stats_proto print +- remove dpdk_skip_nic_init for dpdk-23.11 +- dfx: support get nic bond status + +* Sun Apr 7 2024 yinbin6 - 1.0.2-31 +- Add support for arch ppc64le + +* Sun Apr 7 2024 yinbin6 - 1.0.2-30 +- fix vlan filter can be added when vlan_mode=-1 +- add latency nodes: READ_APP_CALL & WRITE_RPC_MSG +- warp: add configuration check with host_addr and server_ip for ipv6 +- DFX: adapt testcase for gazellectl connect failed +- add udp poll +- perftool: add lhist statstic tool +- Correcting spelling errors +- dpdk add vlan filter +- fix LATENCY_WRITE increase in recv process +- fix netperf setsockopt fail +- recvfrom support timeout +- select timeout arguments check +- FAULT INJECT: add duplicate and reorder methods +- ensure the bond interface flow_type_rss_offloads match slave + +* Thu Mar 14 2024 yinbin6 - 1.0.2-29 +- fix rpc_pool create failed coredump +- dfx: improve log readability when connect ltran/lstack failed +- udp add restriction: message too long +- add limit with level for sockopt +- support udp pkglen > mtu +- FAUT INJECT: add fault inject unset method +- do_setsockopt function no longer checks the results of the kernel. +- recv support MSG_DONTWAIT + +* Thu Mar 14 2024 yinbin6 - 1.0.2-28 +- FAULT INJECT: gazelle add packet delay and packet drop +- diff udp and tcp read from stack +- fix coreddump when stack setup failed in rtc mode +- split the flow fules related functions into separate file +- readv return -1, errno is EAGAIN when recvring no data +- rpc function does not depend on protocol stack diff rpc queue and dfx rpc queue +- gazellectl: support send latency show +- try to ensure arp packet can be sent +- add observable method of data aggregation + +* Wed Feb 07 2024 yibin6 - 1.0.2-27 +- support netperf UDP_STREAM and UDP_RR + +* Sun Feb 4 2024 yinbin6 - 1.0.2-26 +- support netperf UDP_STREAM and UDP_RR +- fix receive fin packet process error +- fix t_params double free +- add bond1 support +- cfg: host_addr is not mandatory +- add bond doc +- set ltran +- remove expand_send_ring +- optimize recv exit process for FIN and unsupport SO_RCVBUF +- remove unused variables in pbuf and reduce mbuf size +- modify conf vlan default vlaue + +* Sat Jan 20 2024 yinbin6 - 1.0.2-25 +- adpat dpdk 23.11 +- udp: do not merge data into last pbuf +- fix host_addr6 can be assigned a multicast address +- diff lstack and ltran dfx sock +- add socket accept fail cnt +- gazellectl: add tcp_input empty ack cnt +- lstack_dpdk: limit mbuf max num +- listen_shadow support ipv6 + +* Sat Jan 06 2024 yinbin6 - 1.0.2-24 +- replace with gz_addr_t +- update src/common/dpdk_common.c +- match_host_addr func support ipv6 +- add example keep-alive interval para + +* Sat Jan 06 2024 yinbin6 - 1.0.2-23 +- fix dpdk_alloc_pktmbuf time-consuming +- ltran: optimize config file error message + +* Wed Dec 27 2023 yinbin6 - 1.0.2-22 +- fix rte_ring_create/free time consuming +- use default nonblock mode +- fix func separate_str_to_array overflow problem +- CFG:fix check func strdup return value is NULL +- fix gazellectl -c msg error +- sigaction: fix deprecated signal flags +- fix alloc not free +- optimize shutdown exit process + +* Tue Dec 19 2023 yinbin6 - 1.0.2-21 +- support netperf +- fix udp multicast bind error + +* Mon Dec 18 2023 yinbin6 - 1.0.2-20 +- fix gazellectl lstack show ip -r with ltran error && log info display unknow error +- mod time err + +* Sat Dec 16 2023 yinbin6 - 1.0.2-19 +- fix EPOLLIN event error +- optimize gazelle exit process 1. close all fds 2. lstack thread exits, then gazelle process exits +- mod unix time stamp to local time +- fix close can't exit +- add keep-alive info +- dfx: fix kernel_events stat + * Sat Dec 9 2023 yinbin6 - 1.0.2-18 - Fixed an issue where no packet is sent or received when UDP traffic is sent - support show nic offload and features @@ -218,12 +456,11 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b * Mon Oct 30 2023 yangchenCloud - 1.0.2-8 - cfg: add run-to-completion mode configure - preload: support thread hijacking mode + +* Mon Oct 30 2023 hantwofish - 1.0.2-7 - epoll: distinguish add/del_sock_event and add/del_sock_event_nolock - cfg: nic rx/tx queue size configure -* Fri Nov 3 2023 liyanan - 1.0.2-7 -- Adapt dpdk fallback - * Sat Oct 14 2023 yinbin6 - 1.0.2-6 - update lwip version buildrequire