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