From de8c44ff8ed7371889515744fac153de484620d5 Mon Sep 17 00:00:00 2001 From: wuchangsheng Date: Thu, 6 Oct 2022 19:55:26 +0800 Subject: [PATCH] refactor tcp new port --- 0029-refactor-tcp-new-port.patch | 204 +++++++++++++++++++++++++++++++ lwip.spec | 10 +- 2 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 0029-refactor-tcp-new-port.patch diff --git a/0029-refactor-tcp-new-port.patch b/0029-refactor-tcp-new-port.patch new file mode 100644 index 0000000..343d680 --- /dev/null +++ b/0029-refactor-tcp-new-port.patch @@ -0,0 +1,204 @@ +From b18cb7d02c10d15873578d61665507f2e341ebe3 Mon Sep 17 00:00:00 2001 +From: wuchangsheng +Date: Thu, 6 Oct 2022 19:52:43 +0800 +Subject: [PATCH] refactor tcp new port + +--- + src/core/tcp.c | 87 +++++++++++++++++++++++++++++------------- + src/include/reg_sock.h | 3 ++ + 2 files changed, 63 insertions(+), 27 deletions(-) + +diff --git a/src/core/tcp.c b/src/core/tcp.c +index 04a7c07..c584585 100644 +--- a/src/core/tcp.c ++++ b/src/core/tcp.c +@@ -202,13 +202,26 @@ PER_THREAD u8_t tcp_active_pcbs_changed; + /** Timer counter to handle calling slow-timer from tcp_tmr() */ + static PER_THREAD u8_t tcp_timer; + static PER_THREAD u8_t tcp_timer_ctr; ++#if USE_LIBOS ++static u16_t tcp_new_port(struct tcp_pcb *pcb); ++#else + static u16_t tcp_new_port(void); ++#endif + + static err_t tcp_close_shutdown_fin(struct tcp_pcb *pcb); + #if LWIP_TCP_PCB_NUM_EXT_ARGS + static void tcp_ext_arg_invoke_callbacks_destroyed(struct tcp_pcb_ext_args *ext_args); + #endif + ++#if USE_LIBOS ++static u8_t port_state[TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START + 1] = {0}; ++void release_port(u16_t port) ++{ ++ if (port >= TCP_LOCAL_PORT_RANGE_START && port <= TCP_LOCAL_PORT_RANGE_END) { ++ port_state[port - TCP_LOCAL_PORT_RANGE_START] = 0; ++ } ++} ++#endif + /** + * Initialize this module. + */ +@@ -237,6 +250,7 @@ tcp_free(struct tcp_pcb *pcb) + { + #if USE_LIBOS + vdev_unreg_done(pcb); ++ release_port(pcb->local_port); + #endif + LWIP_ASSERT("tcp_free: LISTEN", pcb->state != LISTEN); + #if LWIP_TCP_PCB_NUM_EXT_ARGS +@@ -745,7 +759,11 @@ tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) + #endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ + + if (port == 0) { ++#if USE_LIBOS ++ port = tcp_new_port(pcb); ++#else + port = tcp_new_port(); ++#endif + if (port == 0) { + return ERR_BUF; + } +@@ -1056,33 +1074,43 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) + * + * @return a new (free) local TCP port number + */ ++#if USE_LIBOS ++static u16_t ++tcp_new_port(struct tcp_pcb *pcb) ++#else + static u16_t + tcp_new_port(void) ++#endif + { +- u8_t i; + u16_t n = 0; +- u16_t tmp_port; +- struct tcp_pcb *pcb; ++ u16_t tmp_port = 0; + + pthread_mutex_lock(&g_tcp_port_mutex); +-again: +- tcp_port++; +- if (tcp_port == TCP_LOCAL_PORT_RANGE_END) { +- tcp_port = TCP_LOCAL_PORT_RANGE_START; +- } +- /* Check all PCB lists. */ +- for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { +- for (pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { +- if (pcb->local_port == tcp_port) { +- n++; +- if (n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { +- return 0; ++ do { ++ tcp_port++; ++ if (tcp_port == TCP_LOCAL_PORT_RANGE_END) { ++ tcp_port = TCP_LOCAL_PORT_RANGE_START; ++ } ++ ++ if (__atomic_load_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) { ++#if USE_LIBOS ++ if (port_in_stack_queue(pcb->remote_ip.addr, pcb->local_ip.addr, pcb->remote_port, tcp_port)) { ++ tmp_port = tcp_port; ++ __atomic_store_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE); ++ break; + } +- goto again; ++#else ++ __atomic_store_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE); ++ break; ++#endif + } +- } +- } +- tmp_port = tcp_port; ++ ++ n++; ++ if (n > TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START) { ++ break; ++ } ++ } while (tmp_port == 0); ++ + pthread_mutex_unlock(&g_tcp_port_mutex); + + return tmp_port; +@@ -1168,7 +1196,11 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, + + old_local_port = pcb->local_port; + if (pcb->local_port == 0) { ++#if USE_LIBOS ++ pcb->local_port = tcp_new_port(pcb); ++#else + pcb->local_port = tcp_new_port(); ++#endif + if (pcb->local_port == 0) { + return ERR_BUF; + } +@@ -1195,10 +1227,6 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, + #endif /* SO_REUSE */ + } + +-#if USE_LIBOS +- vdev_reg_done(REG_RING_TCP_CONNECT, pcb); +-#endif +- + iss = tcp_next_iss(pcb); + pcb->rcv_nxt = 0; + pcb->snd_nxt = iss; +@@ -1226,6 +1254,10 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, + /* Send a SYN together with the MSS option. */ + ret = tcp_enqueue_flags(pcb, TCP_SYN); + if (ret == ERR_OK) { ++#if USE_LIBOS ++ vdev_reg_done(REG_RING_TCP_CONNECT, pcb); ++#endif ++ + /* SYN segment was enqueued, changed the pcbs state now */ + pcb->state = SYN_SENT; + if (old_local_port != 0) { +@@ -2273,10 +2305,6 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) + LWIP_ASSERT("tcp_pcb_remove: invalid pcb", pcb != NULL); + LWIP_ASSERT("tcp_pcb_remove: invalid pcblist", pcblist != NULL); + +-#if USE_LIBOS +- vdev_unreg_done(pcb); +-#endif +- + TCP_RMV(pcblist, pcb); + + tcp_pcb_purge(pcb); +@@ -2297,6 +2325,11 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) + #endif /* TCP_QUEUE_OOSEQ */ + } + ++#if USE_LIBOS ++ vdev_unreg_done(pcb); ++ release_port(pcb->local_port); ++#endif ++ + pcb->state = CLOSED; + /* reset the local port to prevent the pcb from being 'bound' */ + pcb->local_port = 0; +diff --git a/src/include/reg_sock.h b/src/include/reg_sock.h +index 76673da..5d5710d 100644 +--- a/src/include/reg_sock.h ++++ b/src/include/reg_sock.h +@@ -33,6 +33,8 @@ + #ifndef __REG_SOCK_H__ + #define __REG_SOCK_H__ + ++#include ++ + enum reg_ring_type { + REG_RING_TCP_LISTEN = 0, + REG_RING_TCP_LISTEN_CLOSE, +@@ -58,5 +60,6 @@ struct reg_ring_msg { + }; + + extern int vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple); ++extern bool port_in_stack_queue(uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); + + #endif /* __REG_SOCK_H__ */ +-- +2.27.0 + diff --git a/lwip.spec b/lwip.spec index 4e90473..76e1abb 100644 --- a/lwip.spec +++ b/lwip.spec @@ -4,7 +4,7 @@ Summary: lwip is a small independent implementation of the TCP/IP protocol suite Name: lwip Version: 2.1.2 -Release: 8 +Release: 9 License: BSD URL: http://savannah.nongnu.org/projects/lwip/ Source0: http://download.savannah.nongnu.org/releases/lwip/%{name}-%{version}.zip @@ -42,6 +42,7 @@ Patch9025: 0025-del-redundant-wait_close-and-move-epoll_events-pos.patch Patch9026: 0026-modify-EISCONN-condition.patch Patch9027: 0027-per-thread-reassdata-variables.patch Patch9028: 0028-fix-EISCONN-err-and-remove-same-customized-modificat.patch +Patch9029: 0029-refactor-tcp-new-port.patch BuildRequires: gcc-c++ dos2unix dpdk-devel @@ -88,6 +89,7 @@ find %{_builddir}/%{name}-%{version} -type f -exec dos2unix -q {} \; %patch9026 -p1 %patch9027 -p1 %patch9028 -p1 +%patch9029 -p1 %build cd %{_builddir}/%{name}-%{version}/src @@ -103,7 +105,11 @@ cd %{_builddir}/%{name}-%{version}/src %{_libdir}/liblwip.a %changelog -* Thu Oct 6 2022 wuchangsheng - 2.1.2-7 +* Thu Oct 6 2022 wuchangsheng - 2.1.2-9 +- fix multithread duplicate port num + support select appropriate port num to rss same as nic + +* Thu Oct 6 2022 wuchangsheng - 2.1.2-8 - fix EISCONN conditon err remove same customized modification -- Gitee