From d9ef907e03f44c30e26190b0c5ad895de716ac5c Mon Sep 17 00:00:00 2001
From: kircher <majun65@huawei.com>
Date: Fri, 12 May 2023 20:54:51 +0800
Subject: [PATCH] add udp multicast in support

---
 src/api/api_msg.c          |  5 +++++
 src/api/sockets.c          | 21 ++++++++++++++++++++-
 src/core/dir.mk            |  2 +-
 src/core/udp.c             | 28 +++++++++++++++++++++++++---
 src/include/dpdk_cksum.h   |  4 ++++
 src/include/lwip/opt.h     |  5 +++--
 src/include/lwip/pbuf.h    |  4 ++++
 src/include/lwip/sockets.h | 15 +++++++++++++++
 src/include/lwipopts.h     |  2 +-
 9 files changed, 78 insertions(+), 8 deletions(-)

diff --git a/src/api/api_msg.c b/src/api/api_msg.c
index 5a2e689..98537b8 100644
--- a/src/api/api_msg.c
+++ b/src/api/api_msg.c
@@ -285,8 +285,13 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
 #if LWIP_SO_RCVBUF
     SYS_ARCH_INC(conn->recv_avail, len);
 #endif /* LWIP_SO_RCVBUF */
+#if GAZELLE_ENABLE
+    add_recv_list(conn->socket);
+    LWIP_UNUSED_ARG(len);
+#else
     /* Register event with callback */
     API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
+#endif
   }
 }
 #endif /* LWIP_UDP */
diff --git a/src/api/sockets.c b/src/api/sockets.c
index 7b5606f..bedb86b 100644
--- a/src/api/sockets.c
+++ b/src/api/sockets.c
@@ -54,6 +54,7 @@
 #include "lwip/netif.h"
 #include "lwip/priv/tcpip_priv.h"
 #include "lwip/mld6.h"
+#include "lwip/api.h"
 #if LWIP_CHECKSUM_ON_COPY
 #include "lwip/inet_chksum.h"
 #endif
@@ -1222,7 +1223,7 @@ lwip_recv_tcp_done:
 #endif
 
 /* Convert a netbuf's address data to struct sockaddr */
-static int
+int
 lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port,
                     struct sockaddr *from, socklen_t *fromlen)
 {
@@ -1307,6 +1308,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16
     apiflags = 0;
   }
 
+#if !GAZELLE_ENABLE
   LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf));
   /* Check if there is data left from the last recv operation. */
   buf = sock->lastdata.netbuf;
@@ -1394,6 +1396,18 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16
     sock->lastdata.netbuf = NULL;
     netbuf_delete(buf);
   }
+#else /* GAZELLE_ENABLE */
+  LWIP_UNUSED_ARG(copylen);
+  LWIP_UNUSED_ARG(buf);
+  LWIP_UNUSED_ARG(err);
+  LWIP_UNUSED_ARG(copied);
+  LWIP_UNUSED_ARG(i);
+  buflen = read_lwip_data(sock, flags, apiflags);
+  if (buflen <= 0) {
+    return ERR_BUF;
+  }
+
+#endif /* GAZELLE_ENABLE */
   if (datagram_len) {
     *datagram_len = buflen;
   }
@@ -1451,6 +1465,7 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
       done_socket(sock);
       return -1;
     }
