From 2bbeb8f3bebd721873658991d9b7ef49361f69af Mon Sep 17 00:00:00 2001 From: Lemmy Huang Date: Fri, 19 Jul 2024 09:45:12 +0800 Subject: [PATCH] cleancode: move tcp_hash_table to lwipgz_tcp_priv.h Signed-off-by: Lemmy Huang (cherry picked from commit e5281e35a4dc5fa93a4265e73b8c88d35d5367ef) --- ...-tcp_hash_table-to-lwipgz_tcp_priv.h.patch | 899 ++++++++++++++++++ lwip.spec | 6 +- 2 files changed, 904 insertions(+), 1 deletion(-) create mode 100644 0154-cleancode-move-tcp_hash_table-to-lwipgz_tcp_priv.h.patch diff --git a/0154-cleancode-move-tcp_hash_table-to-lwipgz_tcp_priv.h.patch b/0154-cleancode-move-tcp_hash_table-to-lwipgz_tcp_priv.h.patch new file mode 100644 index 0000000..089855f --- /dev/null +++ b/0154-cleancode-move-tcp_hash_table-to-lwipgz_tcp_priv.h.patch @@ -0,0 +1,899 @@ +From cc2babc37cf2ae592802271c867282cf82bd991f Mon Sep 17 00:00:00 2001 +From: Lemmy Huang +Date: Thu, 11 Jul 2024 19:23:38 +0800 +Subject: [PATCH] cleancode: move tcp_hash_table to lwipgz_tcp_priv.h + +Signed-off-by: Lemmy Huang +--- + src/core/tcp.c | 79 ++++-------- + src/core/tcp_in.c | 31 +---- + src/include/lwip/priv/tcp_priv.h | 175 +------------------------ + src/include/lwip/tcp.h | 104 ++------------- + src/include/lwipgz_tcp_priv.h | 212 +++++++++++++++++++++++++++++++ + src/include/lwipopts.h | 7 +- + 6 files changed, 266 insertions(+), 342 deletions(-) + create mode 100644 src/include/lwipgz_tcp_priv.h + +diff --git a/src/core/tcp.c b/src/core/tcp.c +index a340e1a..4c1304b 100644 +--- a/src/core/tcp.c ++++ b/src/core/tcp.c +@@ -161,7 +161,6 @@ static const char *const tcp_state_str[] = { + + /* last local TCP port */ + static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; +-static pthread_mutex_t g_tcp_port_mutex = PTHREAD_MUTEX_INITIALIZER; + + /* Incremented every coarse grained timer shot (typically every 500 ms). */ + PER_THREAD u32_t tcp_ticks; +@@ -185,21 +184,6 @@ PER_THREAD struct tcp_pcb *tcp_tw_pcbs; + /** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ + PER_THREAD struct tcp_pcb ** tcp_pcb_lists[NUM_TCP_PCB_LISTS] = {NULL, NULL, NULL, NULL}; + +-#if GAZELLE_TCP_PCB_HASH +-#define INIT_TCP_HTABLE(ht_ptr) \ +- do { \ +- int _i; \ +- (ht_ptr)->size = TCP_HTABLE_SIZE; \ +- for (_i = 0; _i < TCP_HTABLE_SIZE; ++_i) { \ +- if (sys_mutex_new(&(ht_ptr)->array[_i].mutex) != ERR_OK) \ +- LWIP_ASSERT("failed to create ht->array[].mutex", 0);\ +- hlist_init_head(&(ht_ptr)->array[_i].chain); \ +- }\ +- } while (0) +- +-PER_THREAD struct tcp_hash_table *tcp_active_htable; /* key: lport/fport/lip/fip */ +-#endif +- + PER_THREAD u8_t tcp_active_pcbs_changed; + + /** Timer counter to handle calling slow-timer from tcp_tmr() */ +@@ -207,16 +191,7 @@ static PER_THREAD u8_t tcp_timer; + static PER_THREAD u8_t tcp_timer_ctr; + #if GAZELLE_ENABLE + 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 GAZELLE_ENABLE ++static pthread_mutex_t g_tcp_port_mutex = PTHREAD_MUTEX_INITIALIZER; + static u8_t port_state[TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START + 1] = {0}; + void release_port(u16_t port) + { +@@ -224,7 +199,19 @@ void release_port(u16_t port) + port_state[port - TCP_LOCAL_PORT_RANGE_START] = 0; + } + } ++#else /* GAZELLE_ENABLE */ ++static u16_t tcp_new_port(void); ++#endif /* GAZELLE_ENABLE */ ++ ++#if GAZELLE_TCP_PCB_HASH ++PER_THREAD struct tcp_hash_table *tcp_active_htable; /* key: lport/fport/lip/fip */ ++#endif /* GAZELLE_TCP_PCB_HASH */ ++ ++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 ++ + /** + * Initialize this module. + */ +@@ -236,15 +223,18 @@ tcp_init(void) + tcp_pcb_lists[2] = &tcp_active_pcbs; + tcp_pcb_lists[3] = &tcp_tw_pcbs; + +-#ifdef LWIP_RAND +- tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +-#endif /* LWIP_RAND */ +- + #if GAZELLE_TCP_PCB_HASH + tcp_active_htable = (struct tcp_hash_table*)mem_malloc(sizeof(struct tcp_hash_table)); + LWIP_ASSERT("malloc tcp_active_htable mem failed.", tcp_active_htable != NULL); +- INIT_TCP_HTABLE(tcp_active_htable); +-#endif ++ tcp_active_htable->size = GAZELLE_TCP_ACTIVE_HTABLE_SIZE; ++ for (int i = 0; i < tcp_active_htable->size; ++i) { ++ hlist_init_head(&tcp_active_htable->array[i].chain); ++ } ++#endif /* GAZELLE_TCP_PCB_HASH */ ++ ++#ifdef LWIP_RAND ++ tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); ++#endif /* LWIP_RAND */ + } + + /** Free a tcp pcb */ +@@ -422,9 +412,6 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) + pcb->local_port, pcb->remote_port); + + tcp_pcb_purge(pcb); +-#if GAZELLE_TCP_PCB_HASH +- TCP_RMV_ACTIVE_HASH(pcb); +-#endif + TCP_RMV_ACTIVE(pcb); + /* Deallocate the pcb since we already sent a RST for it */ + if (tcp_input_pcb == pcb) { +@@ -459,9 +446,6 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) + tcp_free_listen(pcb); + break; + case SYN_SENT: +-#if GAZELLE_TCP_PCB_HASH +- TCP_PCB_REMOVE_ACTIVE_HASH(pcb); +-#endif + TCP_PCB_REMOVE_ACTIVE(pcb); + tcp_free(pcb); + MIB2_STATS_INC(mib2.tcpattemptfails); +@@ -666,9 +650,6 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) + } else { + send_rst = reset; + local_port = pcb->local_port; +-#if GAZELLE_TCP_PCB_HASH +- TCP_PCB_REMOVE_ACTIVE_HASH(pcb); +-#endif + TCP_PCB_REMOVE_ACTIVE(pcb); + } + if (pcb->unacked != NULL) { +@@ -1339,9 +1320,6 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, + if (old_local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } +-#if GAZELLE_TCP_PCB_HASH +- TCP_REG_ACTIVE_HASH(pcb); +-#endif + TCP_REG_ACTIVE(pcb); + MIB2_STATS_INC(mib2.tcpactiveopens); + +@@ -2407,6 +2385,11 @@ 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 GAZELLE_TCP_PCB_HASH ++ if (pcblist == &tcp_active_pcbs) { ++ TCP_RMV_HASH(pcb); ++ } ++#endif /* GAZELLE_TCP_PCB_HASH */ + TCP_RMV(pcblist, pcb); + + tcp_pcb_purge(pcb); +@@ -2439,14 +2422,6 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) + LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); + } + +-#if GAZELLE_TCP_PCB_HASH +-void +-tcp_pcb_remove_hash(struct tcp_hash_table *htb, struct tcp_pcb *pcb) +-{ +- TCP_RMV_HASH(htb, pcb); +-} +-#endif /* GAZELLE_TCP_PCB_HASH */ +- + /** + * Calculates a new initial sequence number for new connections. + * +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index 66c0cdb..7288d2f 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -165,13 +165,6 @@ tcp_input(struct pbuf *p, struct netif *inp) + u8_t hdrlen_bytes; + err_t err; + +-#if GAZELLE_TCP_PCB_HASH +- u32_t idx; +- struct hlist_head *head; +- struct hlist_node *node; +- pcb = NULL; +-#endif +- + LWIP_UNUSED_ARG(inp); + LWIP_ASSERT_CORE_LOCKED(); + LWIP_ASSERT("tcp_input: invalid pbuf", p != NULL); +@@ -312,7 +305,11 @@ tcp_input(struct pbuf *p, struct netif *inp) + prev = NULL; + + #if GAZELLE_TCP_PCB_HASH +- idx = TUPLE4_HASH_FN( ip_current_dest_addr(), tcphdr->dest, ++ pcb = NULL; ++ u32_t idx; ++ struct hlist_head *head; ++ struct hlist_node *node; ++ idx = tcp_pcb_hash( ip_current_dest_addr(), tcphdr->dest, + ip_current_src_addr(), tcphdr->src) & + (tcp_active_htable->size - 1); + head = &tcp_active_htable->array[idx].chain; +@@ -549,9 +546,6 @@ tcp_input(struct pbuf *p, struct netif *inp) + application that the connection is dead before we + deallocate the PCB. */ + TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST); +-#if GAZELLE_TCP_PCB_HASH +- tcp_pcb_remove_hash(tcp_active_htable, pcb); +-#endif + tcp_pcb_remove(&tcp_active_pcbs, pcb); + tcp_free(pcb); + } else { +@@ -722,9 +716,6 @@ tcp_input_delayed_close(struct tcp_pcb *pcb) + ensure the application doesn't continue using the PCB. */ + TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD); + } +-#if GAZELLE_TCP_PCB_HASH +- tcp_pcb_remove_hash(tcp_active_htable, pcb); +-#endif + tcp_pcb_remove(&tcp_active_pcbs, pcb); + tcp_free(pcb); + return 1; +@@ -818,9 +809,6 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) + npcb->netif_idx = pcb->netif_idx; + /* Register the new PCB so that we can begin receiving segments + for it. */ +-#if GAZELLE_TCP_PCB_HASH +- TCP_REG_ACTIVE_HASH(npcb); +-#endif + TCP_REG_ACTIVE(npcb); + + #if GAZELLE_ENABLE +@@ -1155,9 +1143,6 @@ tcp_process(struct tcp_pcb *pcb) + ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); +-#if GAZELLE_TCP_PCB_HASH +- TCP_RMV_ACTIVE_HASH(pcb); +-#endif + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); +@@ -1176,9 +1161,6 @@ tcp_process(struct tcp_pcb *pcb) + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); +-#if GAZELLE_TCP_PCB_HASH +- TCP_RMV_ACTIVE_HASH(pcb); +-#endif + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); +@@ -1189,9 +1171,6 @@ tcp_process(struct tcp_pcb *pcb) + if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_pcb_purge(pcb); +-#if GAZELLE_TCP_PCB_HASH +- TCP_RMV_ACTIVE_HASH(pcb); +-#endif + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); +diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h +index 3ed8200..02df1d0 100644 +--- a/src/include/lwip/priv/tcp_priv.h ++++ b/src/include/lwip/priv/tcp_priv.h +@@ -340,44 +340,6 @@ extern PER_THREAD struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in T + #define NUM_TCP_PCB_LISTS 4 + extern PER_THREAD struct tcp_pcb ** tcp_pcb_lists[NUM_TCP_PCB_LISTS]; + +-#if GAZELLE_ENABLE +-#include "lwipgz_flow.h" +-static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pcb *pcb) +-{ +- LWIP_ASSERT("Invalid parameter", pcb != NULL); +- +- struct gazelle_quintuple qtuple = {0}; +- +- qtuple.protocol = IP_IS_V4_VAL(pcb->local_ip) ? GZ_ADDR_TYPE_V4 : GZ_ADDR_TYPE_V6; +- qtuple.src_ip = *((gz_addr_t *)&pcb->local_ip); +- qtuple.src_port = lwip_htons(pcb->local_port); +- qtuple.dst_ip = *((gz_addr_t *)&pcb->remote_ip); +- qtuple.dst_port = lwip_htons(pcb->remote_port); +- +-#if GAZELLE_TCP_REUSE_IPPORT +- if (reg_type == REG_RING_TCP_CONNECT_CLOSE) { +- struct tcp_pcb_listen* lpcb = pcb->listener; +- if (lpcb != NULL) { +- lpcb->connect_num--; +- } +- } +-#endif +- +- return vdev_reg_xmit(reg_type, &qtuple); +-} +-static inline void vdev_unreg_done(const struct tcp_pcb *pcb) +-{ +- if (pcb->local_port == 0) { +- return; +- } +- if (pcb->state == LISTEN) { +- vdev_reg_done(REG_RING_TCP_LISTEN_CLOSE, pcb); +- } else { +- vdev_reg_done(REG_RING_TCP_CONNECT_CLOSE, pcb); +- } +-} +-#endif +- + /* Axioms about the above lists: + 1) Every TCP PCB that is not CLOSED is in one of the lists. + 2) A PCB is only in one of the lists. +@@ -389,51 +351,12 @@ static inline void vdev_unreg_done(const struct tcp_pcb *pcb) + #ifndef TCP_DEBUG_PCB_LISTS + #define TCP_DEBUG_PCB_LISTS 0 + #endif +-#if TCP_DEBUG_PCB_LISTS +-#if GAZELLE_ENABLE +-#define TCP_REG(pcbs, npcb) do {\ +- struct tcp_pcb *tcp_tmp_pcb; \ +- LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ +- for (tcp_tmp_pcb = *(pcbs); \ +- tcp_tmp_pcb != NULL; \ +- tcp_tmp_pcb = tcp_tmp_pcb->next) { \ +- LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ +- } \ +- LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ +- if (*pcbs) \ +- (*pcbs)->prev = npcb; \ +- (npcb)->prev = NULL; \ +- (npcb)->next = *(pcbs); \ +- LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ +- *(pcbs) = (npcb); \ +- LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ +- tcp_timer_needed(); \ +- } while(0) +-#define TCP_RMV(pcbs, npcb) do { \ +- struct tcp_pcb *tcp_tmp_pcb; \ +- LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ +- LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ +- if(*(pcbs) == (npcb)) { \ +- *(pcbs) = (*pcbs)->next; \ +- if (*pcbs) \ +- (*pcbs)->prev = NULL; \ +- } else { \ +- struct tcp_pcb *prev, *next; \ +- prev = npcb->prev; \ +- next = npcb->next; \ +- if (prev) \ +- prev->next = next; \ +- if (next) \ +- next->prev = prev; \ +- } \ +- } \ +- (npcb)->prev = NULL; \ +- (npcb)->next = NULL; \ +- LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ +- LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ +- } while(0) + +-#else /* GAZELLE_ENABLE */ ++#if GAZELLE_TCP_PCB_HASH ++#include "lwipgz_tcp_priv.h" ++#else /* GAZELLE_TCP_PCB_HASH */ ++ ++#if TCP_DEBUG_PCB_LISTS + #define TCP_REG(pcbs, npcb) do {\ + struct tcp_pcb *tcp_tmp_pcb; \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %"U16_F"\n", (void *)(npcb), (npcb)->local_port)); \ +@@ -466,71 +389,8 @@ static inline void vdev_unreg_done(const struct tcp_pcb *pcb) + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \ + } while(0) + +-#endif /* GAZELLE_ENABLE */ + #else /* LWIP_DEBUG */ + +-#if GAZELLE_TCP_PCB_HASH +-#define TCP_REG_HASH(pcbs, npcb) \ +- do { \ +- u32_t idx; \ +- struct hlist_head *hd; \ +- struct tcp_hash_table *htb = pcbs; \ +- idx = TUPLE4_HASH_FN(&((npcb)->local_ip), (npcb)->local_port, \ +- &((npcb)->remote_ip), (npcb)->remote_port) & \ +- (htb->size - 1); \ +- hd = &htb->array[idx].chain; \ +- hlist_add_head(&(npcb)->tcp_node, hd); \ +- tcp_timer_needed(); \ +- } while (0) +- +-#define TCP_REG_SAMEPORT(first_pcb, lpcb) \ +- do { \ +- struct tcp_pcb_listen *tmp_pcb = first_pcb; \ +- while (tmp_pcb->next_same_port_pcb != NULL) { \ +- tmp_pcb = tmp_pcb->next_same_port_pcb; \ +- }; \ +- tmp_pcb->next_same_port_pcb = lpcb; \ +- tcp_timer_needed(); \ +- } while (0) +- +-#define TCP_RMV_HASH(pcbs, npcb) \ +- do { \ +- hlist_del_node(&(npcb)->tcp_node); \ +- } while (0) +-#endif /* GAZELLE_TCP_PCB_HASH */ +- +-#if GAZELLE_ENABLE +-#define TCP_REG(pcbs, npcb) \ +- do { \ +- if (*pcbs) \ +- (*pcbs)->prev = npcb; \ +- (npcb)->prev = NULL; \ +- (npcb)->next = *pcbs; \ +- *(pcbs) = (npcb); \ +- tcp_timer_needed(); \ +- } while (0) +- +-#define TCP_RMV(pcbs, npcb) \ +- do { \ +- if(*(pcbs) == (npcb)) { \ +- (*(pcbs)) = (*pcbs)->next; \ +- if (*pcbs) \ +- (*pcbs)->prev = NULL; \ +- } \ +- else { \ +- struct tcp_pcb *prev, *next; \ +- prev = npcb->prev; \ +- next = npcb->next; \ +- if (prev) \ +- prev->next = next; \ +- if (next) \ +- next->prev = prev; \ +- } \ +- (npcb)->prev = NULL; \ +- (npcb)->next = NULL; \ +- } while(0) +- +-#else /* GAZELLE_ENABLE */ + #define TCP_REG(pcbs, npcb) \ + do { \ + (npcb)->next = *pcbs; \ +@@ -557,40 +417,19 @@ static inline void vdev_unreg_done(const struct tcp_pcb *pcb) + (npcb)->next = NULL; \ + } while(0) + +-#endif /* GAZELLE_ENABLE */ + #endif /* LWIP_DEBUG */ +- +- +-#if GAZELLE_TCP_PCB_HASH +-#define TCP_REG_ACTIVE_HASH(npcb) \ +- do { \ +- TCP_REG_HASH(tcp_active_htable, npcb); \ +- tcp_active_pcbs_changed = 1; \ +- } while (0) +- +-#define TCP_RMV_ACTIVE_HASH(npcb) \ +- do { \ +- TCP_RMV_HASH(tcp_active_htable, npcb); \ +- tcp_active_pcbs_changed = 1; \ +- } while (0) +- +-#define TCP_PCB_REMOVE_ACTIVE_HASH(pcb) \ +- do { \ +- tcp_pcb_remove_hash(tcp_active_htable, pcb); \ +- tcp_active_pcbs_changed = 1; \ +- } while (0) +- +-void tcp_pcb_remove_hash(struct tcp_hash_table *htb, struct tcp_pcb *pcb); + #endif /* GAZELLE_TCP_PCB_HASH */ + + #define TCP_REG_ACTIVE(npcb) \ + do { \ ++ TCP_REG_ACTIVE_HASH(npcb); \ + TCP_REG(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + + #define TCP_RMV_ACTIVE(npcb) \ + do { \ ++ TCP_RMV_ACTIVE_HASH(npcb); \ + TCP_RMV(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) +diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h +index bfcf605..44a9a5a 100644 +--- a/src/include/lwip/tcp.h ++++ b/src/include/lwip/tcp.h +@@ -51,11 +51,6 @@ + #include "lwip/ip6.h" + #include "lwip/ip6_addr.h" + +-#if GAZELLE_TCP_PCB_HASH +-#include "lwip/sys.h" +-#include "lwipgz_hlist.h" +-#endif +- + #ifdef __cplusplus + extern "C" { + #endif +@@ -214,27 +209,20 @@ typedef u16_t tcpflags_t; + /** + * members common to struct tcp_pcb and struct tcp_listen_pcb + */ +-#if GAZELLE_ENABLE +-#define TCP_PCB_COMMON(type) \ +- type *next; /* for the linked list */ \ +- type *prev; /* for the linked list */ \ +- void *callback_arg; \ +- TCP_PCB_EXTARGS \ +- enum tcp_state state; /* TCP state */ \ +- u8_t prio; \ +- /* ports are in host byte order */ \ +- u16_t local_port +- +-#else /* GAZELLE_ENABLE */ ++#if GAZELLE_TCP_PCB_HASH ++#include "lwipgz_hlist.h" ++#endif + #define TCP_PCB_COMMON(type) \ + type *next; /* for the linked list */ \ ++ type *prev; /* GAZELLE_ENABLE */ \ ++ struct hlist_node tcp_node; /* GAZELLE_TCP_PCB_HASH */ \ + void *callback_arg; \ + TCP_PCB_EXTARGS \ + enum tcp_state state; /* TCP state */ \ + u8_t prio; \ + /* ports are in host byte order */ \ + u16_t local_port +-#endif /* GAZELLE_ENABLE */ ++ + + /** the TCP protocol control block for listening pcbs */ + struct tcp_pcb_listen { +@@ -272,9 +260,6 @@ struct tcp_pcb { + IP_PCB; + /** protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb); +-#if GAZELLE_TCP_PCB_HASH +- struct hlist_node tcp_node; +-#endif + + /* ports are in host byte order */ + u16_t remote_port; +@@ -367,9 +352,7 @@ struct tcp_pcb { + + /* These are ordered by sequence number: */ + struct tcp_seg *unsent; /* Unsent (queued) segments. */ +- struct tcp_seg *last_unsent; + struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ +- struct tcp_seg *last_unacked; + #if TCP_QUEUE_OOSEQ + struct tcp_seg *ooseq; /* Received out of sequence segments. */ + #endif /* TCP_QUEUE_OOSEQ */ +@@ -421,83 +404,18 @@ struct tcp_pcb { + #endif + + #if GAZELLE_ENABLE ++ struct tcp_seg *last_unsent; ++ struct tcp_seg *last_unacked; ++ ++ u8_t need_tso_send; ++ + #define SAME_NODE_RING_SIZE 512 + struct rte_ring *client_rx_ring; + struct rte_ring *client_tx_ring; + u8_t free_ring; + #endif +- +- u8_t need_tso_send; + }; + +-#if GAZELLE_TCP_PCB_HASH +-#define TCP_HTABLE_SIZE MEMP_NUM_NETCONN*12 +- +-struct tcp_hashbucket +-{ +- sys_mutex_t mutex; +- struct hlist_head chain; +-}; +- +-struct tcp_hash_table +-{ +- u32_t size; +- struct tcp_hashbucket array[TCP_HTABLE_SIZE]; +-}; +- +-extern PER_THREAD struct tcp_hash_table *tcp_active_htable; /* key: lport/fport/lip/fip */ +- +-#define JHASH_INITVAL 0xdeadbeef +- +-static inline unsigned int rol32(unsigned int word, unsigned int shift) +-{ +- return (word << shift) | (word >> (32 - shift)); +-} +- +-#define __jhash_final(a, b, c) \ +-{ \ +- c ^= b; c -= rol32(b, 14); \ +- a ^= c; a -= rol32(c, 11); \ +- b ^= a; b -= rol32(a, 25); \ +- c ^= b; c -= rol32(b, 16); \ +- a ^= c; a -= rol32(c, 4); \ +- b ^= a; b -= rol32(a, 14); \ +- c ^= b; c -= rol32(b, 24); \ +-} +- +-static inline unsigned int jhash_3words(unsigned int a, unsigned int b, unsigned int c) +-{ +- a += JHASH_INITVAL; +- b += JHASH_INITVAL;; +- +- __jhash_final(a, b, c); +- +- return c; +-} +- +-static inline unsigned int jhash_3words6(unsigned int *a, unsigned int *b, unsigned int c) +-{ +- for (int i = 0; i < 4; i++) { +- unsigned int e = *((unsigned int *)a + i) + JHASH_INITVAL; +- unsigned int f = *((unsigned int *)b + i) + JHASH_INITVAL; +- +- __jhash_final(e, f, c); +- } +- +- return c; +-} +- +-#if LWIP_IPV4 && LWIP_IPV6 +-#define TUPLE4_HASH_FN(laddr, lport, faddr, fport) \ +- (IP_IS_V4(laddr) ? jhash_3words(ip_2_ip4(laddr)->addr, ip_2_ip4(faddr)->addr, lport|(fport<<16)) \ +- : jhash_3words6(ip_2_ip6(laddr)->addr, ip_2_ip6(faddr)->addr, lport|(fport<<16))) +-#elif LWIP_IPV4 +-#define TUPLE4_HASH_FN(laddr, lport, faddr, fport) \ +- jhash_3words(ip_2_ip4(laddr)->addr, ip_2_ip4(faddr)->addr, lport|(fport<<16)) +-#endif +- +-#endif /* GAZELLE_TCP_PCB_HASH */ +- + #if LWIP_EVENT_API + + enum lwip_event { +diff --git a/src/include/lwipgz_tcp_priv.h b/src/include/lwipgz_tcp_priv.h +new file mode 100644 +index 0000000..c6d0d00 +--- /dev/null ++++ b/src/include/lwipgz_tcp_priv.h +@@ -0,0 +1,212 @@ ++/* ++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, ++ * are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY ++ * OF SUCH DAMAGE. ++ * ++ * This file is part of the lwIP TCP/IP stack. ++ * ++ * Author: Huawei Technologies ++ * ++ */ ++ ++#ifndef __GAZELLE_TCP_PRIV_H__ ++#define __GAZELLE_TCP_PRIV_H__ ++ ++#include "lwip/opt.h" ++#include "lwip/sys.h" ++#include "lwipgz_hlist.h" ++ ++#define __TCP_REG(pcbs, npcb) \ ++ do { \ ++ if (*pcbs) \ ++ (*pcbs)->prev = npcb; \ ++ (npcb)->prev = NULL; \ ++ (npcb)->next = *pcbs; \ ++ *(pcbs) = (npcb); \ ++ tcp_timer_needed(); \ ++ } while (0) ++ ++#define __TCP_RMV(pcbs, npcb) \ ++ do { \ ++ if(*(pcbs) == (npcb)) { \ ++ *(pcbs) = (*pcbs)->next; \ ++ if (*pcbs) \ ++ (*pcbs)->prev = NULL; \ ++ } else { \ ++ struct tcp_pcb *prev, *next; \ ++ prev = npcb->prev; \ ++ next = npcb->next; \ ++ if (prev) \ ++ prev->next = next; \ ++ if (next) \ ++ next->prev = prev; \ ++ } \ ++ (npcb)->prev = NULL; \ ++ (npcb)->next = NULL; \ ++ } while(0) ++ ++#if TCP_DEBUG_PCB_LISTS ++#define TCP_REG(pcbs, npcb) do {\ ++ struct tcp_pcb *tcp_tmp_pcb; \ ++ LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %"U16_F"\n", (void *)(npcb), (npcb)->local_port)); \ ++ for (tcp_tmp_pcb = *(pcbs); \ ++ tcp_tmp_pcb != NULL; \ ++ tcp_tmp_pcb = tcp_tmp_pcb->next) { \ ++ LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ ++ } \ ++ LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ ++ __TCP_REG(pcbs, npcb); \ ++ LWIP_ASSERT("TCP_REG: tcp_pcbs sane", tcp_pcbs_sane()); \ ++ } while(0) ++#define TCP_RMV(pcbs, npcb) do { \ ++ struct tcp_pcb *tcp_tmp_pcb; \ ++ LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ ++ LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \ ++ __TCP_RMV(pcbs, npcb); \ ++ LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ ++ LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \ ++ } while(0) ++ ++#else /* LWIP_DEBUG */ ++ ++#define TCP_REG(pcbs, npcb) __TCP_REG(pcbs, npcb) ++#define TCP_RMV(pcbs, npcb) __TCP_RMV(pcbs, npcb) ++ ++#endif /* LWIP_DEBUG */ ++ ++#if GAZELLE_TCP_PCB_HASH ++struct tcp_hashbucket { ++ sys_mutex_t mutex; ++ struct hlist_head chain; ++}; ++struct tcp_hash_table { ++ u32_t size; ++ struct tcp_hashbucket array[GAZELLE_TCP_ACTIVE_HTABLE_SIZE]; ++}; ++extern PER_THREAD struct tcp_hash_table *tcp_active_htable; ++ ++#include ++static inline u32_t tcp_pcb_hash(ip_addr_t *local_ip, u16_t lport, ip_addr_t *remote_ip, u16_t rport) ++{ ++ u32_t c = lport | (rport << 16); ++ ++#if LWIP_IPV6 ++ if (IP_IS_V6(local_ip)) { ++ ip6_addr_t *lip6 = ip_2_ip6(local_ip); ++ ip6_addr_t *rip6 = ip_2_ip6(remote_ip); ++ for (int i = 0; i < 4; ++i) { ++ c = rte_jhash_3words(lip6->addr[i], rip6->addr[i], c, 0); ++ } ++ } else ++#endif /* LWIP_IPV6 */ ++ { ++ ip4_addr_t *lip4 = ip_2_ip4(local_ip); ++ ip4_addr_t *rip4 = ip_2_ip4(remote_ip); ++ c = rte_jhash_3words(lip4->addr, rip4->addr, c, 0); ++ } ++ ++ return c; ++} ++ ++#define TCP_REG_HASH(pcbs, npcb) \ ++ do { \ ++ struct hlist_head *head; \ ++ struct tcp_hash_table *htb = pcbs; \ ++ u32_t idx = tcp_pcb_hash(&((npcb)->local_ip), (npcb)->local_port, &((npcb)->remote_ip), (npcb)->remote_port); \ ++ idx &= (htb->size - 1); \ ++ head = &htb->array[idx].chain; \ ++ hlist_add_head(&(npcb)->tcp_node, head); \ ++ tcp_timer_needed(); \ ++ } while (0) ++ ++#define TCP_RMV_HASH(npcb) \ ++ do { \ ++ hlist_del_node(&(npcb)->tcp_node); \ ++ } while (0) ++ ++#define TCP_REG_ACTIVE_HASH(npcb) \ ++ do { \ ++ TCP_REG_HASH(tcp_active_htable, npcb); \ ++ tcp_active_pcbs_changed = 1; \ ++ } while (0) ++ ++#define TCP_RMV_ACTIVE_HASH(npcb) \ ++ do { \ ++ TCP_RMV_HASH(npcb); \ ++ tcp_active_pcbs_changed = 1; \ ++ } while (0) ++ ++#endif /* GAZELLE_TCP_PCB_HASH */ ++ ++#if GAZELLE_TCP_REUSE_IPPORT ++#define TCP_REG_SAMEPORT(first_pcb, lpcb) \ ++ do { \ ++ struct tcp_pcb_listen *tmp_pcb = first_pcb; \ ++ while (tmp_pcb->next_same_port_pcb != NULL) { \ ++ tmp_pcb = tmp_pcb->next_same_port_pcb; \ ++ }; \ ++ tmp_pcb->next_same_port_pcb = lpcb; \ ++ tcp_timer_needed(); \ ++ } while (0) ++#endif /* GAZELLE_TCP_REUSE_IPPORT */ ++ ++#if GAZELLE_ENABLE ++#include "lwipgz_flow.h" ++static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pcb *pcb) ++{ ++ LWIP_ASSERT("Invalid parameter", pcb != NULL); ++ ++ struct gazelle_quintuple qtuple = {0}; ++ ++ qtuple.protocol = IP_IS_V4_VAL(pcb->local_ip) ? GZ_ADDR_TYPE_V4 : GZ_ADDR_TYPE_V6; ++ qtuple.src_ip = *((gz_addr_t *)&pcb->local_ip); ++ qtuple.src_port = lwip_htons(pcb->local_port); ++ qtuple.dst_ip = *((gz_addr_t *)&pcb->remote_ip); ++ qtuple.dst_port = lwip_htons(pcb->remote_port); ++ ++#if GAZELLE_TCP_REUSE_IPPORT ++ if (reg_type == REG_RING_TCP_CONNECT_CLOSE) { ++ struct tcp_pcb_listen* lpcb = pcb->listener; ++ if (lpcb != NULL) { ++ lpcb->connect_num--; ++ } ++ } ++#endif ++ ++ return vdev_reg_xmit(reg_type, &qtuple); ++} ++static inline void vdev_unreg_done(const struct tcp_pcb *pcb) ++{ ++ if (pcb->local_port == 0) { ++ return; ++ } ++ if (pcb->state == LISTEN) { ++ vdev_reg_done(REG_RING_TCP_LISTEN_CLOSE, pcb); ++ } else { ++ vdev_reg_done(REG_RING_TCP_CONNECT_CLOSE, pcb); ++ } ++} ++#endif /* GAZELLE_ENABLE */ ++ ++#endif /* __GAZELLE_TCP_PRIV_H__ */ +\ No newline at end of file +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index 5994390..caccf63 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -47,7 +47,11 @@ + + #define FRAME_MTU 1500 + ++#define GAZELLE_MAX_CLIENTS (20000) ++#define GAZELLE_RESERVED_CLIENTS (2000) ++ + #define GAZELLE_TCP_PCB_HASH 1 ++#define GAZELLE_TCP_ACTIVE_HTABLE_SIZE (GAZELLE_MAX_CLIENTS >> 1) + + #define GAZELLE_TCP_MAX_DATA_ACK_NUM 256 + #define GAZELLE_TCP_MAX_PBUF_CHAIN_LEN 40 +@@ -115,9 +119,6 @@ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ + */ +-#define GAZELLE_MAX_CLIENTS (20000) +-#define GAZELLE_RESERVED_CLIENTS (2000) +- + #define LWIP_SUPPORT_CUSTOM_PBUF 1 + + #define MEMP_MEM_MALLOC 0 +-- +2.33.0 + diff --git a/lwip.spec b/lwip.spec index a66c4a7..972bb6f 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.2.0 -Release: 45 +Release: 46 License: BSD URL: http://savannah.nongnu.org/projects/lwip/ Source0: http://download.savannah.nongnu.org/releases/lwip/%{name}-%{version}.zip @@ -165,6 +165,7 @@ Patch9149: 0150-cleancode-refactor-posix_api.patch Patch9150: 0151-cleancode-refactor-lwipgz_list.h.patch Patch9151: 0152-cleancode-refactor-lwipgz_hlist.h.patch Patch9152: 0153-cleancode-move-options-from-opt.h-to-lwipopts.h.patch +Patch9153: 0154-cleancode-move-tcp_hash_table-to-lwipgz_tcp_priv.h.patch BuildRequires: gcc-c++ dos2unix dpdk-devel @@ -194,6 +195,9 @@ cd %{_builddir}/%{name}-%{version}/src %{_libdir}/liblwip.a %changelog +* Fri Jul 19 2024 LemmyHuang - 2.2.0-46 +- cleancode: move tcp_hash_table to lwipgz_tcp_priv.h + * Thu Jul 18 2024 LemmyHuang - 2.2.0-45 - cleancode: move options from opt.h to lwipopts.h