From cc2babc37cf2ae592802271c867282cf82bd991f Mon Sep 17 00:00:00 2001
From: Lemmy Huang <huangliming5@huawei.com>
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 <huangliming5@huawei.com>
---
 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 <rte_jhash.h>
+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