+
     ret = (ssize_t)LWIP_MIN(LWIP_MIN(len, datagram_len), SSIZE_MAX);
     if (fromlen) {
       *fromlen = msg.msg_namelen;
@@ -3998,6 +4013,10 @@ lwip_ioctl(int s, long cmd, ...)
   struct lwip_sock *sock = posix_api->get_socket(s);
   u8_t val;
 
+#if LWIP_SO_RCVBUF
+  int recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+
   int ret = -1;
   void *argp;
   va_list ap;
diff --git a/src/core/dir.mk b/src/core/dir.mk
index ebc01a5..57a9670 100644
--- a/src/core/dir.mk
+++ b/src/core/dir.mk
@@ -1,6 +1,6 @@
 SRC = def.c inet_chksum.c init.c ip.c mem.c memp.c netif.c pbuf.c \
 	  raw.c tcp.c tcp_in.c tcp_out.c timeouts.c udp.c stats.c\
 	  ipv4/icmp.c ipv4/ip4_addr.c ipv4/ip4_frag.c ipv4/etharp.c \
-	  ipv4/ip4.c
+	  ipv4/ip4.c ipv4/igmp.c
 
 $(eval $(call register_dir, core, $(SRC)))
diff --git a/src/core/udp.c b/src/core/udp.c
index 24fc174..8a01c76 100644
--- a/src/core/udp.c
+++ b/src/core/udp.c
@@ -65,6 +65,12 @@
 
 #include <string.h>
 
+#if GAZELLE_ENABLE
+#include "lwipsock.h"
+#include <rte_prefetch.h>
+#include "dpdk_cksum.h"
+#endif
+
 #ifndef UDP_LOCAL_PORT_RANGE_START
 /* From http://www.iana.org/assignments/port-numbers:
    "The Dynamic and/or Private Ports are those from 49152 through 65535" */
@@ -210,7 +216,7 @@ udp_input(struct pbuf *p, struct netif *inp)
 #if LWIP_RECORD_PERF
   PERF_START(PERF_LAYER_UDP, PERF_POINT_UDP);
 #else
-  PERF_START;
+  //PERF_START;
 #endif
 
   UDP_STATS_INC(udp.recv);
@@ -435,7 +441,7 @@ end:
 #if LWIP_RECORD_PERF
   PERF_STOP_INCREASE_COUNT("udp_input", PERF_LAYER_UDP);
 #else
-  PERF_STOP("udp_input");
+  //PERF_STOP("udp_input");
 #endif
 
   return;
@@ -451,7 +457,7 @@ chkerr:
 #if LWIP_RECORD_PERF
   PERF_STOP_INCREASE_COUNT("udp_input", PERF_LAYER_UDP);
 #else
-  PERF_STOP("udp_input");
+  //PERF_STOP("udp_input");
 #endif
 
 #endif /* CHECKSUM_CHECK_UDP */
@@ -608,11 +614,26 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
     UDP_STATS_INC(udp.rterr);
     return ERR_RTE;
   }
+  uint8_t apiflags = 0;
+
+  struct pbuf *udp_pbuf = write_lwip_data((struct lwip_sock *)(p->payload), p->tot_len, &apiflags);
+  write_lwip_over((struct lwip_sock *)(p->payload));
+
+  pbuf_free(p);
+  p = udp_pbuf;
+  if (p == NULL) {
+    return ERR_MEM;
+  }
+
+  if (p->port) {
+    return udp_sendto_if(pcb, p, &(p->addr), p->port, netif);
+  } else {
 #if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP
   return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum);
 #else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
   return udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
 #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */
+  }
 }
 
 /**
@@ -905,6 +926,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
   LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto));
   /* output to IP */
   NETIF_SET_HINTS(netif, &(pcb->netif_hints));
+  udph_cksum_set(q, UDP_HLEN);
   err = ip_output_if_src(q, src_ip, dst_ip, ttl, pcb->tos, ip_proto, netif);
   NETIF_RESET_HINTS(netif);
 
diff --git a/src/include/dpdk_cksum.h b/src/include/dpdk_cksum.h
index df2e2a5..e41644b 100644
--- a/src/include/dpdk_cksum.h
+++ b/src/include/dpdk_cksum.h
@@ -82,6 +82,10 @@ static inline void tcph_cksum_set(struct pbuf *p, u16_t len) {
     p->ol_flags |= RTE_MBUF_F_TX_TCP_CKSUM;
 }
 
