• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 1f0f3742019e2fa62ba1669c5a880fb63a3fee12 Mon Sep 17 00:00:00 2001
2From: jiangheng <jiangheng12@huawei.com>
3Date: Thu, 24 Feb 2022 20:08:46 +0800
4Subject: [PATCH] lstack support mysql mode
5
6---
7 src/api/api_msg.c                |  26 +--
8 src/api/posix_api.c              |   5 +-
9 src/api/sockets.c                | 350 ++-----------------------------
10 src/api/sys_arch.c               |  12 +-
11 src/core/tcp_out.c               |  13 ++
12 src/include/eventpoll.h          |   6 +-
13 src/include/lwip/priv/tcp_priv.h |   2 +-
14 src/include/lwip/sockets.h       |   2 +-
15 src/include/lwipsock.h           |  29 ++-
16 src/include/posix_api.h          |   2 +-
17 src/include/reg_sock.h           |   8 +-
18 11 files changed, 85 insertions(+), 370 deletions(-)
19
20diff --git a/src/api/api_msg.c b/src/api/api_msg.c
21index d5a738f..3072dd9 100644
22--- a/src/api/api_msg.c
23+++ b/src/api/api_msg.c
24@@ -342,6 +342,12 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
25 #endif /* LWIP_SO_RCVBUF */
26     /* Register event with callback */
27     API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
28+#if USE_LIBOS
29+  if (conn->state == NETCONN_WRITE || conn->state == NETCONN_CLOSE ||
30+      conn->state == NETCONN_CONNECT) {
31+    add_recv_list(conn->socket);
32+  }
33+#endif
34   }
35
36   return ERR_OK;
37@@ -457,14 +463,6 @@ err_tcp(void *arg, err_t err)
38   old_state = conn->state;
39   conn->state = NETCONN_NONE;
40
41-#if USE_LIBOS
42-  if (CONN_TYPE_IS_HOST(conn)) {
43-    LWIP_DEBUGF(API_MSG_DEBUG,
44-        ("linux localhost connection already success, ignore lwip err_tcp fd=%d\n", conn->socket));
45-    return;
46-  }
47-#endif /* USE_LIBOS */
48-
49   SYS_ARCH_UNPROTECT(lev);
50
51   /* Notify the user layer about a connection error. Used to signal select. */
52@@ -479,6 +477,12 @@ err_tcp(void *arg, err_t err)
53   if (NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
54     /* use trypost to prevent deadlock */
55     sys_mbox_trypost(&conn->recvmbox, mbox_msg);
56+#if USE_LIBOS
57+    if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
58+        (old_state == NETCONN_CONNECT)) {
59+      add_recv_list(conn->socket);
60+    }
61+#endif
62   }
63   /* pass error message to acceptmbox to wake up pending accept */
64   if (NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) {
65@@ -1344,11 +1348,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
66     int s = conn->socket;
67     struct lwip_sock *sock = get_socket_without_errno(s);
68
69-    if (!!sock && !!sock->epoll_data) {
70-      struct epoll_event ee = {0};
71-      ee.data.fd = s;
72-      ee.events |= EPOLLIN | EPOLLOUT | EPOLLERR;
73-      posix_api->epoll_ctl_fn(sock->epoll_data->fd, EPOLL_CTL_DEL, s, &ee);
74+    if (!!sock) {
75       posix_api->shutdown_fn(s, SHUT_RDWR);
76       LWIP_DEBUGF(API_MSG_DEBUG,
77           ("linux outgoing connection abort fd=%d\n", s));
78diff --git a/src/api/posix_api.c b/src/api/posix_api.c
79index a917cea..eff9f46 100644
80--- a/src/api/posix_api.c
81+++ b/src/api/posix_api.c
82@@ -143,11 +143,10 @@ int posix_api_init(void)
83
84     /* lstack helper api */
85     posix_api->get_socket = get_socket;
86-    posix_api->is_epfd = lwip_is_epfd;
87-    posix_api->epoll_close_fn = lwip_epoll_close;
88+    posix_api->epoll_close_fn = lstack_epoll_close;
89
90     /* support fork */
91-    posix_api->is_chld = 0;
92+    posix_api->is_chld = 1;
93     return ERR_OK;
94
95 err_out:
96diff --git a/src/api/sockets.c b/src/api/sockets.c
97index f44c34f..b032ce9 100644
98--- a/src/api/sockets.c
99+++ b/src/api/sockets.c
100@@ -90,14 +90,6 @@
101 #define API_SELECT_CB_VAR_ALLOC(name, retblock)   API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock)
102 #define API_SELECT_CB_VAR_FREE(name)              API_VAR_FREE(MEMP_SELECT_CB, name)
103
104-#if USE_LIBOS
105-enum KERNEL_LWIP_PATH {
106-  PATH_KERNEL = 0,
107-  PATH_LWIP,
108-  PATH_ERR,
109-};
110-#endif
111-
112 #if LWIP_IPV4
113 #if USE_LIBOS
114 #define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \
115@@ -604,8 +596,6 @@ alloc_socket(struct netconn *newconn, int accepted)
116      * (unless it has been created by accept()). */
117     sockets[i].sendevent  = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
118     sockets[i].errevent   = 0;
119-    sockets[i].epoll_data = NULL;
120-    init_list_node_null(&sockets[i].list);
121     return i + LWIP_SOCKET_OFFSET;
122   }
123
124@@ -714,13 +704,6 @@ free_socket(struct lwip_sock *sock, int is_tcp)
125   /* Protect socket array */
126   SYS_ARCH_PROTECT(lev);
127
128-#if USE_LIBOS
129-  sock->epoll = LIBOS_EPOLLNONE;
130-  sock->events = 0;
131-  sock->epoll_data = NULL;
132-  list_del_node_null(&sock->list);
133-#endif
134-
135   freed = free_socket_locked(sock, is_tcp, &conn, &lastdata);
136   SYS_ARCH_UNPROTECT(lev);
137   /* don't use 'sock' after this line, as another task might have allocated it */
138@@ -749,34 +732,11 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
139   SYS_ARCH_DECL_PROTECT(lev);
140
141   LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
142-#if USE_LIBOS
143-  int sys_errno = 0;
144-
145-  sock = posix_api->get_socket(s);
146-  /*AF_UNIX case*/
147-  if (!sock) {
148-    return posix_api->accept_fn(s, addr, addrlen);
149-  }
150-
151-  /*for AF_INET, we may try both linux and lwip*/
152-  if (!CONN_TYPE_HAS_LIBOS_AND_HOST(sock->conn)) {
153-    LWIP_DEBUGF(SOCKETS_DEBUG, ("conn->type has libos and host bits"));
154-    set_errno(EINVAL);
155-    return -1;
156-  }
157-
158-  /* raise accept syscall in palce */
159-  newsock = posix_api->accept_fn(s, addr, addrlen);
160-  if (newsock >= 0) {
161-    return newsock;
162-  }
163-  sys_errno = errno;
164-#else
165+
166   sock = get_socket(s);
167   if (!sock) {
168     return -1;
169   }
170-#endif
171
172   /* wait for a new connection */
173   err = netconn_accept(sock->conn, &newconn);
174@@ -790,9 +750,6 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
175       sock_set_errno(sock, err_to_errno(err));
176     }
177     done_socket(sock);
178-#if USE_LIBOS
179-    set_errno(sys_errno);
180-#endif /* USE_LIBOS */
181     return -1;
182   }
183   LWIP_ASSERT("newconn != NULL", newconn != NULL);
184@@ -875,24 +832,11 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
185   ip_addr_t local_addr;
186   u16_t local_port;
187   err_t err;
188-#if USE_LIBOS
189-  sock = posix_api->get_socket(s);
190-  /*AF_UNIX case*/
191-  if (!sock) {
192-    return posix_api->bind_fn(s, name, namelen);
193-  }
194-  /*for AF_INET, we may try both linux and lwip*/
195-  if (!CONN_TYPE_HAS_LIBOS_AND_HOST(sock->conn)) {
196-    LWIP_DEBUGF(SOCKETS_DEBUG, ("conn->type has libos and host bits"));
197-    set_errno(EINVAL);
198-    return -1;
199-  }
200-#else
201+
202   sock = get_socket(s);
203   if (!sock) {
204     return -1;
205   }
206-#endif
207
208   if (!SOCK_ADDR_TYPE_MATCH(name, sock)) {
209     /* sockaddr does not match socket type (IPv4/IPv6) */
210@@ -912,18 +856,6 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
211   ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr);
212   LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port));
213
214-#if USE_LIBOS
215-  /* Supports kernel NIC IP address. */
216-  int ret = posix_api->bind_fn(s, name, namelen);
217-  if (ret < 0) {
218-    LWIP_DEBUGF(SOCKETS_DEBUG, ("bind syscall failed\n"));
219-    /* bind must succeed on both linux and libos */
220-    if (!is_host_ipv4(local_addr.addr)) {
221-      return ret;
222-    }
223-  }
224-#endif /* USE_LIBOS */
225-
226 #if LWIP_IPV4 && LWIP_IPV6
227   /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
228   if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) {
229@@ -953,32 +885,13 @@ lwip_close(int s)
230   struct lwip_sock *sock;
231   int is_tcp = 0;
232   err_t err;
233-  int ret = 0;
234
235   LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
236
237-#if USE_LIBOS
238-  if (posix_api->is_epfd(s)) {
239-    return posix_api->epoll_close_fn(s);
240-  }
241-
242-  /* No matter what the result of close, lwip_sock resources should release
243-   * to prevent the potential double freee problem caused by reporting events after the close */
244-  ret = posix_api->close_fn(s);
245-  if ((ret < 0) && (errno == EINTR))
246-    ret = posix_api->close_fn(s);
247-
248-  sock = posix_api->get_socket(s);
249-  /*AF_UNIX case*/
250-  if (!sock) {
251-    return ret;
252-  }
253-#else
254   sock = get_socket(s);
255   if (!sock) {
256     return -1;
257   }
258-#endif /* USE_LIBOS */
259
260   if (sock->conn != NULL) {
261     is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP;
262@@ -1004,7 +917,7 @@ lwip_close(int s)
263
264   free_socket(sock, is_tcp);
265   set_errno(0);
266-  return ret;
267+  return 0;
268 }
269
270 int
271@@ -1013,28 +926,10 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
272   struct lwip_sock *sock;
273   err_t err;
274
275-#if USE_LIBOS
276-  int ret;
277-
278-  sock = posix_api->get_socket(s);
279-  if (!sock) {
280-    return posix_api->connect_fn(s, name, namelen);
281-  }
282-
283-  /* raise connect syscall in place */
284-  ADD_CONN_TYPE_INPRG(sock->conn);
285-  ret = posix_api->connect_fn(s, name, namelen);
286-  if (!ret) {
287-    SET_CONN_TYPE_HOST(sock->conn);
288-    LWIP_DEBUGF(SOCKETS_DEBUG, ("linux connect succeed fd=%d\n", s));
289-    return ret;
290-  }
291-#else
292   sock = get_socket(s);
293   if (!sock) {
294     return -1;
295   }
296-#endif
297
298   if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) {
299     /* sockaddr does not match socket type (IPv4/IPv6) */
300@@ -1106,29 +1001,10 @@ lwip_listen(int s, int backlog)
301
302   LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
303
304-#if USE_LIBOS
305-  int ret;
306-
307-  sock = posix_api->get_socket(s);
308-  /*AF_UNIX case*/
309-  if (!sock) {
310-    return posix_api->listen_fn(s, backlog);
311-  }
312-  /*for AF_INET, we may try both linux and lwip*/
313-  if (!CONN_TYPE_HAS_LIBOS_AND_HOST(sock->conn)) {
314-    LWIP_DEBUGF(SOCKETS_DEBUG, ("conn->type has libos and host bits"));
315-    set_errno(EADDRINUSE);
316-    return -1;
317-  }
318-
319-  if ((ret = posix_api->listen_fn(s, backlog)) == -1)
320-    return ret;
321-#else
322   sock = get_socket(s);
323   if (!sock) {
324     return -1;
325   }
326-#endif
327
328   /* limit the "backlog" parameter to fit in an u8_t */
329   backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff);
330@@ -1160,11 +1036,12 @@ static ssize_t
331 lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
332 {
333   u8_t apiflags = NETCONN_NOAUTORCVD;
334+  ssize_t recvd = 0;
335 #if USE_LIBOS
336   apiflags = 0;
337-#endif
338-  ssize_t recvd = 0;
339+#else
340   ssize_t recv_left = (len <= SSIZE_MAX) ? (ssize_t)len : SSIZE_MAX;
341+#endif
342
343   LWIP_ASSERT("no socket given", sock != NULL);
344   LWIP_ASSERT("this should be checked internally", NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP);
345@@ -1173,6 +1050,7 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
346     apiflags |= NETCONN_DONTBLOCK;
347   }
348
349+#if !USE_LIBOS
350   do {
351     struct pbuf *p;
352     err_t err;
353@@ -1182,13 +1060,6 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
354     /* Check if there is data left from the last recv operation. */
355     if (sock->lastdata.pbuf) {
356       p = sock->lastdata.pbuf;
357-#if USE_LIBOS
358-      if (((flags & MSG_PEEK) == 0) && ((sock->epoll & EPOLLET) == 0)) {
359-        if ((NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP)) {
360-          del_epoll_event(sock->conn, EPOLLIN);
361-        }
362-      }
363-#endif
364     } else {
365       /* No data was left from the previous operation, so we try to get
366          some from the network. */
367@@ -1258,23 +1129,21 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
368     apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN;
369     /* @todo: do we need to support peeking more than one pbuf? */
370   } while ((recv_left > 0) && !(flags & MSG_PEEK));
371+
372 lwip_recv_tcp_done:
373-#if USE_LIBOS
374-  if (apiflags & NETCONN_NOAUTORCVD)
375-#endif
376-  {
377+#else /* USE_LIBOS */
378+  recvd = read_lwip_data(sock, flags, apiflags);
379+  if (recvd <= 0) {
380+    return recvd;
381+  }
382+#endif /* USE_LIBOS */
383+  if (apiflags & NETCONN_NOAUTORCVD) {
384     if ((recvd > 0) && !(flags & MSG_PEEK)) {
385       /* ensure window update after copying all data */
386       netconn_tcp_recvd(sock->conn, (size_t)recvd);
387     }
388   }
389-#if USE_LIBOS
390-  if ((flags & MSG_PEEK) == 0) {
391-    if (((NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP)) && sock->lastdata.pbuf) {
392-      add_epoll_event(sock->conn, EPOLLIN);
393-    }
394-  }
395-#endif
396+
397   sock_set_errno(sock, 0);
398   return recvd;
399 }
400@@ -1461,37 +1330,6 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16
401   return ERR_OK;
402 }
403
404-#if USE_LIBOS
405-static inline enum KERNEL_LWIP_PATH select_path(int s)
406-{
407-  struct lwip_sock *sock;
408-
409-  sock = posix_api->get_socket(s);
410-  /*AF_UNIX case*/
411-  if (!sock) {
412-    return PATH_KERNEL;
413-  }
414-
415-  if (CONN_TYPE_HAS_INPRG(sock->conn)) {
416-    set_errno(EWOULDBLOCK);
417-    return PATH_ERR;
418-  }
419-
420-  /*for AF_INET, we can try erther linux or lwip*/
421-  if (CONN_TYPE_IS_HOST(sock->conn)) {
422-    return PATH_KERNEL;
423-  }
424-
425-  if (!CONN_TYPE_IS_LIBOS(sock->conn)) {
426-    LWIP_DEBUGF(SOCKETS_DEBUG, ("conn->type is not libos bit type=%x", netconn_type(sock->conn)));
427-    set_errno(EINVAL);
428-    return PATH_ERR;
429-  }
430-
431-  return PATH_LWIP;
432-}
433-#endif
434-
435 ssize_t
436 lwip_recvfrom(int s, void *mem, size_t len, int flags,
437               struct sockaddr *from, socklen_t *fromlen)
438@@ -1499,15 +1337,6 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
439   struct lwip_sock *sock;
440   ssize_t ret;
441
442-#if USE_LIBOS
443-  enum KERNEL_LWIP_PATH path = select_path(s);
444-  if (path == PATH_ERR) {
445-    return -1;
446-  } else if (path == PATH_KERNEL) {
447-    return posix_api->recv_from(s, mem, len, flags, from, fromlen);
448-  }
449-#endif
450-
451   LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags));
452   sock = get_socket(s);
453   if (!sock) {
454@@ -1557,14 +1386,6 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
455 ssize_t
456 lwip_read(int s, void *mem, size_t len)
457 {
458-#if USE_LIBOS
459-  enum KERNEL_LWIP_PATH path = select_path(s);
460-  if (path == PATH_ERR) {
461-    return -1;
462-  } else if (path == PATH_KERNEL) {
463-    return posix_api->read_fn(s, mem, len);
464-  }
465-#endif
466   return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
467 }
468
469@@ -1598,15 +1419,6 @@ lwip_recvmsg(int s, struct msghdr *message, int flags)
470   int i;
471   ssize_t buflen;
472
473-#if USE_LIBOS
474-  enum KERNEL_LWIP_PATH path = select_path(s);
475-  if (path == PATH_ERR) {
476-    return -1;
477-  } else if (path == PATH_KERNEL) {
478-    return posix_api->recv_msg(s, message, flags);
479-  }
480-#endif
481-
482   LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags));
483   LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;);
484   LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK|MSG_DONTWAIT)) == 0,
485@@ -1751,15 +1563,6 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags)
486 #endif
487   err_t err = ERR_OK;
488
489-#if USE_LIBOS
490-  enum KERNEL_LWIP_PATH path = select_path(s);
491-  if (path == PATH_ERR) {
492-    return -1;
493-  } else if (path == PATH_KERNEL) {
494-    return posix_api->send_msg(s, msg, flags);
495-  }
496-#endif
497-
498   sock = get_socket(s);
499   if (!sock) {
500     return -1;
501@@ -1923,15 +1726,6 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
502   u16_t remote_port;
503   struct netbuf buf;
504
505-#if USE_LIBOS
506-  enum KERNEL_LWIP_PATH path = select_path(s);
507-  if (path == PATH_ERR) {
508-    return -1;
509-  } else if (path == PATH_KERNEL) {
510-    return posix_api->send_to(s, data, size, flags, to, tolen);
511-  }
512-#endif
513-
514   sock = get_socket(s);
515   if (!sock) {
516     return -1;
517@@ -2030,11 +1824,6 @@ lwip_socket(int domain, int type, int protocol)
518
519   LWIP_UNUSED_ARG(domain); /* @todo: check this */
520
521-#if USE_LIBOS
522-  if ((domain != AF_INET && domain != AF_UNSPEC) || posix_api->is_chld)
523-    return posix_api->socket_fn(domain, type, protocol);
524-#endif
525-
526   /* create a netconn */
527   switch (type) {
528     case SOCK_RAW:
529@@ -2091,14 +1880,6 @@ lwip_socket(int domain, int type, int protocol)
530 ssize_t
531 lwip_write(int s, const void *data, size_t size)
532 {
533-#if USE_LIBOS
534-  enum KERNEL_LWIP_PATH path = select_path(s);
535-  if (path == PATH_ERR) {
536-    return -1;
537-  } else if (path == PATH_KERNEL) {
538-    return posix_api->write_fn(s, data, size);
539-  }
540-#endif
541   return lwip_send(s, data, size, 0);
542 }
543
544@@ -2884,20 +2665,16 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
545         check_waiters = 0;
546       }
547 #if USE_LIBOS
548-      if (sock->epoll & EPOLLET) {
549-        list_del_node_null(&sock->list);
550+      if (conn->state == NETCONN_LISTEN) {
551+        add_epoll_event(conn, EPOLLIN);
552+      } else {
553+        add_recv_list(conn->socket);
554       }
555-      add_epoll_event(conn, EPOLLIN);
556 #endif
557       break;
558     case NETCONN_EVT_RCVMINUS:
559       sock->rcvevent--;
560       check_waiters = 0;
561-#if USE_LIBOS
562-      if ((sock->epoll & EPOLLET) == 0) {
563-        del_epoll_event(conn, EPOLLIN);
564-      }
565-#endif
566       break;
567     case NETCONN_EVT_SENDPLUS:
568       if (sock->sendevent) {
569@@ -2905,27 +2682,16 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
570       }
571       sock->sendevent = 1;
572 #if USE_LIBOS
573-      if (sock->epoll & EPOLLET) {
574-        list_del_node_null(&sock->list);
575-      }
576       add_epoll_event(conn, EPOLLOUT);
577 #endif
578       break;
579     case NETCONN_EVT_SENDMINUS:
580       sock->sendevent = 0;
581       check_waiters = 0;
582-#if USE_LIBOS
583-      if ((sock->epoll & EPOLLET) == 0) {
584-        del_epoll_event(conn, EPOLLOUT);
585-      }
586-#endif
587       break;
588     case NETCONN_EVT_ERROR:
589       sock->errevent = 1;
590 #if USE_LIBOS
591-      if (sock->epoll & EPOLLET) {
592-        list_del_node_null(&sock->list);
593-      }
594       add_epoll_event(conn, EPOLLERR);
595 #endif
596       break;
597@@ -3139,41 +2905,12 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
598 int
599 lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
600 {
601-#if USE_LIBOS
602-  struct lwip_sock *sock;
603-
604-  sock = posix_api->get_socket(s);
605-  if (!sock) {
606-    return posix_api->getpeername_fn(s, name, namelen);
607-  }
608-  /*for AF_INET, if has only host type bit, just call linux api,
609-   *if has libos and host type bits, it's a not connected fd, call
610-   *linux api and return -1(errno == ENOTCONN) is also ok*/
611-  if (CONN_TYPE_HAS_HOST(sock->conn)) {
612-    return posix_api->getpeername_fn(s, name, namelen);
613-  }
614-#endif
615-
616   return lwip_getaddrname(s, name, namelen, 0);
617 }
618
619 int
620 lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
621 {
622-#if USE_LIBOS
623-  struct lwip_sock *sock;
624-
625-  sock = posix_api->get_socket(s);
626-  if (!sock) {
627-    return posix_api->getsockname_fn(s, name, namelen);
628-  }
629-  /*for AF_INET, if has only host type bit, just call linux api,
630-   *if has libos and host type bits, also call linux api*/
631-  if (CONN_TYPE_HAS_HOST(sock->conn)) {
632-    return posix_api->getsockname_fn(s, name, namelen);
633-  }
634-#endif
635-
636   return lwip_getaddrname(s, name, namelen, 1);
637 }
638
639@@ -3186,23 +2923,11 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
640   LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
641 #endif /* !LWIP_TCPIP_CORE_LOCKING */
642
643-#if USE_LIBOS
644-  struct lwip_sock *sock = posix_api->get_socket(s);
645-
646-  if (!sock) {
647-    return posix_api->getsockopt_fn(s, level, optname, optval, optlen);
648-  }
649-  /*for AF_INET, we return linux result? */
650-  if (CONN_TYPE_HAS_HOST(sock->conn)) {
651-    return posix_api->getsockopt_fn(s, level, optname, optval, optlen);
652-  }
653-#else
654   struct lwip_sock *sock = get_socket(s);
655
656   if (!sock) {
657     return -1;
658   }
659-#endif /* USE_LIBOS */
660
661   if ((NULL == optval) || (NULL == optlen)) {
662     sock_set_errno(sock, EFAULT);
663@@ -3645,25 +3370,11 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
664   LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
665 #endif /* !LWIP_TCPIP_CORE_LOCKING */
666
667-#if USE_LIBOS
668-  struct lwip_sock *sock = posix_api->get_socket(s);
669-
670-  if (!sock) {
671-    return posix_api->setsockopt_fn(s, level, optname, optval, optlen);
672-  }
673-  /*for AF_INET, we may try both linux and lwip*/
674-  if (CONN_TYPE_HAS_HOST(sock->conn)) {
675-    if (posix_api->setsockopt_fn(s, level, optname, optval, optlen) < 0) {
676-      return -1;
677-    }
678-  }
679-#else
680   struct lwip_sock *sock = get_socket(s);
681
682   if (!sock) {
683     return -1;
684   }
685-#endif /* USE_LIBOS */
686
687   if (NULL == optval) {
688     sock_set_errno(sock, EFAULT);
689@@ -4308,26 +4019,6 @@ lwip_ioctl(int s, long cmd, void *argp)
690  * the flag O_NONBLOCK is implemented for F_SETFL.
691  */
692 int
693-#if USE_LIBOS
694-lwip_fcntl(int s, int cmd, ...)
695-{
696-  struct lwip_sock *sock = posix_api->get_socket(s);
697-  int val, ret = -1;
698-  int op_mode = 0;
699-  va_list ap;
700-
701-  va_start(ap, cmd);
702-  val = va_arg(ap, int);
703-  va_end(ap);
704-
705-  if (!sock) {
706-    return posix_api->fcntl_fn(s, cmd, val);
707-  }
708-  if (CONN_TYPE_HAS_HOST(sock->conn)) {
709-    if ((ret = posix_api->fcntl_fn(s, cmd, val)) == -1)
710-      return ret;
711-  }
712-#else /* USE_LIBOS */
713 lwip_fcntl(int s, int cmd, int val)
714 {
715   struct lwip_sock *sock = get_socket(s);
716@@ -4337,7 +4028,6 @@ lwip_fcntl(int s, int cmd, int val)
717   if (!sock) {
718     return -1;
719   }
720-#endif /* USE_LIBOS */
721
722   switch (cmd) {
723     case F_GETFL:
724diff --git a/src/api/sys_arch.c b/src/api/sys_arch.c
725index 55561b1..9a92143 100644
726--- a/src/api/sys_arch.c
727+++ b/src/api/sys_arch.c
728@@ -76,8 +76,8 @@ struct sys_mem_stats {
729
730 static PER_THREAD struct sys_mem_stats hugepage_stats;
731
732-static PER_THREAD uint64_t cycles_per_ms __attribute__((aligned(64)));
733-static PER_THREAD uint64_t sys_start_ms __attribute__((aligned(64)));
734+static uint64_t cycles_per_ms __attribute__((aligned(64)));
735+static uint64_t sys_start_ms __attribute__((aligned(64)));
736
737 /*
738  * Mailbox
739@@ -337,8 +337,12 @@ void sys_calibrate_tsc(void)
740 #define MS_PER_SEC  1E3
741     uint64_t freq = rte_get_tsc_hz();
742
743-    cycles_per_ms = (freq + MS_PER_SEC - 1) / MS_PER_SEC;
744-    sys_start_ms = rte_rdtsc() / cycles_per_ms;
745+    if (cycles_per_ms == 0) {
746+        cycles_per_ms = (freq + MS_PER_SEC - 1) / MS_PER_SEC;
747+    }
748+    if (sys_start_ms == 0) {
749+        sys_start_ms = rte_rdtsc() / cycles_per_ms;
750+    }
751 }
752
753 uint32_t sys_now(void)
754diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c
755index dac498e..b99974d 100644
756--- a/src/core/tcp_out.c
757+++ b/src/core/tcp_out.c
758@@ -472,6 +472,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
759    * pos records progress as data is segmented.
760    */
761
762+#if !USE_LIBOS
763   /* Find the tail of the unsent queue. */
764   if (pcb->unsent != NULL) {
765     u16_t space;
766@@ -587,6 +588,13 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
767                 pcb->unsent_oversize == 0);
768 #endif /* TCP_OVERSIZE */
769   }
770+#else /* USE_LIBOS */
771+  if (pcb->unsent != NULL) {
772+    /* @todo: this could be sped up by keeping last_unsent in the pcb */
773+    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
774+         last_unsent = last_unsent->next);
775+  }
776+#endif /* USE_LIBOS */
777
778   /*
779    * Phase 3: Create new segments.
780@@ -604,6 +612,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
781     u8_t chksum_swapped = 0;
782 #endif /* TCP_CHECKSUM_ON_COPY */
783
784+#if !USE_LIBOS
785     if (apiflags & TCP_WRITE_FLAG_COPY) {
786       /* If copy is set, memory should be allocated and data copied
787        * into pbuf */
788@@ -650,6 +659,10 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
789       /* Concatenate the headers and data pbufs together. */
790       pbuf_cat(p/*header*/, p2/*data*/);
791     }
792+#else  /* USE_LIBOS */
793+    p = (struct pbuf *)arg;
794+    seglen = p->len;
795+#endif  /* USE_LIBOS */
796
797     queuelen += pbuf_clen(p);
798
799diff --git a/src/include/eventpoll.h b/src/include/eventpoll.h
800index f525bc2..aacc1d2 100644
801--- a/src/include/eventpoll.h
802+++ b/src/include/eventpoll.h
803@@ -63,9 +63,7 @@ struct libos_epoll {
804     int efd; /* eventfd */
805 };
806
807-extern int add_epoll_event(struct netconn*, uint32_t);
808-extern int del_epoll_event(struct netconn*, uint32_t);
809-extern int lwip_epoll_close(int);
810-extern int lwip_is_epfd(int);
811+extern void add_epoll_event(struct netconn*, uint32_t);
812+extern int32_t lstack_epoll_close(int32_t);
813
814 #endif /* __EVENTPOLL_H__ */
815diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h
816index f771725..83208bf 100644
817--- a/src/include/lwip/priv/tcp_priv.h
818+++ b/src/include/lwip/priv/tcp_priv.h
819@@ -349,7 +349,7 @@ static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pc
820 {
821   LWIP_ASSERT("Invalid parameter", pcb != NULL);
822
823-  struct libnet_quintuple qtuple;
824+  struct gazelle_quintuple qtuple;
825   qtuple.protocol   = 0;
826   qtuple.src_ip     = pcb->local_ip.addr;
827   qtuple.src_port   = lwip_htons(pcb->local_port);
828diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h
829index 345e26c..4e7e671 100644
830--- a/src/include/lwip/sockets.h
831+++ b/src/include/lwip/sockets.h
832@@ -647,7 +647,7 @@ int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
833
834 #if USE_LIBOS
835 int lwip_ioctl(int s, long cmd, ...);
836-int lwip_fcntl(int s, int cmd, ...);
837+int lwip_fcntl(int s, int cmd, int val);
838 #else
839 int lwip_ioctl(int s, long cmd, void *argp);
840 int lwip_fcntl(int s, int cmd, int val);
841diff --git a/src/include/lwipsock.h b/src/include/lwipsock.h
842index e9ffbb1..069cdcb 100644
843--- a/src/include/lwipsock.h
844+++ b/src/include/lwipsock.h
845@@ -60,6 +60,10 @@ union lwip_sock_lastdata {
846   struct pbuf *pbuf;
847 };
848
849+#if USE_LIBOS
850+struct protocol_stack;
851+struct weakup_poll;
852+#endif
853 /** Contains all internal pointers and states used for a socket */
854 struct lwip_sock {
855   /** sockets currently are built on netconns, each socket has one netconn */
856@@ -88,14 +92,19 @@ struct lwip_sock {
857 #endif
858
859 #if USE_LIBOS
860-  struct list_node list;
861-  /* registered events */
862-  uint32_t epoll;
863-  /* available events */
864-  uint32_t events;
865+  uint32_t epoll_events; /* registered events */
866+  uint32_t events; /* available events */
867+  int32_t in_event; /* avoid recurring events */
868   epoll_data_t ep_data;
869-  /* libos_epoll pointer in use */
870-  struct libos_epoll *epoll_data;
871+  struct weakup_poll *weakup;
872+  struct protocol_stack *stack;
873+  void *recv_ring;
874+  struct pbuf *recv_lastdata; /* unread data in one pbuf */
875+  struct pbuf *send_lastdata; /* unread data in one pbuf */
876+  void *send_ring;
877+  int32_t recv_flags;
878+  int32_t nextfd; /* listenfd list */
879+  struct list_node recv_list;
880 #endif
881 };
882
883@@ -138,6 +147,10 @@ get_socket_without_errno(int s)
884
885   return sock;
886 }
887+
888+extern void add_recv_list(int32_t fd);
889+extern ssize_t read_lwip_data(struct lwip_sock *sock, int32_t flags, u8_t apiflags);
890+extern void gazelle_clean_sock(int32_t fd);
891 #endif /* USE_LIBOS */
892
893 struct lwip_sock *get_socket(int s);
894@@ -145,6 +158,4 @@ struct lwip_sock *get_socket_by_fd(int s);
895 void lwip_sock_init(void);
896 void lwip_exit(void);
897
898-extern int is_host_ipv4(uint32_t ipv4);
899-
900 #endif /* __LWIPSOCK_H__ */
901diff --git a/src/include/posix_api.h b/src/include/posix_api.h
902index 0dca8eb..2afd266 100644
903--- a/src/include/posix_api.h
904+++ b/src/include/posix_api.h
905@@ -34,7 +34,7 @@
906 #define __POSIX_API_H__
907
908 #include <signal.h>
909-#include <poll.h>
910+#include <sys/poll.h>
911 #include <sys/epoll.h>
912 #include <sys/eventfd.h>
913
914diff --git a/src/include/reg_sock.h b/src/include/reg_sock.h
915index 76d4c48..76673da 100644
916--- a/src/include/reg_sock.h
917+++ b/src/include/reg_sock.h
918@@ -41,7 +41,7 @@ enum reg_ring_type {
919     RING_REG_MAX,
920 };
921
922-struct libnet_quintuple {
923+struct gazelle_quintuple {
924 	uint32_t protocol;
925     /* net byte order */
926     uint16_t src_port;
927@@ -54,9 +54,9 @@ struct reg_ring_msg {
928     enum reg_ring_type type;
929
930     uint32_t tid;
931-    struct libnet_quintuple qtuple;
932+    struct gazelle_quintuple qtuple;
933 };
934
935-extern int vdev_reg_xmit(enum reg_ring_type type, struct libnet_quintuple *qtuple);
936+extern int vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple);
937
938-#endif /* __REG_SOCK_H__ */
939\ No newline at end of file
940+#endif /* __REG_SOCK_H__ */
941--
9422.30.0
943
944