1195972f6Sopenharmony_ciFrom 71d82a830005540ef92b2bcd7c121c9ff85beb64 Mon Sep 17 00:00:00 2001
2195972f6Sopenharmony_ciFrom: j00660176 <jiangheng14@huawei.com>
3195972f6Sopenharmony_ciDate: Mon, 12 Jun 2023 20:21:23 +0800
4195972f6Sopenharmony_ciSubject: [PATCH] fix udp send/recv in multiple queue
5195972f6Sopenharmony_ci
6195972f6Sopenharmony_ci---
7195972f6Sopenharmony_ci src/core/udp.c         | 73 +++++++++++++++++++++++++++++++++++++++---
8195972f6Sopenharmony_ci src/include/lwip/udp.h |  4 +++
9195972f6Sopenharmony_ci 2 files changed, 73 insertions(+), 4 deletions(-)
10195972f6Sopenharmony_ci
11195972f6Sopenharmony_cidiff --git a/src/core/udp.c b/src/core/udp.c
12195972f6Sopenharmony_ciindex fba645b..0b1fa65 100644
13195972f6Sopenharmony_ci--- a/src/core/udp.c
14195972f6Sopenharmony_ci+++ b/src/core/udp.c
15195972f6Sopenharmony_ci@@ -65,10 +65,12 @@
16195972f6Sopenharmony_ci 
17195972f6Sopenharmony_ci #include <string.h>
18195972f6Sopenharmony_ci 
19195972f6Sopenharmony_ci-#if GAZELLE_ENABLE
20195972f6Sopenharmony_ci-#include "lwipsock.h"
21195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE
22195972f6Sopenharmony_ci+#include <pthread.h>
23195972f6Sopenharmony_ci #include <rte_prefetch.h>
24195972f6Sopenharmony_ci+#include "lwipsock.h"
25195972f6Sopenharmony_ci #include "dpdk_cksum.h"
26195972f6Sopenharmony_ci+#include "reg_sock.h"
27195972f6Sopenharmony_ci #endif
28195972f6Sopenharmony_ci 
29195972f6Sopenharmony_ci #ifndef UDP_LOCAL_PORT_RANGE_START
30195972f6Sopenharmony_ci@@ -81,10 +83,24 @@
31195972f6Sopenharmony_ci 
32195972f6Sopenharmony_ci /* last local UDP port */
33195972f6Sopenharmony_ci static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START;
34195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE
35195972f6Sopenharmony_ci+static pthread_mutex_t g_udp_port_mutex = PTHREAD_MUTEX_INITIALIZER;
36195972f6Sopenharmony_ci+static u8_t port_state[UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START + 1] = {0};
37195972f6Sopenharmony_ci+static void udp_release_port(u16_t port)
38195972f6Sopenharmony_ci+{
39195972f6Sopenharmony_ci+    if (port >= UDP_LOCAL_PORT_RANGE_START && port <= UDP_LOCAL_PORT_RANGE_END) {
40195972f6Sopenharmony_ci+        port_state[port - UDP_LOCAL_PORT_RANGE_START] = 0;
41195972f6Sopenharmony_ci+    }
42195972f6Sopenharmony_ci+}
43195972f6Sopenharmony_ci+#endif
44195972f6Sopenharmony_ci 
45195972f6Sopenharmony_ci /* The list of UDP PCBs */
46195972f6Sopenharmony_ci /* exported in udp.h (was static) */
47195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE
48195972f6Sopenharmony_ci+PER_THREAD struct udp_pcb *udp_pcbs;
49195972f6Sopenharmony_ci+#else
50195972f6Sopenharmony_ci struct udp_pcb *udp_pcbs;
51195972f6Sopenharmony_ci+#endif
52195972f6Sopenharmony_ci 
53195972f6Sopenharmony_ci /**
54195972f6Sopenharmony_ci  * Initialize this module.
55195972f6Sopenharmony_ci@@ -102,6 +118,37 @@ udp_init(void)
56195972f6Sopenharmony_ci  *
57195972f6Sopenharmony_ci  * @return a new (free) local UDP port number
58195972f6Sopenharmony_ci  */
59195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE
60195972f6Sopenharmony_ci+static u16_t
61195972f6Sopenharmony_ci+udp_new_port(struct udp_pcb *dst_pcb)
62195972f6Sopenharmony_ci+{
63195972f6Sopenharmony_ci+  u16_t n = 0;
64195972f6Sopenharmony_ci+  u16_t tmp_port = 0;
65195972f6Sopenharmony_ci+
66195972f6Sopenharmony_ci+  pthread_mutex_lock(&g_udp_port_mutex);
67195972f6Sopenharmony_ci+  do {
68195972f6Sopenharmony_ci+    if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) {
69195972f6Sopenharmony_ci+      udp_port = UDP_LOCAL_PORT_RANGE_START;
70195972f6Sopenharmony_ci+    }
71195972f6Sopenharmony_ci+
72195972f6Sopenharmony_ci+    if (__atomic_load_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) {
73195972f6Sopenharmony_ci+      if (port_in_stack_queue(dst_pcb->remote_ip.addr, dst_pcb->local_ip.addr, dst_pcb->remote_port, udp_port)) {
74195972f6Sopenharmony_ci+          tmp_port = udp_port;
75195972f6Sopenharmony_ci+          __atomic_store_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE);
76195972f6Sopenharmony_ci+          break;
77195972f6Sopenharmony_ci+      }
78195972f6Sopenharmony_ci+    }
79195972f6Sopenharmony_ci+    n++;
80195972f6Sopenharmony_ci+    if (n > UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START) {
81195972f6Sopenharmony_ci+      break;
82195972f6Sopenharmony_ci+    }
83195972f6Sopenharmony_ci+  } while (tmp_port == 0);
84195972f6Sopenharmony_ci+
85195972f6Sopenharmony_ci+  pthread_mutex_unlock(&g_udp_port_mutex);
86195972f6Sopenharmony_ci+
87195972f6Sopenharmony_ci+  return tmp_port;
88195972f6Sopenharmony_ci+}
89195972f6Sopenharmony_ci+#else
90195972f6Sopenharmony_ci static u16_t
91195972f6Sopenharmony_ci udp_new_port(void)
92195972f6Sopenharmony_ci {
93195972f6Sopenharmony_ci@@ -123,6 +170,7 @@ again:
94195972f6Sopenharmony_ci   }
95195972f6Sopenharmony_ci   return udp_port;
96195972f6Sopenharmony_ci }
97195972f6Sopenharmony_ci+#endif
98195972f6Sopenharmony_ci 
99195972f6Sopenharmony_ci /** Common code to see if the current input packet matches the pcb
100195972f6Sopenharmony_ci  * (current input packet is accessed via ip(4/6)_current_* macros)
101195972f6Sopenharmony_ci@@ -789,7 +837,21 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
102195972f6Sopenharmony_ci   /* if the PCB is not yet bound to a port, bind it here */
103195972f6Sopenharmony_ci   if (pcb->local_port == 0) {
104195972f6Sopenharmony_ci     LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
105195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE
106195972f6Sopenharmony_ci+    ip_addr_t tmp_local_ip = pcb->local_ip;
107195972f6Sopenharmony_ci+    ip_addr_t tmp_remote_ip = pcb->remote_ip;
108195972f6Sopenharmony_ci+    u16_t tmp_remote_port = pcb->remote_port;
109195972f6Sopenharmony_ci+
110195972f6Sopenharmony_ci+    pcb->local_ip = netif->ip_addr;
111195972f6Sopenharmony_ci+    pcb->remote_port = dst_port;
112195972f6Sopenharmony_ci+    pcb->remote_ip = *dst_ip;
113195972f6Sopenharmony_ci+#endif
114195972f6Sopenharmony_ci     err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
115195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE
116195972f6Sopenharmony_ci+      pcb->local_ip = tmp_local_ip;
117195972f6Sopenharmony_ci+      pcb->remote_ip = tmp_remote_ip;
118195972f6Sopenharmony_ci+      pcb->remote_port =  tmp_remote_port;
119195972f6Sopenharmony_ci+#endif
120195972f6Sopenharmony_ci     if (err != ERR_OK) {
121195972f6Sopenharmony_ci       LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
122195972f6Sopenharmony_ci       return err;
123195972f6Sopenharmony_ci@@ -941,7 +1003,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
124195972f6Sopenharmony_ci   /* @todo: must this be increased even if error occurred? */
125195972f6Sopenharmony_ci   MIB2_STATS_INC(mib2.udpoutdatagrams);
126195972f6Sopenharmony_ci 
127195972f6Sopenharmony_ci-#if !GAZELLE_ENABLE
128195972f6Sopenharmony_ci+#if !GAZELLE_UDP_ENABLE
129195972f6Sopenharmony_ci   /* did we chain a separate header pbuf earlier? */
130195972f6Sopenharmony_ci   if (q != p)
131195972f6Sopenharmony_ci #endif
132195972f6Sopenharmony_ci@@ -1026,7 +1088,7 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
133195972f6Sopenharmony_ci 
134195972f6Sopenharmony_ci   /* no port specified? */
135195972f6Sopenharmony_ci   if (port == 0) {
136195972f6Sopenharmony_ci-    port = udp_new_port();
137195972f6Sopenharmony_ci+    port = udp_new_port(pcb);
138195972f6Sopenharmony_ci     if (port == 0) {
139195972f6Sopenharmony_ci       /* no more ports available in local range */
140195972f6Sopenharmony_ci       LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
141195972f6Sopenharmony_ci@@ -1252,6 +1314,9 @@ udp_remove(struct udp_pcb *pcb)
142195972f6Sopenharmony_ci       }
143195972f6Sopenharmony_ci     }
144195972f6Sopenharmony_ci   }
145195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE
146195972f6Sopenharmony_ci+  udp_release_port(pcb->local_port);
147195972f6Sopenharmony_ci+#endif
148195972f6Sopenharmony_ci   memp_free(MEMP_UDP_PCB, pcb);
149195972f6Sopenharmony_ci }
150195972f6Sopenharmony_ci 
151195972f6Sopenharmony_cidiff --git a/src/include/lwip/udp.h b/src/include/lwip/udp.h
152195972f6Sopenharmony_ciindex b1c78e5..f588d90 100644
153195972f6Sopenharmony_ci--- a/src/include/lwip/udp.h
154195972f6Sopenharmony_ci+++ b/src/include/lwip/udp.h
155195972f6Sopenharmony_ci@@ -112,7 +112,11 @@ struct udp_pcb {
156195972f6Sopenharmony_ci   void *recv_arg;
157195972f6Sopenharmony_ci };
158195972f6Sopenharmony_ci /* udp_pcbs export for external reference (e.g. SNMP agent) */
159195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE
160195972f6Sopenharmony_ci+extern PER_THREAD struct udp_pcb *udp_pcbs;
161195972f6Sopenharmony_ci+#else
162195972f6Sopenharmony_ci extern struct udp_pcb *udp_pcbs;
163195972f6Sopenharmony_ci+#endif
164195972f6Sopenharmony_ci 
165195972f6Sopenharmony_ci /* The following functions is the application layer interface to the
166195972f6Sopenharmony_ci    UDP code. */
167195972f6Sopenharmony_ci-- 
168195972f6Sopenharmony_ci2.33.0
169195972f6Sopenharmony_ci
170