1a9643ea8Slogwang /* 22317ada5Sfengbojiang * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. 3a9643ea8Slogwang * All rights reserved. 4a9643ea8Slogwang * 5a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without 6a9643ea8Slogwang * modification, are permitted provided that the following conditions are met: 7a9643ea8Slogwang * 8a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright notice, this 9a9643ea8Slogwang * list of conditions and the following disclaimer. 10a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright notice, 11a9643ea8Slogwang * this list of conditions and the following disclaimer in the documentation 12a9643ea8Slogwang * and/or other materials provided with the distribution. 13a9643ea8Slogwang * 14a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16a9643ea8Slogwang * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17a9643ea8Slogwang * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18a9643ea8Slogwang * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19a9643ea8Slogwang * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20a9643ea8Slogwang * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21a9643ea8Slogwang * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22a9643ea8Slogwang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23a9643ea8Slogwang * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24a9643ea8Slogwang * 25a9643ea8Slogwang */ 26a9643ea8Slogwang 27a9643ea8Slogwang #ifndef _FSTACK_API_H 28a9643ea8Slogwang #define _FSTACK_API_H 29a9643ea8Slogwang 30a9643ea8Slogwang #ifdef __cplusplus 31a9643ea8Slogwang extern "C" { 32a9643ea8Slogwang #endif 33a9643ea8Slogwang #include <sys/socket.h> 34a9643ea8Slogwang #include <sys/select.h> 35a9643ea8Slogwang #include <sys/poll.h> 36144c6bcdSlogwang #include <netinet/in.h> 377e048838Slogwang #include <sys/time.h> 38a9643ea8Slogwang 39a9643ea8Slogwang #include "ff_event.h" 40a9643ea8Slogwang #include "ff_errno.h" 41a9643ea8Slogwang 42a9643ea8Slogwang struct linux_sockaddr { 43a9643ea8Slogwang short sa_family; 4471d12233Sfengbojiang char sa_data[14]; 45a9643ea8Slogwang }; 46a9643ea8Slogwang 47d7140ab7Sfengbojiang(姜凤波) #define AF_INET6_LINUX 10 489e60a85fSroot #define PF_INET6_LINUX AF_INET6_LINUX 49aa61e4b5Sfengbojiang(姜凤波) #define AF_INET6_FREEBSD 28 50aa61e4b5Sfengbojiang(姜凤波) #define PF_INET6_FREEBSD AF_INET6_FREEBSD 51d7140ab7Sfengbojiang(姜凤波) 52a9643ea8Slogwang typedef int (*loop_func_t)(void *arg); 53a9643ea8Slogwang 54a02c88d6Slogwang int ff_init(int argc, char * const argv[]); 55a9643ea8Slogwang 56a9643ea8Slogwang void ff_run(loop_func_t loop, void *arg); 57a9643ea8Slogwang 58eb5902d9Slogwang /* POSIX-LIKE api begin */ 59eb5902d9Slogwang 60a9643ea8Slogwang int ff_fcntl(int fd, int cmd, ...); 61a9643ea8Slogwang 62a9643ea8Slogwang int ff_sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, 63a9643ea8Slogwang const void *newp, size_t newlen); 64a9643ea8Slogwang 65a9643ea8Slogwang int ff_ioctl(int fd, unsigned long request, ...); 66a9643ea8Slogwang 67a9643ea8Slogwang int ff_socket(int domain, int type, int protocol); 68a9643ea8Slogwang 69a9643ea8Slogwang int ff_setsockopt(int s, int level, int optname, const void *optval, 70a9643ea8Slogwang socklen_t optlen); 71a9643ea8Slogwang 72a9643ea8Slogwang int ff_getsockopt(int s, int level, int optname, void *optval, 73a9643ea8Slogwang socklen_t *optlen); 74a9643ea8Slogwang 75a9643ea8Slogwang int ff_listen(int s, int backlog); 76a9643ea8Slogwang int ff_bind(int s, const struct linux_sockaddr *addr, socklen_t addrlen); 77a9643ea8Slogwang int ff_accept(int s, struct linux_sockaddr *addr, socklen_t *addrlen); 78a9643ea8Slogwang int ff_connect(int s, const struct linux_sockaddr *name, socklen_t namelen); 79a9643ea8Slogwang int ff_close(int fd); 80a9643ea8Slogwang int ff_shutdown(int s, int how); 81a9643ea8Slogwang 82a9643ea8Slogwang int ff_getpeername(int s, struct linux_sockaddr *name, 83a9643ea8Slogwang socklen_t *namelen); 84a9643ea8Slogwang int ff_getsockname(int s, struct linux_sockaddr *name, 85a9643ea8Slogwang socklen_t *namelen); 86a9643ea8Slogwang 87a9643ea8Slogwang ssize_t ff_read(int d, void *buf, size_t nbytes); 88a9643ea8Slogwang ssize_t ff_readv(int fd, const struct iovec *iov, int iovcnt); 89a9643ea8Slogwang 90a9643ea8Slogwang ssize_t ff_write(int fd, const void *buf, size_t nbytes); 91a9643ea8Slogwang ssize_t ff_writev(int fd, const struct iovec *iov, int iovcnt); 92a9643ea8Slogwang 93a9643ea8Slogwang ssize_t ff_send(int s, const void *buf, size_t len, int flags); 94a9643ea8Slogwang ssize_t ff_sendto(int s, const void *buf, size_t len, int flags, 95a9643ea8Slogwang const struct linux_sockaddr *to, socklen_t tolen); 96a9643ea8Slogwang ssize_t ff_sendmsg(int s, const struct msghdr *msg, int flags); 97a9643ea8Slogwang 98a9643ea8Slogwang ssize_t ff_recv(int s, void *buf, size_t len, int flags); 99a9643ea8Slogwang ssize_t ff_recvfrom(int s, void *buf, size_t len, int flags, 100a9643ea8Slogwang struct linux_sockaddr *from, socklen_t *fromlen); 101a9643ea8Slogwang ssize_t ff_recvmsg(int s, struct msghdr *msg, int flags); 102a9643ea8Slogwang 103a9643ea8Slogwang int ff_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 104a9643ea8Slogwang struct timeval *timeout); 105a9643ea8Slogwang 106a9643ea8Slogwang int ff_poll(struct pollfd fds[], nfds_t nfds, int timeout); 107a9643ea8Slogwang 108a9643ea8Slogwang int ff_kqueue(void); 109a9643ea8Slogwang int ff_kevent(int kq, const struct kevent *changelist, int nchanges, 110a9643ea8Slogwang struct kevent *eventlist, int nevents, const struct timespec *timeout); 1111a78ce8eSRon int ff_kevent_do_each(int kq, const struct kevent *changelist, int nchanges, 1121a78ce8eSRon void *eventlist, int nevents, const struct timespec *timeout, 1131a78ce8eSRon void (*do_each)(void **, struct kevent *)); 114a9643ea8Slogwang 1157e048838Slogwang int ff_gettimeofday(struct timeval *tv, struct timezone *tz); 1167e048838Slogwang 117867abe45Swhl739 int ff_dup(int oldfd); 118867abe45Swhl739 int ff_dup2(int oldfd, int newfd); 119867abe45Swhl739 120eb5902d9Slogwang /* POSIX-LIKE api end */ 121eb5902d9Slogwang 122eb5902d9Slogwang 123eb5902d9Slogwang /* Tests if fd is used by F-Stack */ 124a02c88d6Slogwang extern int ff_fdisused(int fd); 125a02c88d6Slogwang 12670bb2888Schenwei extern int ff_getmaxfd(void); 127eb5902d9Slogwang 128144c6bcdSlogwang /* route api begin */ 129144c6bcdSlogwang enum FF_ROUTE_CTL { 130144c6bcdSlogwang FF_ROUTE_ADD, 131144c6bcdSlogwang FF_ROUTE_DEL, 132144c6bcdSlogwang FF_ROUTE_CHANGE, 133144c6bcdSlogwang }; 134144c6bcdSlogwang 135144c6bcdSlogwang enum FF_ROUTE_FLAG { 136144c6bcdSlogwang FF_RTF_HOST, 137144c6bcdSlogwang FF_RTF_GATEWAY, 138144c6bcdSlogwang }; 139144c6bcdSlogwang 140144c6bcdSlogwang /* 141144c6bcdSlogwang * On success, 0 is returned. 142144c6bcdSlogwang * On error, -1 is returned, and errno is set appropriately. 143144c6bcdSlogwang */ 144144c6bcdSlogwang int ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag, 145144c6bcdSlogwang struct linux_sockaddr *dst, struct linux_sockaddr *gw, 146144c6bcdSlogwang struct linux_sockaddr *netmask); 147144c6bcdSlogwang 1483b2bd0f6Slogwang /* route api end */ 1493b2bd0f6Slogwang 150eb5902d9Slogwang 151eb5902d9Slogwang /* dispatch api begin */ 152ee6c3aa3Sfengbojiang(姜凤波) #define FF_DISPATCH_ERROR (-1) 153ee6c3aa3Sfengbojiang(姜凤波) #define FF_DISPATCH_RESPONSE (-2) 154eb5902d9Slogwang 155eb5902d9Slogwang /* 156eb5902d9Slogwang * Packet dispatch callback function. 157eb5902d9Slogwang * Implemented by user. 158eb5902d9Slogwang * 159eb5902d9Slogwang * @param data 160127dd473Swhl739 * The data pointer of this packet. 161eb5902d9Slogwang * @param len 162127dd473Swhl739 * The length of this packet. 163127dd473Swhl739 * @param queue_id 164127dd473Swhl739 * Current queue of this packet. 165eb5902d9Slogwang * @param nb_queues 166eb5902d9Slogwang * Number of queues to be dispatched. 167eb5902d9Slogwang * 168eb5902d9Slogwang * @return 0 to (nb_queues - 1) 169eb5902d9Slogwang * The queue id that the packet will be dispatched to. 170d9e0c21aSfengbojiang(姜凤波) * @return FF_DISPATCH_ERROR (-1) 171eb5902d9Slogwang * Error occurs or packet is handled by user, packet will be freed. 172d9e0c21aSfengbojiang(姜凤波) * @return FF_DISPATCH_RESPONSE (-2) 173d9e0c21aSfengbojiang(姜凤波) * Packet is handled by user, packet will be responsed. 174eb5902d9Slogwang * 175eb5902d9Slogwang */ 176ee6c3aa3Sfengbojiang(姜凤波) typedef int (*dispatch_func_t)(void *data, uint16_t *len, 177127dd473Swhl739 uint16_t queue_id, uint16_t nb_queues); 178eb5902d9Slogwang 179eb5902d9Slogwang /* regist a packet dispath function */ 180eb5902d9Slogwang void ff_regist_packet_dispatcher(dispatch_func_t func); 181eb5902d9Slogwang 182eb5902d9Slogwang /* dispatch api end */ 183eb5902d9Slogwang 184aa61e4b5Sfengbojiang(姜凤波) /* pcb lddr api begin */ 185aa61e4b5Sfengbojiang(姜凤波) /* 186aa61e4b5Sfengbojiang(姜凤波) * pcb lddr callback function. 187aa61e4b5Sfengbojiang(姜凤波) * Implemented by user. 188aa61e4b5Sfengbojiang(姜凤波) * 189aa61e4b5Sfengbojiang(姜凤波) * @param family 190aa61e4b5Sfengbojiang(姜凤波) * The remote server addr, should be AF_INET or AF_INET6. 191aa61e4b5Sfengbojiang(姜凤波) * @param dst_addr 192aa61e4b5Sfengbojiang(姜凤波) * The remote server addr, should be (in_addr *) or (in6_addr *). 193aa61e4b5Sfengbojiang(姜凤波) * @param dst_port 194aa61e4b5Sfengbojiang(姜凤波) * The remote server port. 195aa61e4b5Sfengbojiang(姜凤波) * @param src_addr 196aa61e4b5Sfengbojiang(姜凤波) * Return parameter. 197aa61e4b5Sfengbojiang(姜凤波) * The local addr, should be (in_addr *) or (in6_addr *). 198aa61e4b5Sfengbojiang(姜凤波) * If set (INADDR_ANY) or (in6addr_any), the app then will 199aa61e4b5Sfengbojiang(姜凤波) * call `in_pcbladdr()` to get laddr. 200aa61e4b5Sfengbojiang(姜凤波) * 201aa61e4b5Sfengbojiang(姜凤波) * @return error_no 202aa61e4b5Sfengbojiang(姜凤波) * 0 means success. 203aa61e4b5Sfengbojiang(姜凤波) * 204aa61e4b5Sfengbojiang(姜凤波) */ 205aa61e4b5Sfengbojiang(姜凤波) typedef int (*pcblddr_func_t)(uint16_t family, void *dst_addr, 206aa61e4b5Sfengbojiang(姜凤波) uint16_t dst_port, void *src_addr); 207aa61e4b5Sfengbojiang(姜凤波) 208aa61e4b5Sfengbojiang(姜凤波) /* regist a pcb lddr function */ 209aa61e4b5Sfengbojiang(姜凤波) void ff_regist_pcblddr_fun(pcblddr_func_t func); 210aa61e4b5Sfengbojiang(姜凤波) 211aa61e4b5Sfengbojiang(姜凤波) /* pcb lddr api end */ 212eb5902d9Slogwang 2133b2bd0f6Slogwang /* internal api begin */ 2143b2bd0f6Slogwang 215867abe45Swhl739 /* FreeBSD style calls. Used for tools. */ 216867abe45Swhl739 int ff_ioctl_freebsd(int fd, unsigned long request, ...); 217867abe45Swhl739 int ff_setsockopt_freebsd(int s, int level, int optname, 218867abe45Swhl739 const void *optval, socklen_t optlen); 219867abe45Swhl739 int ff_getsockopt_freebsd(int s, int level, int optname, 220867abe45Swhl739 void *optval, socklen_t *optlen); 221867abe45Swhl739 222144c6bcdSlogwang /* 2233b2bd0f6Slogwang * Handle rtctl. 224144c6bcdSlogwang * The data is a pointer to struct rt_msghdr. 225144c6bcdSlogwang */ 226144c6bcdSlogwang int ff_rtioctl(int fib, void *data, unsigned *plen, unsigned maxlen); 227144c6bcdSlogwang 2283b2bd0f6Slogwang /* 2293b2bd0f6Slogwang * Handle ngctl. 2303b2bd0f6Slogwang */ 2313b2bd0f6Slogwang enum FF_NGCTL_CMD { 2323b2bd0f6Slogwang NGCTL_SOCKET, 2333b2bd0f6Slogwang NGCTL_BIND, 2343b2bd0f6Slogwang NGCTL_CONNECT, 2353b2bd0f6Slogwang NGCTL_SEND, 2363b2bd0f6Slogwang NGCTL_RECV, 2373b2bd0f6Slogwang NGCTL_CLOSE, 2383b2bd0f6Slogwang }; 2393b2bd0f6Slogwang 2403b2bd0f6Slogwang int ff_ngctl(int cmd, void *data); 2413b2bd0f6Slogwang 2423b2bd0f6Slogwang /* internal api end */ 243144c6bcdSlogwang 244*1f5a5310Sfengbojiang /* zero ccopy API begin */ 245*1f5a5310Sfengbojiang struct ff_zc_mbuf { 246*1f5a5310Sfengbojiang void *bsd_mbuf; /* point to the head mbuf */ 247*1f5a5310Sfengbojiang void *bsd_mbuf_off; /* ponit to the current mbuf in the mbuf chain with offset */ 248*1f5a5310Sfengbojiang int off; /* the offset of total mbuf, APP shouldn't modify it */ 249*1f5a5310Sfengbojiang int len; /* the total len of the mbuf chain */ 250*1f5a5310Sfengbojiang }; 251*1f5a5310Sfengbojiang 252*1f5a5310Sfengbojiang /* 253*1f5a5310Sfengbojiang * Get the ff zero copy mbuf. 254*1f5a5310Sfengbojiang * 255*1f5a5310Sfengbojiang * @param m 256*1f5a5310Sfengbojiang * The ponitor of 'sturct ff_zc_mbuf', and can't be NULL. 257*1f5a5310Sfengbojiang * Can used by 'ff_zc_mbuf_write' and 'ff_zc_mbuf_read'. 258*1f5a5310Sfengbojiang * @param len 259*1f5a5310Sfengbojiang * The total buf len of mbuf chain that you want to alloc. 260*1f5a5310Sfengbojiang * 261*1f5a5310Sfengbojiang * @return error_no 262*1f5a5310Sfengbojiang * 0 means success. 263*1f5a5310Sfengbojiang * -1 means error. 264*1f5a5310Sfengbojiang */ 265*1f5a5310Sfengbojiang int ff_zc_mbuf_get(struct ff_zc_mbuf *m, int len); 266*1f5a5310Sfengbojiang 267*1f5a5310Sfengbojiang /* 268*1f5a5310Sfengbojiang * Write data to the mbuf chain in 'sturct ff_zc_mbuf'. 269*1f5a5310Sfengbojiang * APP can call this function multiple times, need pay attion to the offset of data. 270*1f5a5310Sfengbojiang * but the total len can't be larger than m->len. 271*1f5a5310Sfengbojiang * After this fuction return success, 272*1f5a5310Sfengbojiang * the struct 'ff_zc_mbuf *m' can be reused in `ff_zc_mbuf_get`. 273*1f5a5310Sfengbojiang * 274*1f5a5310Sfengbojiang * APP nedd call 'ff_write' to send data actually after finish write data to mbuf, 275*1f5a5310Sfengbojiang * And use 'bsd_mbuf' of 'struct ff_zc_mbuf' as the 'buf' argument. 276*1f5a5310Sfengbojiang * 277*1f5a5310Sfengbojiang * See 'example/main_zc.c' 278*1f5a5310Sfengbojiang * 279*1f5a5310Sfengbojiang * @param m 280*1f5a5310Sfengbojiang * The ponitor of 'sturct ff_zc_mbuf', must be call 'ff_zc_mbuf_get' first. 281*1f5a5310Sfengbojiang * @param data 282*1f5a5310Sfengbojiang * The pointer of data that want to write to socket, need pay attion to the offset. 283*1f5a5310Sfengbojiang * @param len 284*1f5a5310Sfengbojiang * The len that APP want to write to mbuf chain this time. 285*1f5a5310Sfengbojiang * 286*1f5a5310Sfengbojiang * @return error_no 287*1f5a5310Sfengbojiang * 0 means success. 288*1f5a5310Sfengbojiang * -1 means error. 289*1f5a5310Sfengbojiang */ 290*1f5a5310Sfengbojiang int ff_zc_mbuf_write(struct ff_zc_mbuf *m, const char *data, int len); 291*1f5a5310Sfengbojiang 292*1f5a5310Sfengbojiang /* 293*1f5a5310Sfengbojiang * Read data to the mbuf chain in 'sturct ff_zc_mbuf'. 294*1f5a5310Sfengbojiang * not implemented now. 295*1f5a5310Sfengbojiang */ 296*1f5a5310Sfengbojiang int ff_zc_mbuf_read(struct ff_zc_mbuf *m, const char *data, int len); 297*1f5a5310Sfengbojiang 298*1f5a5310Sfengbojiang /* ZERO COPY API end */ 299*1f5a5310Sfengbojiang 300a9643ea8Slogwang #ifdef __cplusplus 301a9643ea8Slogwang } 302a9643ea8Slogwang #endif 303a9643ea8Slogwang #endif 304a9643ea8Slogwang 305