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