• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 5d9613fe21e2e02863517dbd9d5db539336351b9 Mon Sep 17 00:00:00 2001
2From: zhengjiebing <zhengjiebing_yewu@cmss.chinamobile.com>
3Date: Fri, 17 Nov 2023 20:37:56 +0800
4Subject: [PATCH] enable ipv6
5
6---
7 src/api/sockets.c                | 12 +++++++++++-
8 src/core/dir.mk                  |  4 +++-
9 src/core/init.c                  |  2 ++
10 src/core/ipv6/ip6.c              | 18 ++++++++++++++++--
11 src/core/ipv6/ip6_frag.c         |  4 ++++
12 src/core/tcp.c                   |  2 +-
13 src/core/tcp_in.c                |  4 ++--
14 src/core/tcp_out.c               |  2 ++
15 src/core/udp.c                   |  2 +-
16 src/include/dpdk_cksum.h         | 12 ++++++------
17 src/include/dpdk_version.h       |  1 +
18 src/include/lwip/priv/tcp_priv.h | 27 ++++++++++++++++++++-------
19 src/include/lwip/sockets.h       |  2 ++
20 src/include/lwip/tcp.h           | 21 ++++++++++++++++++++-
21 src/include/lwipopts.h           | 11 ++++++++++-
22 src/include/reg_sock.h           |  7 ++++++-
23 16 files changed, 107 insertions(+), 24 deletions(-)
24
25diff --git a/src/api/sockets.c b/src/api/sockets.c
26index 6cff4cb..62052f2 100644
27--- a/src/api/sockets.c
28+++ b/src/api/sockets.c
29@@ -113,6 +113,14 @@
30 #endif /* LWIP_IPV4 */
31
32 #if LWIP_IPV6
33+#if GAZELLE_ENABLE
34+#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \
35+      (sin6)->sin6_family = AF_INET6; \
36+      (sin6)->sin6_port = lwip_htons((port)); \
37+      (sin6)->sin6_flowinfo = 0; \
38+      inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \
39+      (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); }while(0)
40+#else
41 #define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \
42       (sin6)->sin6_len = sizeof(struct sockaddr_in6); \
43       (sin6)->sin6_family = AF_INET6; \
44@@ -120,6 +128,7 @@
45       (sin6)->sin6_flowinfo = 0; \
46       inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \
47       (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); }while(0)
48+#endif /* GAZELLE_ENABLE */
49 #define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) do { \
50     inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \
51     if (ip6_addr_has_scope(ip_2_ip6(ipaddr), IP6_UNKNOWN)) { \
52@@ -555,7 +564,8 @@ alloc_socket(struct netconn *newconn, int accepted, int flags)
53   LWIP_UNUSED_ARG(accepted);
54
55 #if GAZELLE_ENABLE
56-  int type, protocol = 0, domain = AF_INET;
57+  int type, protocol = 0;
58+  int domain = NETCONNTYPE_ISIPV6(newconn->type) ? AF_INET6 : AF_INET;
59   switch (NETCONNTYPE_GROUP(newconn->type)) {
60     case NETCONN_RAW:
61       type = SOCK_RAW;
62diff --git a/src/core/dir.mk b/src/core/dir.mk
63index 57a9670..69b43d1 100644
64--- a/src/core/dir.mk
65+++ b/src/core/dir.mk
66@@ -1,6 +1,8 @@
67 SRC = def.c inet_chksum.c init.c ip.c mem.c memp.c netif.c pbuf.c \
68 	  raw.c tcp.c tcp_in.c tcp_out.c timeouts.c udp.c stats.c\
69 	  ipv4/icmp.c ipv4/ip4_addr.c ipv4/ip4_frag.c ipv4/etharp.c \
70-	  ipv4/ip4.c ipv4/igmp.c
71+	  ipv4/ip4.c ipv4/igmp.c ipv6/icmp6.c ipv6/ip6_addr.c ipv6/ip6_frag.c \
72+	  ipv6/ethip6.c ipv6/ip6.c ipv6/dhcp6.c ipv6/inet6.c \
73+	  ipv6/mld6.c ipv6/nd6.c
74
75 $(eval $(call register_dir, core, $(SRC)))
76diff --git a/src/core/init.c b/src/core/init.c
77index 60e1c68..6880fd3 100644
78--- a/src/core/init.c
79+++ b/src/core/init.c
80@@ -347,7 +347,9 @@ lwip_init(void)
81   mem_init();
82   memp_init();
83   pbuf_init();
84+#if !GAZELLE_ENABLE
85   netif_init();
86+#endif  /* GAZELLE_ENABLE */
87 #if LWIP_IPV4
88   ip_init();
89 #if LWIP_ARP
90diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c
91index 9d904ec..101e599 100644
92--- a/src/core/ipv6/ip6.c
93+++ b/src/core/ipv6/ip6.c
94@@ -60,6 +60,10 @@
95 #include "lwip/debug.h"
96 #include "lwip/stats.h"
97
98+#if GAZELLE_ENABLE && (CHECKSUM_CHECK_IP_HW || CHECKSUM_GEN_IP_HW)
99+#include "dpdk_cksum.h"
100+#endif
101+
102 #ifdef LWIP_HOOK_FILENAME
103 #include LWIP_HOOK_FILENAME
104 #endif
105@@ -1232,6 +1236,10 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
106     /* src cannot be NULL here */
107     ip6_addr_copy_to_packed(ip6hdr->src, *src);
108
109+#if CHECKSUM_GEN_IP_HW
110+    iph_cksum_set(p, IP6_HLEN, 0);
111+#endif /* CHECKSUM_GEN_IP_HW */
112+
113   } else {
114     /* IP header already included in p */
115     ip6hdr = (struct ip6_hdr *)p->payload;
116@@ -1270,9 +1278,15 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
117 #endif /* ENABLE_LOOPBACK */
118 #if LWIP_IPV6_FRAG
119   /* don't fragment if interface has mtu set to 0 [loopif] */
120-  if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
121-    return ip6_frag(p, netif, dest);
122+#if GAZELLE_ENABLE
123+  if (!(netif_get_txol_flags(netif) & DEV_TX_OFFLOAD_TCP_TSO)) {
124+#endif
125+    if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
126+      return ip6_frag(p, netif, dest);
127+    }
128+#if GAZELLE_ENABLE
129   }
130+#endif
131 #endif /* LWIP_IPV6_FRAG */
132
133   LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
134diff --git a/src/core/ipv6/ip6_frag.c b/src/core/ipv6/ip6_frag.c
135index 8b352f5..67e36bf 100644
136--- a/src/core/ipv6/ip6_frag.c
137+++ b/src/core/ipv6/ip6_frag.c
138@@ -689,6 +689,7 @@ ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p)
139   memp_free(MEMP_FRAG_PBUF, p);
140 }
141
142+#if !GAZELLE_ENABLE
143 /** Free-callback function to free a 'struct pbuf_custom_ref', called by
144  * pbuf_free. */
145 static void
146@@ -702,6 +703,7 @@ ip6_frag_free_pbuf_custom(struct pbuf *p)
147   }
148   ip6_frag_free_pbuf_custom_ref(pcr);
149 }
150+#endif  /* !GAZELLE_ENABLE */
151 #endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
152
153 /**
154@@ -816,7 +818,9 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
155       }
156       pbuf_ref(p);
157       pcr->original = p;
158+#if !GAZELLE_ENABLE
159       pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom;
160+#endif  /* !GAZELLE_ENABLE */
161
162       /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain
163        * so that it is removed when pbuf_dechain is later called on rambuf.
164diff --git a/src/core/tcp.c b/src/core/tcp.c
165index c44664e..963b8a4 100644
166--- a/src/core/tcp.c
167+++ b/src/core/tcp.c
168@@ -1155,7 +1155,7 @@ tcp_new_port(void)
169
170       if (__atomic_load_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) {
171 #if GAZELLE_ENABLE
172-        if (port_in_stack_queue(pcb->remote_ip.addr, pcb->local_ip.addr, pcb->remote_port, tcp_port)) {
173+        if (port_in_stack_queue(pcb->remote_ip, pcb->local_ip, pcb->remote_port, tcp_port)) {
174             tmp_port = tcp_port;
175             __atomic_store_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE);
176             break;
177diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c
178index ecbd616..7154659 100644
179--- a/src/core/tcp_in.c
180+++ b/src/core/tcp_in.c
181@@ -309,8 +309,8 @@ tcp_input(struct pbuf *p, struct netif *inp)
182   prev = NULL;
183
184 #if GAZELLE_TCP_PCB_HASH
185-  idx = TUPLE4_HASH_FN( ip_current_dest_addr()->addr, tcphdr->dest,
186-                      ip_current_src_addr()->addr, tcphdr->src) &
187+  idx = TUPLE4_HASH_FN( ip_current_dest_addr(), tcphdr->dest,
188+                      ip_current_src_addr(), tcphdr->src) &
189          (tcp_active_htable->size - 1);
190   head = &tcp_active_htable->array[idx].chain;
191   tcppcb_hlist_for_each(pcb, node, head) {
192diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c
193index 073d989..137e3cf 100644
194--- a/src/core/tcp_out.c
195+++ b/src/core/tcp_out.c
196@@ -139,7 +139,9 @@ static err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct
197 static struct netif *
198 tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst)
199 {
200+#if LWIP_IPV6
201   LWIP_UNUSED_ARG(src); /* in case IPv4-only and source-based routing is disabled */
202+#endif /* LWIP_IPV6 */
203
204   if ((pcb != NULL) && (pcb->netif_idx != NETIF_NO_INDEX)) {
205     return netif_get_by_index(pcb->netif_idx);
206diff --git a/src/core/udp.c b/src/core/udp.c
207index 828a489..727a705 100644
208--- a/src/core/udp.c
209+++ b/src/core/udp.c
210@@ -132,7 +132,7 @@ udp_new_port(struct udp_pcb *dst_pcb)
211     }
212
213     if (__atomic_load_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) {
214-      if (port_in_stack_queue(dst_pcb->remote_ip.addr, dst_pcb->local_ip.addr, dst_pcb->remote_port, udp_port)) {
215+      if (port_in_stack_queue(dst_pcb->remote_ip, dst_pcb->local_ip, dst_pcb->remote_port, udp_port)) {
216           tmp_port = udp_port;
217           __atomic_store_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE);
218           break;
219diff --git a/src/include/dpdk_cksum.h b/src/include/dpdk_cksum.h
220index b8056f9..38cfb96 100644
221--- a/src/include/dpdk_cksum.h
222+++ b/src/include/dpdk_cksum.h
223@@ -66,7 +66,7 @@ static inline void ethh_cksum_set(struct pbuf *p, u16_t len) {
224
225 // replaces IPH_CHKSUM_SET
226 static inline void iph_cksum_set(struct pbuf *p, u16_t len, bool do_ipcksum) {
227-    p->ol_flags |= RTE_MBUF_F_TX_IPV4;
228+    p->ol_flags |= ((len == IP_HLEN) ? RTE_MBUF_F_TX_IPV4 : RTE_MBUF_F_TX_IPV6);
229     if (do_ipcksum) {
230         p->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM;
231     }
232@@ -95,16 +95,16 @@ static inline void udph_cksum_set(struct pbuf *p, u16_t len) {
233 static inline u16_t ip_chksum_pseudo_offload(u8_t proto, u16_t proto_len,
234                                              const ip_addr_t *src, const ip_addr_t *dst)
235 {
236-    struct ipv4_psd_header {
237-        uint32_t src_addr; /* IP address of source host. */
238-        uint32_t dst_addr; /* IP address of destination host. */
239+    struct ip_psd_header {
240+        ip_addr_t src_addr; /* IP address of source host. */
241+        ip_addr_t dst_addr; /* IP address of destination host. */
242         uint8_t  zero;     /* zero. */
243         uint8_t  proto;    /* L4 protocol type. */
244         uint16_t len;      /* L4 length. */
245     } psd_hdr;
246
247-    psd_hdr.src_addr = ip4_addr_get_u32(src);
248-    psd_hdr.dst_addr = ip4_addr_get_u32(dst);
249+    ip_addr_copy(psd_hdr.src_addr, *src);
250+    ip_addr_copy(psd_hdr.dst_addr, *dst);
251     psd_hdr.proto = proto;
252     psd_hdr.len = lwip_htons(proto_len);
253     psd_hdr.zero = 0;
254diff --git a/src/include/dpdk_version.h b/src/include/dpdk_version.h
255index c90ddb8..e61d0b3 100644
256--- a/src/include/dpdk_version.h
257+++ b/src/include/dpdk_version.h
258@@ -43,6 +43,7 @@
259 #define RTE_MBUF_F_RX_IP_CKSUM_BAD  PKT_RX_IP_CKSUM_BAD
260 #define RTE_MBUF_F_RX_L4_CKSUM_BAD  PKT_RX_L4_CKSUM_BAD
261 #define RTE_MBUF_F_TX_IPV4          PKT_TX_IPV4
262+#define RTE_MBUF_F_TX_IPV6          PKT_TX_IPV6
263 #define RTE_MBUF_F_TX_IP_CKSUM      PKT_TX_IP_CKSUM
264 #define RTE_MBUF_F_TX_TCP_CKSUM     PKT_TX_TCP_CKSUM
265 #define RTE_MBUF_F_TX_TCP_SEG       PKT_TX_TCP_SEG
266diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h
267index ddae3fd..9b1341c 100644
268--- a/src/include/lwip/priv/tcp_priv.h
269+++ b/src/include/lwip/priv/tcp_priv.h
270@@ -347,11 +347,24 @@ static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pc
271   LWIP_ASSERT("Invalid parameter", pcb != NULL);
272
273   struct gazelle_quintuple qtuple;
274-  qtuple.protocol   = 0;
275-  qtuple.src_ip     = pcb->local_ip.addr;
276-  qtuple.src_port   = lwip_htons(pcb->local_port);
277-  qtuple.dst_ip     = pcb->remote_ip.addr;
278-  qtuple.dst_port   = lwip_htons(pcb->remote_port);
279+  if (IP_IS_V4_VAL(pcb->local_ip)) {
280+      qtuple.protocol   = 0;
281+      qtuple.src_ip     = ip_2_ip4(&pcb->local_ip)->addr;
282+      qtuple.src_port   = lwip_htons(pcb->local_port);
283+      qtuple.dst_ip     = ip_2_ip4(&pcb->remote_ip)->addr;
284+      qtuple.dst_port   = lwip_htons(pcb->remote_port);
285+  } else {
286+#if LWIP_IPV6
287+      qtuple.protocol   = 1;
288+      qtuple.src_port   = lwip_htons(pcb->local_port);
289+      qtuple.dst_port   = lwip_htons(pcb->remote_port);
290+
291+      for (int i = 0; i < 4; i++) {
292+          qtuple.src_ip6[i] = pcb->local_ip.u_addr.ip6.addr[i];
293+          qtuple.dst_ip6[i] = pcb->remote_ip.u_addr.ip6.addr[i];
294+      }
295+#endif
296+  }
297
298 #if GAZELLE_TCP_REUSE_IPPORT
299   if (reg_type == REG_RING_TCP_CONNECT_CLOSE) {
300@@ -474,8 +487,8 @@ static inline void vdev_unreg_done(const struct tcp_pcb *pcb)
301     u32_t idx;                                     \
302     struct hlist_head *hd;                         \
303     struct tcp_hash_table *htb = pcbs;             \
304-    idx = TUPLE4_HASH_FN((npcb)->local_ip.addr, (npcb)->local_port,  \
305-                       (npcb)->remote_ip.addr, (npcb)->remote_port) & \
306+    idx = TUPLE4_HASH_FN(&((npcb)->local_ip), (npcb)->local_port,  \
307+                       &((npcb)->remote_ip), (npcb)->remote_port) & \
308                        (htb->size - 1);            \
309     hd = &htb->array[idx].chain;                   \
310     hlist_add_head(&(npcb)->tcp_node, hd);         \
311diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h
312index cfec6a5..5715df4 100644
313--- a/src/include/lwip/sockets.h
314+++ b/src/include/lwip/sockets.h
315@@ -88,7 +88,9 @@ struct sockaddr_in {
316
317 #if LWIP_IPV6
318 struct sockaddr_in6 {
319+#if !GAZELLE_ENABLE
320   u8_t            sin6_len;      /* length of this structure    */
321+#endif /* GAZELLE_ENABLE */
322   sa_family_t     sin6_family;   /* AF_INET6                    */
323   in_port_t       sin6_port;     /* Transport layer port #      */
324   u32_t           sin6_flowinfo; /* IPv6 flow information       */
325diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h
326index 959df3e..91a86c9 100644
327--- a/src/include/lwip/tcp.h
328+++ b/src/include/lwip/tcp.h
329@@ -476,7 +476,26 @@ static inline unsigned int jhash_3words(unsigned int a, unsigned int b, unsigned
330   return c;
331 }
332
333-#define TUPLE4_HASH_FN(laddr, lport, faddr, fport)	 jhash_3words(laddr, faddr,lport|(fport<<16))
334+static inline unsigned int jhash_3words6(unsigned int *a, unsigned int *b, unsigned int c)
335+{
336+  for (int i = 0; i < 4; i++) {
337+    unsigned int e = *((unsigned int *)a + i) + JHASH_INITVAL;
338+    unsigned int f = *((unsigned int *)b + i) + JHASH_INITVAL;
339+
340+    __jhash_final(e, f, c);
341+  }
342+
343+  return c;
344+}
345+
346+#if LWIP_IPV4 && LWIP_IPV6
347+#define TUPLE4_HASH_FN(laddr, lport, faddr, fport)  \
348+      (IP_IS_V4(laddr) ? jhash_3words(ip_2_ip4(laddr)->addr, ip_2_ip4(faddr)->addr, lport|(fport<<16))  \
349+      : jhash_3words6(ip_2_ip6(laddr)->addr, ip_2_ip6(faddr)->addr, lport|(fport<<16)))
350+#elif LWIP_IPV4
351+#define TUPLE4_HASH_FN(laddr, lport, faddr, fport)  \
352+      jhash_3words(ip_2_ip4(laddr)->addr, ip_2_ip4(faddr)->addr, lport|(fport<<16))
353+#endif
354
355 #define tcppcb_hlist_for_each(tcppcb, node, list) \
356   hlist_for_each_entry(tcppcb, node, list, tcp_node)
357diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h
358index a18179e..9ab5cde 100644
359--- a/src/include/lwipopts.h
360+++ b/src/include/lwipopts.h
361@@ -178,6 +178,14 @@
362 #define IP_HLEN 20
363
364
365+/*
366+   -------------------------------------
367+   ----------- IPv6  options -----------
368+   -------------------------------------
369+*/
370+#define LWIP_IPV6                1
371+#define IP6_HLEN                 40
372+
373 /*
374    ---------------------------------
375    ---------- UDP options ----------
376@@ -211,7 +219,7 @@
377 #define TCP_OVERSIZE TCP_MSS
378 #define LWIP_NETIF_TX_SINGLE_PBUF 1
379
380-#define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN)
381+#define TCP_MSS (FRAME_MTU - IP6_HLEN - TCP_HLEN - VLAN_LEN)
382
383 #define TCP_WND (2500 * TCP_MSS)
384
385@@ -263,5 +271,6 @@
386
387 #define ETHARP_SUPPORT_VLAN 1
388 #define LWIP_VLAN_PCP 1
389+#define VLAN_LEN 4
390
391 #endif /* __LWIPOPTS_H__ */
392diff --git a/src/include/reg_sock.h b/src/include/reg_sock.h
393index 5d5710d..5a5e971 100644
394--- a/src/include/reg_sock.h
395+++ b/src/include/reg_sock.h
396@@ -34,6 +34,7 @@
397 #define __REG_SOCK_H__
398
399 #include <stdbool.h>
400+#include "lwip/ip_addr.h"
401
402 enum reg_ring_type {
403     REG_RING_TCP_LISTEN = 0,
404@@ -50,6 +51,10 @@ struct gazelle_quintuple {
405     uint16_t dst_port;
406     uint32_t src_ip;
407     uint32_t dst_ip;
408+#if LWIP_IPV6
409+    uint32_t src_ip6[4];
410+    uint32_t dst_ip6[4];
411+#endif
412 };
413
414 struct reg_ring_msg {
415@@ -60,6 +65,6 @@ struct reg_ring_msg {
416 };
417
418 extern int vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple);
419-extern bool port_in_stack_queue(uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port);
420+extern bool port_in_stack_queue(ip_addr_t src_ip, ip_addr_t dst_ip, uint16_t src_port, uint16_t dst_port);
421
422 #endif /* __REG_SOCK_H__ */
423--
4242.27.0
425
426