Projects
openEuler:22.03:LTS:SP3
gazelle
_service:tar_scm_kernel_repo:0018-preload-suppo...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm_kernel_repo:0018-preload-support-thread-hijacking-mode.patch of Package gazelle
From 7c6d623f4009ec40349504281b9af396d05418ec Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng14@huawei.com> Date: Mon, 9 Oct 2023 11:36:34 +0800 Subject: [PATCH] preload: support thread hijacking mode --- src/lstack/api/lstack_wrap.c | 208 ++++++++++------------------ src/lstack/core/lstack_cfg.c | 3 +- src/lstack/core/lstack_init.c | 2 +- src/lstack/core/lstack_preload.c | 114 ++++++++++++++- src/lstack/include/lstack_preload.h | 9 ++ 5 files changed, 202 insertions(+), 134 deletions(-) diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c index 236c689..ab39a68 100644 --- a/src/lstack/api/lstack_wrap.c +++ b/src/lstack/api/lstack_wrap.c @@ -40,73 +40,15 @@ #include "gazelle_base_func.h" #include "lstack_thread_rpc.h" +#include "lstack_preload.h" + #ifndef SOCK_TYPE_MASK #define SOCK_TYPE_MASK 0xf #endif -enum KERNEL_LWIP_PATH { - PATH_KERNEL = 0, - PATH_LWIP, - PATH_UNKNOW, -}; - -static inline enum KERNEL_LWIP_PATH select_path(int fd, struct lwip_sock **socket) -{ - if (unlikely(posix_api == NULL)) { - /* - * posix api maybe call before gazelle init - * So, we must call posix_api_init at the head of select_path - */ - if (posix_api_init() != 0) { - LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n"); - } - return PATH_KERNEL; - } - - if (unlikely(posix_api->ues_posix)) { - return PATH_KERNEL; - } - - struct lwip_sock *sock = get_socket_by_fd(fd); - - /* AF_UNIX case */ - if (!sock || !sock->conn || CONN_TYPE_IS_HOST(sock->conn)) { - return PATH_KERNEL; - } - - if (socket) { - *socket = sock; - } - - if (likely(CONN_TYPE_IS_LIBOS(sock->conn))) { - return PATH_LWIP; - } - - if (NETCONN_IS_UDP(sock)) { - return PATH_LWIP; - } else { - struct tcp_pcb *pcb = sock->conn->pcb.tcp; - /* after lwip connect, call send immediately, pcb->state is SYN_SENT, need return PATH_LWIP */ - /* pcb->state default value is CLOSED when call socket, need return PATH_UNKNOW */ - if (pcb != NULL && pcb->state <= ESTABLISHED && pcb->state >= LISTEN) { - return PATH_LWIP; - } - } - - return PATH_UNKNOW; -} - static inline int32_t do_epoll_create1(int32_t flags) { - if (posix_api == NULL) { - /* posix api maybe call before gazelle init */ - if (posix_api_init() != 0) { - LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n"); - } - return posix_api->epoll_create1_fn(flags); - } - - if (unlikely(posix_api->ues_posix)) { + if (select_posix_path() == PATH_KERNEL) { return posix_api->epoll_create1_fn(flags); } @@ -115,15 +57,7 @@ static inline int32_t do_epoll_create1(int32_t flags) static inline int32_t do_epoll_create(int32_t size) { - if (posix_api == NULL) { - /* posix api maybe call before gazelle init */ - if (posix_api_init() != 0) { - LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n"); - } - return posix_api->epoll_create_fn(size); - } - - if (unlikely(posix_api->ues_posix)) { + if (select_posix_path() == PATH_KERNEL) { return posix_api->epoll_create_fn(size); } @@ -132,7 +66,7 @@ static inline int32_t do_epoll_create(int32_t size) static inline int32_t do_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event* event) { - if (unlikely(posix_api->ues_posix)) { + if (select_posix_path() == PATH_KERNEL) { return posix_api->epoll_ctl_fn(epfd, op, fd, event); } @@ -141,7 +75,7 @@ static inline int32_t do_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct static inline int32_t do_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout) { - if (unlikely(posix_api->ues_posix)) { + if (select_posix_path() == PATH_KERNEL) { return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout); } @@ -158,8 +92,7 @@ static inline int32_t do_epoll_wait(int32_t epfd, struct epoll_event* events, in static inline int32_t do_accept(int32_t s, struct sockaddr *addr, socklen_t *addrlen) { - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_KERNEL) { + if (select_fd_posix_path(s, NULL) == PATH_KERNEL) { return posix_api->accept_fn(s, addr, addrlen); } @@ -177,8 +110,7 @@ static int32_t do_accept4(int32_t s, struct sockaddr *addr, socklen_t *addrlen, GAZELLE_RETURN(EINVAL); } - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_KERNEL) { + if (select_fd_posix_path(s, NULL) == PATH_KERNEL) { return posix_api->accept4_fn(s, addr, addrlen, flags); } @@ -219,22 +151,21 @@ static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen } struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_KERNEL) { + if (select_fd_posix_path(s, &sock) == PATH_KERNEL) { return posix_api->bind_fn(s, name, namelen); } - int32_t ret = posix_api->bind_fn(s, name, namelen); - if (ret < 0) { - /* ip is not lstack, just return */ - if (!match_host_addr(((struct sockaddr_in *)name)->sin_addr.s_addr)) { - return ret; + if (match_host_addr(((struct sockaddr_in *)name)->sin_addr.s_addr)) { + /* maybe kni addr */ + posix_api->bind_fn(s, name, namelen); + if (NETCONN_IS_UDP(sock) && get_global_cfg_params()->listen_shadow) { + return stack_broadcast_bind(s, name, namelen); + } else { + return stack_single_bind(s, name, namelen); } - } - - if (NETCONN_IS_UDP(sock) && get_global_cfg_params()->listen_shadow) { - return stack_broadcast_bind(s, name, namelen); } else { - return stack_single_bind(s, name, namelen); + SET_CONN_TYPE_HOST(sock->conn); + return posix_api->bind_fn(s, name, namelen); } } @@ -299,7 +230,7 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name } struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_KERNEL) { + if (select_fd_posix_path(s, &sock) == PATH_KERNEL) { return posix_api->connect_fn(s, name, namelen); } @@ -309,6 +240,7 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name } if (!netconn_is_nonblocking(sock->conn)) { + LSTACK_LOG(ERR, LSTACK, "connect does not support blocking fd currently\n"); GAZELLE_RETURN(EINVAL); } @@ -330,8 +262,7 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name static inline int32_t do_listen(int32_t s, int32_t backlog) { - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_KERNEL) { + if (select_fd_posix_path(s, NULL) == PATH_KERNEL) { return posix_api->listen_fn(s, backlog); } @@ -355,8 +286,7 @@ static inline int32_t do_getpeername(int32_t s, struct sockaddr *name, socklen_t GAZELLE_RETURN(EINVAL); } - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_LWIP) { + if (select_fd_posix_path(s, NULL) == PATH_LWIP) { return rpc_call_getpeername(s, name, namelen); } @@ -369,8 +299,7 @@ static inline int32_t do_getsockname(int32_t s, struct sockaddr *name, socklen_t GAZELLE_RETURN(EINVAL); } - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_LWIP) { + if (select_fd_posix_path(s, NULL) == PATH_LWIP) { return rpc_call_getsockname(s, name, namelen); } @@ -391,8 +320,7 @@ static bool unsupport_optname(int32_t optname) static inline int32_t do_getsockopt(int32_t s, int32_t level, int32_t optname, void *optval, socklen_t *optlen) { - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_LWIP && !unsupport_optname(optname)) { + if (select_fd_posix_path(s, NULL) == PATH_LWIP && !unsupport_optname(optname)) { return rpc_call_getsockopt(s, level, optname, optval, optlen); } @@ -401,8 +329,7 @@ static inline int32_t do_getsockopt(int32_t s, int32_t level, int32_t optname, v static inline int32_t do_setsockopt(int32_t s, int32_t level, int32_t optname, const void *optval, socklen_t optlen) { - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_KERNEL || unsupport_optname(optname)) { + if (select_fd_posix_path(s, NULL) == PATH_KERNEL || unsupport_optname(optname)) { return posix_api->setsockopt_fn(s, level, optname, optval, optlen); } @@ -417,13 +344,27 @@ static inline int32_t do_setsockopt(int32_t s, int32_t level, int32_t optname, c static inline int32_t do_socket(int32_t domain, int32_t type, int32_t protocol) { - if ((domain != AF_INET && domain != AF_UNSPEC) - || ((type & SOCK_DGRAM) && !get_global_cfg_params()->udp_enable) - || posix_api->ues_posix) { + int32_t ret; + /* process not init completed or not hajacking thread */ + if (select_posix_path() == PATH_KERNEL) { + return posix_api->socket_fn(domain, type, protocol); + } + + if ((domain != AF_INET && domain != AF_UNSPEC) || + ((type & SOCK_DGRAM) && !get_global_cfg_params()->udp_enable)) { return posix_api->socket_fn(domain, type, protocol); } - return rpc_call_socket(domain, type, protocol); + ret = rpc_call_socket(domain, type, protocol); + /* if udp_enable = 1 in lstack.conf, udp protocol must be in user path currently */ + if ((ret >= 0) && (type & SOCK_DGRAM)) { + struct lwip_sock *sock = get_socket(ret); + if (sock != NULL && sock->conn != NULL) { + SET_CONN_TYPE_LIBOS(sock->conn); + } + } + + return ret; } static inline ssize_t do_recv(int32_t sockfd, void *buf, size_t len, int32_t flags) @@ -436,12 +377,12 @@ static inline ssize_t do_recv(int32_t sockfd, void *buf, size_t len, int32_t fla return 0; } - struct lwip_sock *sock = NULL; - if (select_path(sockfd, &sock) == PATH_LWIP) { - return do_lwip_read_from_stack(sockfd, buf, len, flags, NULL, NULL); + if (select_posix_path() == PATH_KERNEL || // maybe fd is created by open before posix_api_init called + select_fd_posix_path(sockfd, NULL) == PATH_KERNEL) { + return posix_api->recv_fn(sockfd, buf, len, flags); } - return posix_api->recv_fn(sockfd, buf, len, flags); + return do_lwip_read_from_stack(sockfd, buf, len, flags, NULL, NULL); } static inline ssize_t do_read(int32_t s, void *mem, size_t len) @@ -454,17 +395,18 @@ static inline ssize_t do_read(int32_t s, void *mem, size_t len) return 0; } - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_LWIP) { - return do_lwip_read_from_stack(s, mem, len, 0, NULL, NULL); + if (select_posix_path() == PATH_KERNEL || + select_fd_posix_path(s, NULL) == PATH_KERNEL) { + return posix_api->read_fn(s, mem, len); } - return posix_api->read_fn(s, mem, len); + + return do_lwip_read_from_stack(s, mem, len, 0, NULL, NULL); } static inline ssize_t do_readv(int32_t s, const struct iovec *iov, int iovcnt) { - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) != PATH_LWIP) { + if (select_posix_path() == PATH_KERNEL || + select_fd_posix_path(s, NULL) == PATH_KERNEL) { return posix_api->readv_fn(s, iov, iovcnt); } @@ -487,8 +429,8 @@ static inline ssize_t do_readv(int32_t s, const struct iovec *iov, int iovcnt) static inline ssize_t do_send(int32_t sockfd, const void *buf, size_t len, int32_t flags) { - struct lwip_sock *sock = NULL; - if (select_path(sockfd, &sock) != PATH_LWIP) { + if (select_posix_path() == PATH_KERNEL || + select_fd_posix_path(sockfd, NULL) == PATH_KERNEL) { return posix_api->send_fn(sockfd, buf, len, flags); } @@ -497,8 +439,8 @@ static inline ssize_t do_send(int32_t sockfd, const void *buf, size_t len, int32 static inline ssize_t do_write(int32_t s, const void *mem, size_t size) { - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) != PATH_LWIP) { + if (select_posix_path() == PATH_KERNEL || + select_fd_posix_path(s, NULL) == PATH_KERNEL) { return posix_api->write_fn(s, mem, size); } @@ -507,8 +449,9 @@ static inline ssize_t do_write(int32_t s, const void *mem, size_t size) static inline ssize_t do_writev(int32_t s, const struct iovec *iov, int iovcnt) { - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) != PATH_LWIP) { + struct lwip_sock *sock; + if (select_posix_path() == PATH_KERNEL || + select_fd_posix_path(s, &sock) == PATH_KERNEL) { return posix_api->writev_fn(s, iov, iovcnt); } @@ -530,12 +473,12 @@ static inline ssize_t do_recvmsg(int32_t s, struct msghdr *message, int32_t flag GAZELLE_RETURN(EINVAL); } - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_LWIP) { - return do_lwip_recvmsg_from_stack(s, message, flags); + if (select_posix_path() == PATH_KERNEL || + select_fd_posix_path(s, NULL) == PATH_KERNEL) { + return posix_api->recv_msg(s, message, flags); } - return posix_api->recv_msg(s, message, flags); + return do_lwip_recvmsg_from_stack(s, message, flags); } static inline ssize_t do_sendmsg(int32_t s, const struct msghdr *message, int32_t flags) @@ -544,12 +487,13 @@ static inline ssize_t do_sendmsg(int32_t s, const struct msghdr *message, int32_ GAZELLE_RETURN(EINVAL); } - struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_LWIP) { - return do_lwip_sendmsg_to_stack(sock, s, message, flags); + struct lwip_sock *sock; + if (select_posix_path() == PATH_KERNEL || + select_fd_posix_path(s, &sock) == PATH_KERNEL) { + return posix_api->send_msg(s, message, flags); } - return posix_api->send_msg(s, message, flags); + return do_lwip_sendmsg_to_stack(sock, s, message, flags); } static inline ssize_t udp_recvfrom(struct lwip_sock *sock, int32_t sockfd, void *buf, size_t len, int32_t flags, @@ -596,7 +540,7 @@ static inline ssize_t do_recvfrom(int32_t sockfd, void *buf, size_t len, int32_t } struct lwip_sock *sock = NULL; - if (select_path(sockfd, &sock) == PATH_LWIP) { + if (select_fd_posix_path(sockfd, &sock) == PATH_LWIP) { if (NETCONN_IS_UDP(sock)) { return udp_recvfrom(sock, sockfd, buf, len, flags, addr, addrlen); } else { @@ -611,7 +555,7 @@ static inline ssize_t do_sendto(int32_t sockfd, const void *buf, size_t len, int const struct sockaddr *addr, socklen_t addrlen) { struct lwip_sock *sock = NULL; - if (select_path(sockfd, &sock) != PATH_LWIP) { + if (select_fd_posix_path(sockfd, &sock) != PATH_LWIP) { return posix_api->send_to(sockfd, buf, len, flags, addr, addrlen); } @@ -621,7 +565,8 @@ static inline ssize_t do_sendto(int32_t sockfd, const void *buf, size_t len, int static inline int32_t do_close(int32_t s) { struct lwip_sock *sock = NULL; - if (select_path(s, &sock) == PATH_KERNEL) { + if (select_posix_path() == PATH_KERNEL || + select_fd_posix_path(s, &sock) == PATH_KERNEL) { /* we called lwip_socket, even if kernel fd */ if (posix_api != NULL && !posix_api->ues_posix && /* contain posix_api->close_fn if success */ @@ -639,7 +584,7 @@ static inline int32_t do_close(int32_t s) static int32_t do_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout) { - if (unlikely(posix_api->ues_posix) || fds == NULL || nfds == 0) { + if ((select_posix_path() == PATH_KERNEL) || fds == NULL || nfds == 0) { return posix_api->poll_fn(fds, nfds, timeout); } @@ -684,7 +629,8 @@ static int32_t do_sigaction(int32_t signum, const struct sigaction *act, struct val = va_arg(ap, typeof(val)); \ va_end(ap); \ struct lwip_sock *sock = NULL; \ - if (select_path(_fd, &sock) == PATH_KERNEL) \ + if (select_posix_path() == PATH_KERNEL || \ + select_fd_posix_path(_fd, &sock) == PATH_KERNEL) \ return _fcntl_fn(_fd, _cmd, val); \ int32_t ret = _fcntl_fn(_fd, _cmd, val); \ if (ret == -1) \ diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c index 0eca86e..189459a 100644 --- a/src/lstack/core/lstack_cfg.c +++ b/src/lstack/core/lstack_cfg.c @@ -223,7 +223,8 @@ static int32_t parse_host_addr(void) int32_t match_host_addr(uint32_t addr) { /* network byte order */ - if (addr == g_config_params.host_addr.addr) { + if (addr == g_config_params.host_addr.addr || + addr == INADDR_ANY) { return 1; } return 0; diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c index 2183e3a..b6e9bf1 100644 --- a/src/lstack/core/lstack_init.c +++ b/src/lstack/core/lstack_init.c @@ -285,7 +285,7 @@ __attribute__((constructor)) void gazelle_network_init(void) } if (stack_thread_setup() != 0) { - LSTACK_EXIT(1, "stack_init_in_setup failed\n"); + LSTACK_EXIT(1, "stack_thread_setup failed\n"); } /* lwip initialization */ diff --git a/src/lstack/core/lstack_preload.c b/src/lstack/core/lstack_preload.c index e3a98fc..1d68501 100644 --- a/src/lstack/core/lstack_preload.c +++ b/src/lstack/core/lstack_preload.c @@ -12,8 +12,13 @@ #include <string.h> #include <stdlib.h> #include <unistd.h> +#define __USE_GNU +#include <pthread.h> +#include <securec.h> -#include "securec.h" +#include <lwip/posix_api.h> +#include <lwip/lwipsock.h> +#include <lwip/lwipopts.h> #include "lstack_log.h" #include "lstack_preload.h" @@ -22,10 +27,17 @@ #define LSTACK_SO_NAME "liblstack.so" #define LSTACK_PRELOAD_NAME_LEN PATH_MAX #define LSTACK_PRELOAD_ENV_PROC "GAZELLE_BIND_PROCNAME" +#define LSTACK_PRELOAD_ENV_THRD "GAZELLE_THREAD_NAME" + +#define EXCLUDE_THRD_CNT 1 +const static char *g_exclude_thread[EXCLUDE_THRD_CNT] = {"eal-intr-thread"}; +static PER_THREAD enum KERNEL_LWIP_PATH g_preload_thrdpath = PATH_UNKNOW; struct lstack_preload { int32_t preload_switch; char env_procname[LSTACK_PRELOAD_NAME_LEN]; + bool get_thrdname; + char env_thrdname[LSTACK_PRELOAD_NAME_LEN]; }; static struct lstack_preload g_preload_info = {0}; @@ -52,12 +64,104 @@ static int32_t preload_check_bind_proc(void) return -1; } +static void preload_get_thrdname(void) +{ + g_preload_info.get_thrdname = true; + + char *enval = NULL; + enval = getenv(LSTACK_PRELOAD_ENV_THRD); + if (enval == NULL) { + return; + } + if (strcpy_s(g_preload_info.env_thrdname, LSTACK_PRELOAD_NAME_LEN, enval) != EOK) { + return; + } + + LSTACK_PRE_LOG(LSTACK_INFO, "thread name=%s ok\n", g_preload_info.env_thrdname); +} + +enum KERNEL_LWIP_PATH select_fd_posix_path(int32_t fd, struct lwip_sock **socket) +{ + struct lwip_sock *sock = get_socket_by_fd(fd); + + /* AF_UNIX case */ + if (!sock || !sock->conn || CONN_TYPE_IS_HOST(sock->conn)) { + return PATH_KERNEL; + } + + if (socket) { + *socket = sock; + } + + if (likely(CONN_TYPE_IS_LIBOS(sock->conn))) { + return PATH_LWIP; + } + + return PATH_UNKNOW; +} + +enum KERNEL_LWIP_PATH select_posix_path(void) +{ + if (unlikely(posix_api == NULL)) { + /* + * posix api maybe call before gazelle init + * So, we must call posix_api_init at the head of select_path + */ + if (posix_api_init() != 0) { + LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n"); + } + return PATH_KERNEL; + } + + if (unlikely(posix_api->ues_posix)) { + return PATH_KERNEL; + } + + if (g_preload_thrdpath != PATH_UNKNOW) { + return g_preload_thrdpath; + } + + if (!g_preload_info.get_thrdname) { + preload_get_thrdname(); + } + + char thread_name[PATH_MAX] = {0}; + if (pthread_getname_np(pthread_self(), thread_name, PATH_MAX) != 0) { + g_preload_thrdpath = PATH_KERNEL; + return PATH_KERNEL; + } + + /* exclude dpdk thread */ + for (int i = 0; i < EXCLUDE_THRD_CNT; i++) { + if (strstr(thread_name, g_exclude_thread[i]) != NULL) { + g_preload_thrdpath = PATH_KERNEL; + return PATH_KERNEL; + } + } + + /* not set GAZELLE_THREAD_NAME, select all thread */ + if (g_preload_info.env_thrdname[0] == '\0') { + g_preload_thrdpath = PATH_LWIP; + return PATH_LWIP; + } + + if (strstr(thread_name, g_preload_info.env_thrdname) == NULL) { + g_preload_thrdpath = PATH_KERNEL; + return PATH_KERNEL; + } + + g_preload_thrdpath = PATH_LWIP; + return PATH_LWIP; +} + int preload_info_init(void) { char *enval = NULL; g_preload_info.preload_switch = 0; + preload_get_thrdname(); + enval = getenv(LSTACK_PRELOAD_ENV_SYS); if (enval == NULL) { return 0; @@ -75,6 +179,14 @@ int preload_info_init(void) return -1; } + enval = getenv(LSTACK_PRELOAD_ENV_THRD); + if (enval != NULL) { + if (strcpy_s(g_preload_info.env_thrdname, LSTACK_PRELOAD_NAME_LEN, enval) != EOK) { + return -1; + } + g_preload_info.get_thrdname = true; + } + g_preload_info.preload_switch = 1; LSTACK_PRE_LOG(LSTACK_INFO, "LD_PRELOAD ok\n"); return preload_check_bind_proc(); diff --git a/src/lstack/include/lstack_preload.h b/src/lstack/include/lstack_preload.h index 4ba6525..0ad7877 100644 --- a/src/lstack/include/lstack_preload.h +++ b/src/lstack/include/lstack_preload.h @@ -11,6 +11,15 @@ */ #ifndef __LSTACK_PRELOAD_H__ #define __LSTACK_PRELOAD_H__ +#include <stdbool.h> +enum KERNEL_LWIP_PATH { + PATH_KERNEL = 0, + PATH_LWIP, + PATH_UNKNOW, +}; + +enum KERNEL_LWIP_PATH select_posix_path(void); +enum KERNEL_LWIP_PATH select_fd_posix_path(int32_t fd, struct lwip_sock **socket); int preload_info_init(void); #endif -- 2.23.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.