+static inline void udph_cksum_set(struct pbuf *p, u16_t len) {
+    p->l4_len = len;
+}
+
 static inline u16_t ip_chksum_pseudo_offload(u8_t proto, u16_t proto_len,
                                              const ip_addr_t *src, const ip_addr_t *dst)
 {
diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h
index 527f2d7..e61b3f1 100644
--- a/src/include/lwip/opt.h
+++ b/src/include/lwip/opt.h
@@ -133,6 +133,7 @@
  * MEMCPY: override this if you have a faster implementation at hand than the
  * one included in your C library
  */
+//#include <rte_memcpy.h>
 #if !defined MEMCPY || defined __DOXYGEN__
 #define MEMCPY(dst,src,len)             memcpy(dst,src,len)
 #endif
@@ -1123,7 +1124,7 @@
  * LWIP_IGMP==1: Turn on IGMP module.
  */
 #if !defined LWIP_IGMP || defined __DOXYGEN__
-#define LWIP_IGMP                       0
+#define LWIP_IGMP                       1
 #endif
 #if !LWIP_IPV4
 #undef LWIP_IGMP
@@ -2092,7 +2093,7 @@
  * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
  */
 #if !defined LWIP_SO_RCVBUF || defined __DOXYGEN__
-#define LWIP_SO_RCVBUF                  0
+#define LWIP_SO_RCVBUF                  1
 #endif
 
 /**
diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h
index 46ff26a..e08d4fa 100644
--- a/src/include/lwip/pbuf.h
+++ b/src/include/lwip/pbuf.h
@@ -40,6 +40,8 @@
 
 #include "lwip/opt.h"
 #include "lwip/err.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip6_addr.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -236,6 +238,8 @@ struct pbuf {
   struct pbuf *last;
   pthread_spinlock_t pbuf_lock;
   struct tcp_pcb *pcb;
+  ip_addr_t addr;
+  u16_t port;
 #endif /* GAZELLE_ENABLE CHECKSUM_OFFLOAD_SWITCH */
 
   /** In case the user needs to store data custom data on a pbuf */
diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h
index 8e41155..a7cec29 100644
--- a/src/include/lwip/sockets.h
+++ b/src/include/lwip/sockets.h
@@ -52,6 +52,7 @@
 #include "lwip/err.h"
 #include "lwip/inet.h"
 #include "lwip/errno.h"
+#include "lwip/api.h"
 
 #include <string.h>
 
@@ -332,20 +333,31 @@ struct linger {
 
 
 #if LWIP_MULTICAST_TX_OPTIONS
+#if GAZELLE_ENABLE
+#define IP_MULTICAST_IF 32
+#define IP_MULTICAST_TTL 33
+#define IP_MULTICAST_LOOP 34
+#else
 /*
  * Options and types for UDP multicast traffic handling
  */
 #define IP_MULTICAST_TTL   5
 #define IP_MULTICAST_IF    6
 #define IP_MULTICAST_LOOP  7
+#endif /* GAZELLE_ENABLE */
 #endif /* LWIP_MULTICAST_TX_OPTIONS */
 
 #if LWIP_IGMP
+#if GAZELLE_ENABLE
+#define IP_ADD_MEMBERSHIP  35
+#define IP_DROP_MEMBERSHIP 36
+#else
 /*
  * Options and types related to multicast membership
  */
 #define IP_ADD_MEMBERSHIP  3
 #define IP_DROP_MEMBERSHIP 4
+#endif /* GAZELLE_ENABLE */
 
 typedef struct ip_mreq {
     struct in_addr imr_multiaddr; /* IP multicast address of group */
@@ -675,6 +687,7 @@ ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags,
 int lwip_socket(int domain, int type, int protocol);
 ssize_t lwip_write(int s, const void *dataptr, size_t size);
 ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt);
+
 #if LWIP_SOCKET_SELECT
 int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
                 struct timeval *timeout);
@@ -686,6 +699,8 @@ int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
 #if GAZELLE_ENABLE
 int lwip_ioctl(int s, long cmd, ...);
 int lwip_fcntl(int s, int cmd, int val);
+int lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port,
+                    struct sockaddr *from, socklen_t *fromlen);
 #else
 int lwip_ioctl(int s, long cmd, void *argp);
 int lwip_fcntl(int s, int cmd, int val);
diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h
index 5b6bf6e..abc3f15 100644
--- a/src/include/lwipopts.h
+++ b/src/include/lwipopts.h
@@ -169,7 +169,7 @@
    ---------- UDP options ----------
    ---------------------------------
 */
-#define LWIP_UDP 0
+#define LWIP_UDP 1
 
 /*
    ---------------------------------
-- 
2.33.0

