blob: 0a5335fab9cf8e6befae098a60d15c659c708d07 [file] [log] [blame]
/*
* Copyright (c) 2017 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef included_vcom_socket_h
#define included_vcom_socket_h
#include <string.h>
#include <vcl/vcom_glibc_socket.h>
#include <vppinfra/types.h>
#include <sys/socket.h>
#define INVALID_SESSION_ID (~0)
#define INVALID_FD (~0)
#define INVALID_VEP_IDX INVALID_SESSION_ID
#define INVALID_EPFD INVALID_FD
typedef enum
{
SOCKET_TYPE_UNBOUND = 0,
SOCKET_TYPE_KERNEL_BOUND,
SOCKET_TYPE_VPPCOM_BOUND
} vcom_socket_type_t;
typedef enum
{
EPOLL_TYPE_UNBOUND = 0,
EPOLL_TYPE_KERNEL_BOUND,
EPOLL_TYPE_VPPCOM_BOUND
} vcom_epoll_type_t;
typedef enum
{
FD_TYPE_INVALID = 0,
FD_TYPE_KERNEL,
FD_TYPE_EPOLL,
FD_TYPE_VCOM_SOCKET,
/* add new types here */
/* FD_TYPE_MAX should be the last entry */
FD_TYPE_MAX
} vcom_fd_type_t;
typedef struct
{
/* file descriptor -
* fd 0, 1, 2 have special meaning and are reserved,
* -1 denote invalid fd */
i32 fd;
/* session id - -1 denote invalid sid */
i32 sid;
/* socket type */
vcom_socket_type_t type;
/* vcom socket attributes here */
} vcom_socket_t;
typedef struct
{
/* epoll file descriptor -
* epfd 0, 1, 2 have special meaning and are reserved,
* -1 denote invalid epfd */
i32 epfd;
/* vep idx - -1 denote invalid vep_idx */
i32 vep_idx;
/* epoll type */
vcom_epoll_type_t type;
/* flags - 0 or EPOLL_CLOEXEC */
i32 flags;
/* vcom epoll attributes here */
/*
* 00. count of file descriptors currently registered
* on this epoll instance.
* 01. number of file descriptors in the epoll set.
* 02. EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL
* update the count.
* 03. cached for frequent access.
* */
i32 count;
i32 vcl_cnt;
i32 libc_cnt;
/* close( ) called on this epoll instance */
/* 0 - close ( ) not called, 1 - close( ) called. */
u32 close;
} vcom_epoll_t;
typedef struct
{
/* "container" of this item */
i32 epfd;
/* fd - file descriptor information this item refers to */
i32 fd;
/* next and prev fd in the "epoll set" of epfd */
i32 next_fd;
i32 prev_fd;
/* vcom fd type */
vcom_fd_type_t type;
/* interested events and the source fd */
struct epoll_event event;
/* ready events and the source fd */
struct epoll_event revent;
/* epitem attributes here */
} vcom_epitem_t;
typedef union vcom_epitem_key
{
struct
{
i32 fd;
i32 epfd;
};
i64 key;
} __EPOLL_PACKED vcom_epitem_key_t;
static inline char *
vcom_socket_type_str (vcom_socket_type_t t)
{
switch (t)
{
case SOCKET_TYPE_UNBOUND:
return "SOCKET_TYPE_UNBOUND";
case SOCKET_TYPE_KERNEL_BOUND:
return "SOCKET_TYPE_KERNEL_BOUND";
case SOCKET_TYPE_VPPCOM_BOUND:
return "SOCKET_TYPE_VPPCOM_BOUND";
default:
return "SOCKET_TYPE_UNKNOWN";
}
}
static inline char *
vcom_socket_epoll_type_str (vcom_epoll_type_t t)
{
switch (t)
{
case EPOLL_TYPE_UNBOUND:
return "EPOLL_TYPE_UNBOUND";
case EPOLL_TYPE_KERNEL_BOUND:
return "EPOLL_TYPE_KERNEL_BOUND";
case EPOLL_TYPE_VPPCOM_BOUND:
return "EPOLL_TYPE_VPPCOM_BOUND";
default:
return "EPOLL_TYPE_UNKNOWN";
}
}
static inline char *
vcom_socket_vcom_fd_type_str (vcom_fd_type_t t)
{
switch (t)
{
case FD_TYPE_KERNEL:
return "FD_TYPE_KERNEL";
case FD_TYPE_EPOLL:
return "FD_TYPE_EPOLL";
case FD_TYPE_VCOM_SOCKET:
return "FD_TYPE_VCOM_SOCKET";
default:
return "FD_TYPE_UNKNOWN";
}
}
static inline int
vcom_socket_type_is_vppcom_bound (vcom_socket_type_t t)
{
return t == SOCKET_TYPE_VPPCOM_BOUND;
}
static inline int
vcom_socket_epoll_type_is_vppcom_bound (vcom_epoll_type_t t)
{
return t == EPOLL_TYPE_VPPCOM_BOUND;
}
static inline void
vsocket_init (vcom_socket_t * vsock)
{
memset (vsock, 0, sizeof (*vsock));
vsock->fd = INVALID_FD;
vsock->sid = INVALID_SESSION_ID;
vsock->type = SOCKET_TYPE_UNBOUND;
/* vcom socket attributes init here */
}
static inline void
vepoll_init (vcom_epoll_t * vepoll)
{
memset (vepoll, 0, sizeof (*vepoll));
vepoll->epfd = INVALID_EPFD;
vepoll->vep_idx = INVALID_VEP_IDX;
vepoll->type = EPOLL_TYPE_UNBOUND;
vepoll->flags = 0;
vepoll->count = 0;
vepoll->close = 0;
/* vcom epoll attributes init here */
}
static inline void
vepitem_init (vcom_epitem_t * vepitem)
{
struct epoll_event event = {.events = 0,.data.fd = INVALID_FD };
memset (vepitem, 0, sizeof (*vepitem));
vepitem->epfd = INVALID_EPFD;
vepitem->fd = INVALID_FD;
vepitem->next_fd = INVALID_FD;
vepitem->prev_fd = INVALID_FD;
vepitem->type = FD_TYPE_INVALID;
vepitem->event = event;
vepitem->revent = event;
/* vepoll attributes init here */
}
static inline void
vepitemkey_init (vcom_epitem_key_t * epfdfd)
{
memset (epfdfd, 0, sizeof (*epfdfd));
epfdfd->epfd = INVALID_EPFD;
epfdfd->fd = INVALID_FD;
}
static inline void
vsocket_set (vcom_socket_t * vsock, i32 fd, i32 sid, vcom_socket_type_t type)
{
vsock->fd = fd;
vsock->sid = sid;
vsock->type = type;
/* vcom socket attributes set here */
}
static inline void
vepoll_set (vcom_epoll_t * vepoll,
i32 epfd, i32 vep_idx,
vcom_epoll_type_t type, i32 flags, i32 count, u32 close)
{
vepoll->epfd = epfd;
vepoll->vep_idx = vep_idx;
vepoll->type = type;
vepoll->flags = flags;
vepoll->count = count;
vepoll->close = close;
/* vcom epoll attributes set here */
}
static inline void
vepitem_set (vcom_epitem_t * vepitem,
i32 epfd,
i32 fd, i32 next_fd, i32 prev_fd,
vcom_fd_type_t type,
struct epoll_event event, struct epoll_event revent)
{
vepitem->epfd = epfd;
vepitem->fd = fd;
vepitem->next_fd = next_fd;
vepitem->prev_fd = prev_fd;
vepitem->type = type;
vepitem->event = event;
vepitem->revent = revent;
/* vcom epitem attributes set here */
}
static inline void
vepitemkey_set (vcom_epitem_key_t * epfdfd, i32 epfd, i32 fd)
{
epfdfd->epfd = epfd;
epfdfd->fd = fd;
}
static inline int
vsocket_is_vppcom_bound (vcom_socket_t * vsock)
{
return vcom_socket_type_is_vppcom_bound (vsock->type);
}
static inline int
vepoll_is_vppcom_bound (vcom_epoll_t * vepoll)
{
return vcom_socket_epoll_type_is_vppcom_bound (vepoll->type);
}
int vcom_socket_main_init (void);
void vcom_socket_main_destroy (void);
void vcom_socket_main_show (void);
int vcom_socket_is_vcom_fd (int fd);
int vcom_socket_is_vcom_epfd (int epfd);
int vcom_socket_close (int __fd);
ssize_t vcom_socket_read (int __fd, void *__buf, size_t __nbytes);
ssize_t vcom_socket_readv (int __fd, const struct iovec *__iov, int __iovcnt);
ssize_t vcom_socket_write (int __fd, const void *__buf, size_t __n);
ssize_t vcom_socket_writev (int __fd, const struct iovec *__iov,
int __iovcnt);
int vcom_socket_fcntl_va (int __fd, int __cmd, va_list __ap);
int vcom_socket_ioctl_va (int __fd, unsigned long int __cmd, va_list __ap);
int
vcom_socket_select (int vcom_nfds, fd_set * __restrict vcom_readfds,
fd_set * __restrict vcom_writefds,
fd_set * __restrict vcom_exceptfds,
struct timeval *__restrict timeout);
int vcom_socket_socket (int __domain, int __type, int __protocol);
int
vcom_socket_socketpair (int __domain, int __type, int __protocol,
int __fds[2]);
int vcom_socket_bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
int
vcom_socket_getsockname (int __fd, __SOCKADDR_ARG __addr,
socklen_t * __restrict __len);
int
vcom_socket_connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
int
vcom_socket_getpeername (int __fd, __SOCKADDR_ARG __addr,
socklen_t * __restrict __len);
ssize_t
vcom_socket_send (int __fd, const void *__buf, size_t __n, int __flags);
ssize_t vcom_socket_recv (int __fd, void *__buf, size_t __n, int __flags);
/*
* RETURN 1 if __fd is (SOCK_STREAM, SOCK_SEQPACKET),
* 0 otherwise
* */
int vcom_socket_is_connection_mode_socket (int __fd);
ssize_t
vcom_socket_sendto (int __fd, const void *__buf, size_t __n,
int __flags, __CONST_SOCKADDR_ARG __addr,
socklen_t __addr_len);
ssize_t
vcom_socket_recvfrom (int __fd, void *__restrict __buf, size_t __n,
int __flags, __SOCKADDR_ARG __addr,
socklen_t * __restrict __addr_len);
ssize_t
vcom_socket_sendmsg (int __fd, const struct msghdr *__message, int __flags);
#ifdef __USE_GNU
int
vcom_socket_sendmmsg (int __fd, struct mmsghdr *__vmessages,
unsigned int __vlen, int __flags);
#endif
ssize_t vcom_socket_recvmsg (int __fd, struct msghdr *__message, int __flags);
#ifdef __USE_GNU
int
vcom_socket_recvmmsg (int __fd, struct mmsghdr *__vmessages,
unsigned int __vlen, int __flags,
struct timespec *__tmo);
#endif
int
vcom_socket_getsockopt (int __fd, int __level, int __optname,
void *__restrict __optval,
socklen_t * __restrict __optlen);
int
vcom_socket_setsockopt (int __fd, int __level, int __optname,
const void *__optval, socklen_t __optlen);
int vcom_socket_listen (int __fd, int __n);
int
vcom_socket_accept (int __fd, __SOCKADDR_ARG __addr,
socklen_t * __restrict __addr_len);
int
vcom_socket_accept4 (int __fd, __SOCKADDR_ARG __addr,
socklen_t * __restrict __addr_len, int __flags);
int vcom_socket_shutdown (int __fd, int __how);
int vcom_socket_epoll_create1 (int __flags);
int
vcom_socket_epoll_ctl (int __epfd, int __op, int __fd,
struct epoll_event *__event);
int
vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events,
int __maxevents, int __timeout,
const __sigset_t * __ss);
/*
* handle only vcom fds
*/
int vcom_socket_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
#ifdef __USE_GNU
int
vcom_socket_ppoll (struct pollfd *__fds, nfds_t __nfds,
const struct timespec *__timeout, const __sigset_t * __ss);
#endif
#endif /* included_vcom_socket_h */
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/